AWS Lambda + CloudWatch 를 이용해 주기적으로 AWS RDS 중지, 시작하는 방법(How to stop and start AWS RDS periodically using AWS Lambda + CloudWatch)



## AWS Lambda + CloudWatch 를 이용해 주기적으로 AWS RDS 중지, 시작하는 방법(How to stop and start AWS RDS periodically using AWS Lambda + CloudWatch)

가끔씩 사용하는 **AWS EC2 + RDS** 가 있다. 그래서 평소에는 중지해놓고, 필요할 때만 실행시키고 싶은데 **RDS** 가 문제다.

왜 그런지는 모르겠는데~~(AWS가 돈을 많이 벌고 싶어서 인 것 같은데... 왜 그런지 아시는 분은 알려주세요...)~~ 중지 후 7일마다 스스로 시작이 된다.

그래서 깜빡하고 나면 비싸도 너무 비싼 RDS 요금이 왕창 나온다. 그래서 매 주 미리 알림을 맞춰놓고, 콘솔에 들어가 중지를 하는데 가끔씩 까먹기도 하고, 너무 귀찮기도 해서 나를 대신할 방법을 찾아봤다.



크게 방법이 2가지 있는데, 아래와 같다.

1. [AWS Instance Scheduler](https://aws.amazon.com/ko/solutions/implementations/instance-scheduler/) 를 이용하는 방법
2. AWS Lambda + CloudWatch 를 이용하는 방법



그런데 검색해보니 1번 방법은 적어도 5달러 이상 나올 것 같아서, 2번 방법으로 시도해봤다.~~(내 돈은 아니지만 5달러도 아까ㅇ...)~~

서두가 길었는데, 이제 AWS Lambda + CloudWatch 를 이용해 주기적으로 AWS RDS 중지, 시작하는 방법을 알아보자.



### AWS Lambda + CloudWatch 설정

먼저 크게

1. AWS Lambda 설정
2. IAM 정책 설정, 
3. CloudWatch 설정

순으로 나눠서 설정해보자.



#### 1. AWS Lambda 설정

AWS 계정은 있다고 가정하고, AWS에 로그인하고 들어가 서비스에서 **AWS Lambda** 를 클릭한다. 그 다음 **함수 생성**을 클릭.

<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrAXald84NOpfgagSGxYNWzXdZDFU1fv5Y3a2da_Uqiv4oGF3P4HCh5Zht0ySvLk6OWZ8RZx2MmkpcAEpGV8Vy8EVyMSRUlxoFtYlW_HFpRzGDOfN_03QGMCprJiNa0vjt1atdmmFryI4z/s0/%25E1%2584%2589%25E1%2585%25B3%25E1%2584%258F%25E1%2585%25B3%25E1%2584%2585%25E1%2585%25B5%25E1%2586%25AB%25E1%2584%2589%25E1%2585%25A3%25E1%2586%25BA+2020-12-04+%25E1%2584%258B%25E1%2585%25A9%25E1%2584%258C%25E1%2585%25A5%25E1%2586%25AB+11.47.10.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" data-original-height="1290" data-original-width="1942" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrAXald84NOpfgagSGxYNWzXdZDFU1fv5Y3a2da_Uqiv4oGF3P4HCh5Zht0ySvLk6OWZ8RZx2MmkpcAEpGV8Vy8EVyMSRUlxoFtYlW_HFpRzGDOfN_03QGMCprJiNa0vjt1atdmmFryI4z/s0/%25E1%2584%2589%25E1%2585%25B3%25E1%2584%258F%25E1%2585%25B3%25E1%2584%2585%25E1%2585%25B5%25E1%2586%25AB%25E1%2584%2589%25E1%2585%25A3%25E1%2586%25BA+2020-12-04+%25E1%2584%258B%25E1%2585%25A9%25E1%2584%258C%25E1%2585%25A5%25E1%2586%25AB+11.47.10.png"/></a></div>

**새로 작성** 을 선택하고(그대로 두고) **함수 이름** 을 작성합니다. 런타임(사용할 언어)의 경우 여기선, Python 2.7로 하겠습니다.

그리고 권한은 그대로 **기본 Lambda 권한을 가진 새 역할 생성** 으로 두고 **함수 생성**을 클릭합니다. 생성이 되면 생성된 함수에 들어가 코드를 삽입합니다.

<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhEq1BJpsUM-Tu95ZkZTWqQRvW6d4jbrsuJaKtA7I7Gv4YxgfKOR1KpGp1hvbFtpWssm2V9ZtubXe5HdvSfHPyJnXkykjEvII4TTeXDeKclN3iVHKeInYBVos9MQxcNROedvDEJVEpxkKj/s0/%25E1%2584%2589%25E1%2585%25B3%25E1%2584%258F%25E1%2585%25B3%25E1%2584%2585%25E1%2585%25B5%25E1%2586%25AB%25E1%2584%2589%25E1%2585%25A3%25E1%2586%25BA+2020-12-04+%25E1%2584%258B%25E1%2585%25A9%25E1%2584%258C%25E1%2585%25A5%25E1%2586%25AB+11.50.12.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" data-original-height="1037" data-original-width="2048" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhEq1BJpsUM-Tu95ZkZTWqQRvW6d4jbrsuJaKtA7I7Gv4YxgfKOR1KpGp1hvbFtpWssm2V9ZtubXe5HdvSfHPyJnXkykjEvII4TTeXDeKclN3iVHKeInYBVos9MQxcNROedvDEJVEpxkKj/s0/%25E1%2584%2589%25E1%2585%25B3%25E1%2584%258F%25E1%2585%25B3%25E1%2584%2585%25E1%2585%25B5%25E1%2586%25AB%25E1%2584%2589%25E1%2585%25A3%25E1%2586%25BA+2020-12-04+%25E1%2584%258B%25E1%2585%25A9%25E1%2584%258C%25E1%2585%25A5%25E1%2586%25AB+11.50.12.png"/></a></div>

함수 코드는 다음과 같이 삽입합니다. 아래의 코드는 Maria DB(mysql)의 경우이며 DB Cluster를 중지해야하는 경우의 코드입니다.

```
import boto3
region = 'ap-northeast-2' # RDS가 존재하는 region 
db_cluster_identifier = 'WRITE YOUR DB CLUSTER IDENTIFIER' # RDS Cluster의 DB 식별자

def lambda_handler(event, context):
    ec2 = boto3.client('rds', region_name=region)
    ec2.stop_db_cluster(DBClusterIdentifier=db_cluster_identifier)
    print 'stopped your RDS cluster: ' + str(db_cluster_identifier)
```

만약 DB instance 를 중지해야하는 경우 아래와 같은 코드를 사용하면 됩니다.

```
import boto3
region = 'ap-northeast-2' # RDS가 존재하는 region 
db_instance_identifier = 'WRITE YOUR DB INSTANCE IDENTIFIER' # RDS Instance의 식별자

def lambda_handler(event, context):
    ec2 = boto3.client('rds', region_name=region)
    ec2.stop_db_instance(DBInstanceIdentifier=db_instance_identifier)
    print 'stopped your RDS Instance: ' + str(db_cluster_identifier)
```

RDS를 시작하는 경우엔 `ec2.stop_db_cluster` 대신 `ec2.start_db_cluster` 를, `ec2.stop_db_instance` 대신 `ec2.start_db_instance` 를 적어주면 됩니다.

##### 함수 코드를 수정한 후에는 꼭 저장을 하고, 배포 버튼을 눌러야합니다 !!!

그리고 **권한** 탭을 선택하고 **편집** 버튼을 누릅니다. 이 때, **역할 이름** 을 복사하거나 기억해두세요. **IAM 설정** 시 필요합니다. **편집**에 들어간 후, **제한 시간**을 **10초**로 변경합니다. 더 길게 해도 됩니다.

<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjINbbQvEBajDfiJ-4QlM7-ZtH8EYwU3UBF0TpUZx99VdQq8QOYCT89BZSeYVbO0U0o3wrwYxZY1Gf8q1qv_8zeVNIDkohoMgF19B6GwsDsy-Ge9SSGSbtT_WZipTJRYBL09qbn5X7blH_U/s0/%25E1%2584%2589%25E1%2585%25B3%25E1%2584%258F%25E1%2585%25B3%25E1%2584%2585%25E1%2585%25B5%25E1%2586%25AB%25E1%2584%2589%25E1%2585%25A3%25E1%2586%25BA+2020-12-04+%25E1%2584%258B%25E1%2585%25A9%25E1%2584%2592%25E1%2585%25AE+12.20.54.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" data-original-height="1162" data-original-width="2048" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjINbbQvEBajDfiJ-4QlM7-ZtH8EYwU3UBF0TpUZx99VdQq8QOYCT89BZSeYVbO0U0o3wrwYxZY1Gf8q1qv_8zeVNIDkohoMgF19B6GwsDsy-Ge9SSGSbtT_WZipTJRYBL09qbn5X7blH_U/s0/%25E1%2584%2589%25E1%2585%25B3%25E1%2584%258F%25E1%2585%25B3%25E1%2584%2585%25E1%2585%25B5%25E1%2586%25AB%25E1%2584%2589%25E1%2585%25A3%25E1%2586%25BA+2020-12-04+%25E1%2584%258B%25E1%2585%25A9%25E1%2584%2592%25E1%2585%25AE+12.20.54.png"/></a></div>

이제 IAM 정책을 설정하고, 해당 Lambda의 권한을 설정해봅시다.



#### 2. IAM 정책 설정

**IAM**에 가서 **정책**에 들어가 **정책 생성** 을 클릭합니다.

<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLQSVtbKpWwjCjp6W4DLwr1jAQDJN6w0hWCVR-NIJciREpN9UbiNr0TfezD2fhaiFmc-Egfvi46U57c8xR9VrORrtjnE5H-t8Ne-Le3vXQ3NyM5zKOjrHlaYGtJptazPVCcNcdcgUJ-MuX/s0/%25E1%2584%2589%25E1%2585%25B3%25E1%2584%258F%25E1%2585%25B3%25E1%2584%2585%25E1%2585%25B5%25E1%2586%25AB%25E1%2584%2589%25E1%2585%25A3%25E1%2586%25BA+2020-12-04+%25E1%2584%258B%25E1%2585%25A9%25E1%2584%2592%25E1%2585%25AE+12.27.52.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" border="0" data-original-height="700" data-original-width="2610" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLQSVtbKpWwjCjp6W4DLwr1jAQDJN6w0hWCVR-NIJciREpN9UbiNr0TfezD2fhaiFmc-Egfvi46U57c8xR9VrORrtjnE5H-t8Ne-Le3vXQ3NyM5zKOjrHlaYGtJptazPVCcNcdcgUJ-MuX/s0/%25E1%2584%2589%25E1%2585%25B3%25E1%2584%258F%25E1%2585%25B3%25E1%2584%2585%25E1%2585%25B5%25E1%2586%25AB%25E1%2584%2589%25E1%2585%25A3%25E1%2586%25BA+2020-12-04+%25E1%2584%258B%25E1%2585%25A9%25E1%2584%2592%25E1%2585%25AE+12.27.52.png"/></a></div>

그 다음 **JSON** 탭을 선택한 후 아래 **코드**를 삽입하고 **정책 검토** 를 클릭합니다.

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "arn:aws:logs:*:*:*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "rds:StopDBInstance",
                "rds:Describe*",
                "rds:DescribeDBClusters",
                "rds:StopDBCluster",
                "rds:StartDBCluster"
            ],
            "Resource": "*"
        }
    ]
}
```

**정책 검토** 단계에서 의미있는 **이름** 과 **설명** 을 작성하고 **정책 생성** 을 클릭합니다.

생성이 되면, **IAM 역할** 메뉴에 들어가서 위의 **역할 이름** 을 검색한 후, 클릭해서 들어갑니다. 그 다음 **정책 연결** 을 누른 후, 위에서 생성한 정책 이름을 검색해서 체크한 후 **정책 연결** 버튼을 클릭합니다. 그러면 IAM 정책 설정이 완료됐습니다. 마지막으로 CloudWatch 설정을 해보겠습니다.



#### 3. CloudWatch 설정

**AWS CloudWatch** 에 들어간 후, 왼쪽 메뉴 중 **규칙** 메뉴를 선택합니다. 그 다음, **규칙 생성** 버튼을 클릭합니다.

**일정** 버튼을 클릭하고 **Cron 표현식**으로 원하는 일정으로 설정합니다. 저의 경우 매주 목요일 오후 7시 40분 마다 호출할 예정이기 때문에 다음과 같이 Cron 표현식을 적었습니다. UTC 기준으로 설정하는 것이기 때문에 한국 시간으로 19:40 THU 는 10:40 THU 로 써야하고 이는 아래와 같이 적습니다.

```
40 10 ? * THU *
```

Cron 표현식에 대한 정보는 [이 곳](https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/ScheduledEvents.html)에서 확인해보실 수 있습니다. 참고로 [CronMaker](http://www.cronmaker.com/?1) 와 같은 사이트에서 도움을 받을 수 있습니다.

그 다음 오른쪽 **대상** 에선 Lambda 함수를 선택하고, 위에서 만든 함수 이름을 찾아 선택하고 **세부 정보 구성** 을 선택합니다. 의미있는 **이름**과 **설명**을 작성한 후 **규칙 생성** 버튼을 클릭합니다. 이제 설정이 끝났습니다. 기다려보면 확인할 수 있습니다. 참고로 **Lambda**가 잘 실행되는지 확인해보기 위해선 해당 Lambda 페이지에서 **테스트** 버튼을 눌러서 테스트해볼 수 있습니다.



**참고한 사이트**

https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html#RDS.Client.stop_db_cluster

https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html#RDS.Client.stop_db_instance

https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/ScheduledEvents.html

https://qastack.kr/server/867642/how-to-start-and-stop-aws-ec2-instance-based-on-a-time-based-schedule

https://docs.aws.amazon.com/ko_kr/autoscaling/plans/userguide/security_iam_id-based-policy-examples.html

https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_StopDBCluster.html

https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_StopDBCluster.html

http://www.cronmaker.com/?1


댓글

이 블로그의 인기 게시물

부트스트랩 사용 시 버튼 오른쪽 정렬하는 방법 (How to use float-right for right align in bootstrap)

맥(Mac)에서 MySql 사용 시 Error: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) 오류가 발생하는 경우 해결 방법

HTML, CSS - footer fixed (foot 하단 고정 시키기)