Step Functions를 사용해서 7일 이상 동안 Amazon RDS 인스턴스를 중지하려면 어떻게 해야 하나요?

8분 분량
0

AWS Step Functions를 사용하여 7일 이상 Amazon Relational Database Service(RDS)를 중지하려고 합니다.

간략한 설명

기본적으로 Amazon RDS 데이터베이스 인스턴스를 한 번에 최대 7일 동안 중지할 수 있습니다. 7일이 지나면 유지 관리 업데이트를 놓치지 않도록 인스턴스가 다시 시작됩니다.

7일 이상 인스턴스를 중지하려면 Step Functions를 사용하여 유지 관리 기간을 놓치지 않고 워크플로를 자동화할 수 있습니다.

참고: 다른 해결 방법은 AWS Lambda 함수를 사용하여 Amazon RDS 인스턴스를 7일 이상 중지하려면 어떻게 해야 하나요?를 참조합니다.

해결 방법

IAM 권한 구성

Step Functions가 인스턴스를 시작 및 중지하고 인스턴스에 대한 정보를 검색할 수 있도록 허용하는 AWS ID 및 액세스 관리(IAM) 정책을 생성합니다.

1.    IAM 콘솔을 엽니다.

  1. 탐색 창에서 정책을 선택합니다. 그런 다음 정책 생성을 선택합니다.

  2. JSON 탭을 선택합니다. 그런 다음 정책을 입력하여 필요한 IAM 권한을 부여합니다.

{
    "Version": "2012-10-17",
    "Statement":
    [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "rds:DescribeDBInstances",
                "rds:StopDBInstance",
                "rds:StartDBInstance"
            ],
            "Resource": "*"
        }
    ]
}
  1. 다음을 선택합니다. 태그.

  2. (선택 사항) 태그를 추가하려면 태그 추가를 선택한 다음 필드에 적절한 값을 입력합니다.

  3. 다음을 선택합니다. 검토합니다.

  4. 정책의 이름 (예: step-functions-start-stop-rds-policy)을입력합니다. 정책에 부여된 권한의 검토는 요약 섹션을 참조합니다.

8.    정책 생성을 선택합니다.

자세한 내용은 JSON 편집기를 사용한 정책 생성을 참조합니다.

IAM 역할을 생성 및 필요 정책을 연결

1.    IAM 콘솔을 엽니다.

  1. 탐색 창에서 역할을 선택합니다. 그런 다음 역할 생성을 선택합니다.

  2. 신뢰할 수 있는 개체 유형 선택에서 AWS 서비스를 선택합니다.

  3. 다른 AWS 서비스 사용 사례 드롭다운 목록에서 Step Functions를 선택합니다. 그런 다음 Step Functions 옵션을 선택합니다.

5.    다음을 선택합니다.
참고: 권한 추가 페이지에서는 아무 조치도 취하지 마세요. 먼저 역할을 만들고 기본 권한을 편집합니다.

6.    다음을 선택합니다.

  1. 역할 이름에 역할 이름 (예: step-functions-start-stop-rds-role)을입력합니다.
    (선택 사항) 역할 설명을 업데이트합니다.
    (선택 사항) 태그를 추가하려면 필드에 적절한 값을 입력합니다.

  2. 역할 생성을 선택합니다. 해당 메뉴를 선택하면 역할 목록으로 돌아갑니다.

  3. 검색 창에 생성한 역할의 이름을 입력합니다. 그리고 해당 역할을 선택하여 세부 정보를 확인합니다.

  4. 권한 탭에서 권한 추가 드롭다운 목록을 선택합니다. 그런 다음 정책 첨부를 선택합니다.

  5. IAM 권한 구성 섹션에서 생성한 정책의 이름 (예: step-functions-start-stop-rds-policy)을입력합니다. 이 정책이 옵션으로 표시되면 정책을 선택합니다.

  6. 권한 탭에서 AWSLambdaRole AWS 관리형 정책을 선택한 다음 제거를 선택합니다.

자세한 내용은 AWS 서비스 역할 생성(콘솔)을 참조합니다.

DB 인스턴스용 태그 추가

1.    Amazon RDS 콘솔을 엽니다.

  1. 탐색 창에서 데이터베이스를 선택합니다.

  2. 자동으로 시작하고 중지하려는 DB 인스턴스를 선택합니다.

  3. 태그 탭을 선택합니다.

5. 추가를 선택합니다. 태그 키autostart를 입력합니다. yes를 입력합니다.

  1. 다른 태그 추가를 선택합니다. 태그 키autostop을 입력합니다. 값은yes 를 입력합니다.

  2. 이러한 태그를 저장하려면 추가를 선택합니다.

자세한 내용은 태그 추가, 나열 및 제거를 참조합니다.

상태 머신을 생성하여 태그된 DB 인스턴스를 시작하고 중지합니다.

  1. Step Functions 콘솔을 엽니다.

  2. 탐색 창에서 상태 머신을 선택합니다. 그런 다음 상태 머신 생성을 선택합니다.

  3. 코드로 워크플로 작성을 선택합니다.

  4. 기본 유형표준으로 유지합니다.

5. **정의 ** 편집기에서 샘플 JSON 정의를 삭제합니다. 그런 다음 상태 머신 정의를 입력합니다.

{
  "Comment": "State Machine Definition to start and stop RDS DB instances",
  "StartAt": "Describe DBInstances to Start",
  "States": {
    "Describe DBInstances to Start": {
      "Type": "Task",
      "Parameters": {},
      "Resource": "arn:aws:states:::aws-sdk:rds:describeDBInstances",
      "Next": "Iterate on Instances to Start",
      "Retry": [
        {
          "ErrorEquals": [
            "Rds.InternalFailure",
            "Rds.ServiceUnavailable",
            "Rds.ThrottlingException",
            "Rds.SdkClientException"
          ],
          "BackoffRate": 2,
          "IntervalSeconds": 1,
          "MaxAttempts": 2
        }
      ]
    },
    "Iterate on Instances to Start": {
      "Type": "Map",
      "ItemProcessor": {
        "ProcessorConfig": {
          "Mode": "INLINE"
        },
        "StartAt": "Format Array before Start",
        "States": {
          "Format Array before Start": {
            "Type": "Pass",
            "Next": "Check If Instance stopped, if no Tags or if Tags contains 'autostart=yes'",
            "Parameters": {
              "DbInstanceStatus.$": "$.DBInstance.DbInstanceStatus",
              "DbInstanceIdentifier.$": "$.DBInstance.DbInstanceIdentifier",
              "TagList.$": "$.DBInstance.TagList",
              "TagsArrayLength.$": "States.ArrayLength($.DBInstance.TagList)",
              "TagContainsKey.$": "States.ArrayContains($.DBInstance.TagList,$.LookingFor)"
            }
          },
          "Check If Instance stopped, if no Tags or if Tags contains 'autostart=yes'": {
            "Type": "Choice",
            "Choices": [
              {
                "Not": {
                  "Variable": "$.DbInstanceStatus",
                  "StringEquals": "stopped"
                },
                "Next": "Instance is not in 'stopped' status"
              },
              {
                "Variable": "$.TagsArrayLength",
                "NumericEquals": 0,
                "Next": "No Tags found to Start"
              },
              {
                "Variable": "$.TagContainsKey",
                "BooleanEquals": true,
                "Next": "Tags found Start DBInstance"
              }
            ],
            "Default": "No Tags found to Start"
          },
          "Tags found Start DBInstance": {
            "Type": "Task",
            "Parameters": {
              "DbInstanceIdentifier.$": "$.DbInstanceIdentifier"
            },
            "Resource": "arn:aws:states:::aws-sdk:rds:startDBInstance",
            "Retry": [
              {
                "ErrorEquals": [
                  "Rds.InternalFailure",
                  "Rds.ServiceUnavailable",
                  "Rds.ThrottlingException",
                  "Rds.SdkClientException"
                ],
                "BackoffRate": 2,
                "IntervalSeconds": 1,
                "MaxAttempts": 2
              }
            ],
            "Catch": [
              {
                "ErrorEquals": [
                  "States.ALL"
                ],
                "Next": "Failed to Start DBInstance"
              }
            ],
            "ResultSelector": {
              "message": "Instance Started",
              "DbInstanceIdentifier.$": "$.DbInstance.DbInstanceIdentifier"
            },
            "End": true
          },
          "Failed to Start DBInstance": {
            "Type": "Pass",
            "Parameters": {
              "message": "Failed to start instance",
              "DbInstanceIdentifier.$": "$.DbInstanceIdentifier"
            },
            "End": true
          },
          "No Tags found to Start": {
            "Type": "Pass",
            "End": true,
            "Parameters": {
              "message": "No Tags found to Start",
              "DbInstanceIdentifier.$": "$.DbInstanceIdentifier"
            }
          },
          "Instance is not in 'stopped' status": {
            "Type": "Pass",
            "End": true,
            "Parameters": {
              "message": "Instance is not in 'stopped' status",
              "DbInstanceIdentifier.$": "$.DbInstanceIdentifier"
            }
          }
        }
      },
      "InputPath": "$.DbInstances",
      "Next": "Wait for 1 hour and 30 minutes",
      "ItemSelector": {
        "LookingFor": {
          "Key": "autostart",
          "Value": "yes"
        },
        "DBInstance.$": "$$.Map.Item.Value"
      }
    },
    "Wait for 1 hour and 30 minutes": {
      "Type": "Wait",
      "Seconds": 5400,
      "Next": "Describe DBInstances to Stop"
    },
    "Describe DBInstances to Stop": {
      "Type": "Task",
      "Parameters": {},
      "Resource": "arn:aws:states:::aws-sdk:rds:describeDBInstances",
      "Retry": [
        {
          "ErrorEquals": [
            "Rds.InternalFailure",
            "Rds.ServiceUnavailable",
            "Rds.ThrottlingException",
            "Rds.SdkClientException"
          ],
          "BackoffRate": 2,
          "IntervalSeconds": 1,
          "MaxAttempts": 2
        }
      ],
      "Next": "Iterate on Instances to Stop"
    },
    "Iterate on Instances to Stop": {
      "Type": "Map",
      "ItemProcessor": {
        "ProcessorConfig": {
          "Mode": "INLINE"
        },
        "StartAt": "Format Array before Stop",
        "States": {
          "Format Array before Stop": {
            "Type": "Pass",
            "Next": "Check If Instance available, if no Tags or if Tags contains 'autostop=yes'",
            "Parameters": {
              "DbInstanceStatus.$": "$.DBInstance.DbInstanceStatus",
              "DbInstanceIdentifier.$": "$.DBInstance.DbInstanceIdentifier",
              "TagList.$": "$.DBInstance.TagList",
              "TagsArrayLength.$": "States.ArrayLength($.DBInstance.TagList)",
              "TagContainsKey.$": "States.ArrayContains($.DBInstance.TagList,$.LookingFor)"
            }
          },
          "Check If Instance available, if no Tags or if Tags contains 'autostop=yes'": {
            "Type": "Choice",
            "Choices": [
              {
                "Not": {
                  "Variable": "$.DbInstanceStatus",
                  "StringEquals": "available"
                },
                "Next": "Instance is not in 'available' status"
              },
              {
                "Variable": "$.TagsArrayLength",
                "NumericEquals": 0,
                "Next": "No Tags found to Stop"
              },
              {
                "Variable": "$.TagContainsKey",
                "BooleanEquals": true,
                "Next": "Tags found Stop DBInstance"
              }
            ],
            "Default": "No Tags found to Stop"
          },
          "Tags found Stop DBInstance": {
            "Type": "Task",
            "Parameters": {
              "DbInstanceIdentifier.$": "$.DbInstanceIdentifier"
            },
            "Resource": "arn:aws:states:::aws-sdk:rds:stopDBInstance",
            "Retry": [
              {
                "ErrorEquals": [
                  "Rds.InternalFailure",
                  "Rds.ServiceUnavailable",
                  "Rds.ThrottlingException",
                  "Rds.SdkClientException"
                ],
                "BackoffRate": 2,
                "IntervalSeconds": 1,
                "MaxAttempts": 2
              }
            ],
            "Catch": [
              {
                "ErrorEquals": [
                  "States.ALL"
                ],
                "Next": "Failed to Stop DBInstance"
              }
            ],
            "ResultSelector": {
              "message": "Instance Stopped",
              "DbInstanceIdentifier.$": "$.DbInstance.DbInstanceIdentifier"
            },
            "End": true
          },
          "Failed to Stop DBInstance": {
            "Type": "Pass",
            "Parameters": {
              "message": "Failed to stop instance",
              "DbInstanceIdentifier.$": "$.DbInstanceIdentifier"
            },
            "End": true
          },
          "No Tags found to Stop": {
            "Type": "Pass",
            "End": true,
            "Parameters": {
              "message": "No Tags found to Stop",
              "DbInstanceIdentifier.$": "$.DbInstanceIdentifier"
            }
          },
          "Instance is not in 'available' status": {
            "Type": "Pass",
            "End": true,
            "Parameters": {
              "message": "Instance is not in 'available' status",
              "DbInstanceIdentifier.$": "$.DbInstanceIdentifier"
            }
          }
        }
      },
      "InputPath": "$.DbInstances",
      "Next": "Workflow Finished",
      "ItemSelector": {
        "LookingFor": {
          "Key": "autostop",
          "Value": "yes"
        },
        "DBInstance.$": "$$.Map.Item.Value"
      }
    },
    "Workflow Finished": {
      "Type": "Succeed"
    }
  }
}

참고: 테스트 목적으로 1시간 30분 대기 상태에서 필드를 수정할 수 있습니다. 또한 이 값을 확장하여 유지 관리 기간을 늘리거나 줄일 수 있습니다.

6.    다음을 선택합니다.

  1. 상태 머신의 이름 (예: step-functions-start-stop-rds-state-machine)을입력합니다.

  2. 권한에서 기존 역할 선택을 선택합니다. 그런 다음 생성한 IAM 역할, 예를 들어, step-functions-start-stop-rds-role을 선택합니다.

  3. (선택 사항) 태그를 추가하려면 필드에 적절한 값을 입력합니다.

  4. 상태 머신 생성을 선택합니다.

워크플로 테스트 수행

다음 단계를 수행하여 Stopped 상태의 태그된 DB 인스턴스의 함수 테스트를 완료합니다.

  1. Step Functions 콘솔을 엽니다.

  2. 탐색 창에서 상태 머신을 선택합니다.

  3. 생성한 상태 머신을 선택하여 DB 인스턴스를 시작합니다.

  4. 실행 시작을 선택합니다.
    참고: 이 해결 방법에는 이벤트 페이로드가 필요하지 않습니다. 실행 시작 대화 상자에서 이벤트 페이로드를 제거하거나 기본 이벤트를 그대로 둘 수 있습니다.

  5. 실행 시작을 선택합니다.

일정 생성

태그된 DB 인스턴스의 주간 유지 관리 기간을 예약하려면 EventBridge 규칙을 생성합니다. 이 규칙은 유지 관리 기간 30분 전에 DB 인스턴스를 자동으로 시작합니다.

다음 사용 사례 예시에서 유지 관리 기간은 일요일 22:00~22:30에 일어납니다. 예제의 규칙은 매주 일요일 21:30 에 DB 인스턴스를 시작합니다.

  1. EventBridge 콘솔을 엽니다.

  2. 태그된 DB 인스턴스를 시작하고 중지하는 상태 머신 생성 섹션에서 이전에 생성한 상태 머신을 선택합니다.

  3. 버스에서 규칙을 선택합니다.

  4. 드롭다운 목록에서 기본 이벤트 버스를 선택합니다.

  5. 규칙 생성을 선택합니다.

  6. 규칙 이름에 원하는 규칙의 이름 (예: step-functions-start-stop-rds-rule)을입력합니다.

  7. 규칙 유형에서 일정을 선택합니다. 이 페이지의 다른 값은 기본 설정을 유지합니다.

  8. EventBridge 스케줄러로 계속을 선택합니다.

  9. 반복 일정발생을 선택합니다. 그런 다음 일정 유형에서 CRON 기반 일정을 선택합니다.

  10. 자동화된 일정에 Cron 표현식 (예: cron(30 21 ? * SUN *))을추가합니다.

  11. 변경 가능 시간 창에서 끄기를 선택합니다.

12.    다음을 선택합니다.

  1. 자주 사용하는 API를 선택한 다음 StartExecution을 선택합니다.

  2. StartExecution에서 생성한 상태 머신 (예: step-functions-start-stop-rds-state-machine)을선택합니다. 입력의 기본값인 **{}**을 유지합니다.

15.    다음을 선택합니다.

  1. 재시도 정책 및 DLQ(Dead Letter Queue) 에서 재시도 정책을 지워 비활성화합니다.

  2. 권한에서 다음의 기본 옵션을 유지합니다. 이 일정에 대한 새 역할을 생성합니다.

**참고:EventBridge는 담당할 새 역할을 생성하고 특정 워크플로에 대한 ** StartExecution API를 시작합니다.

  1. 다음을 선택합니다.

  2. 일정 세부 정보에서 다음 10개의 호출 날짜가 예상 일정 날짜와 일치하는지 확인합니다.

  3. 일정 생성을 선택합니다.

EventBridge가 규칙을 호출하면 Step Function 워크플로가 시작됩니다. 이 작업으로 인해 유지 관리 기간 30분 전에 DB 인스턴스가 시작됩니다. 그런 다음 워크플로우는 유지 관리 기간이 끝나고 30분 후에 DB 인스턴스를 중지합니다.  예를 들어 워크플로가 21:30에 DB 인스턴스를 시작한다면, 유지 관리 기간은 22:00~22:30에 시작됩니다. 그런 다음 워크플로는 23:00에 인스턴스를 중지합니다.

댓글 없음