概要
AWS にて RDS の定期ダンプを取得したかったので ECS にある cron 的な機能を使ってダンプを定期取得する設定をしてみた
ECS で動かす定期実行用のコンテナのイメージやタスクも管理を自動化してみた
今回 postgres が対象です mysql 等は適宜 dockerfile を変更してください
前提条件
- AWS のアカウント取得済み
- RDS 構築済み
- bitbucket のアカウント取得済み
準備
IAM ユーザーの作成
今回 bitbucket pipeline からのデプロイとダンプデータ S3 へのアップロード用にユーザーを作成する。
通常はデプロイと S3 でユーザーを分けた方がいいのだが今回は管理コストの面で一つで作成します。
IAM を開き左メニューにあるユーザーを開くその後ユーザーの追加を開くと下記の様な画面になる
ユーザー名を適宜入力,アクセスの種類をプログラムによるアクセスに制限

AmazonECS_FullAccess, AmazonEC2ContainerRegistryFullAccess, AmazonS3FullAccessを選択(今回 CLI で同一ユーザーを使いたかったので広に権限取ってあります。わかる人は適宜絞ってください。)

その後特に設定項目はないのでユーザーの作成まで進む
最後にこのような画面が表示されるのでアクセスキー ID とシークレットアクセスキーをメモしておいてください。シークレットアクセスキーに関しては追加発行できますが二度と再表示できないので絶対にメモしておいてください。

IAM ロールの作成
タスクを実行するためのロールだが自動で作られるものではあるのだが ECS を全く使っていない場合は作成されていないので手動で作成する。
(ecsTaskExecutionRoleと最後に付くロールが既にある場合はその ARN をメモしておいてください)
IAM を開き左メニューにあるロールを開くその後ロールの作成を開くと下記の様な画面になる
Elastic Container Serviceを選択次にElastic Container Service Taskを選択次へ

AmazonECSTaskExecutionRolePolicyを選択その後特に設定項目はないのでロールの作成まで進む

作成が完了したら元の画面に戻ってくるので先ほど作成したロールを開く下記画面のロール ARNをメモしておいてください。

バケットの作成
特別設定する項目はありません。適宜設定の上作成しておいてください。
その際作成した名前をメモしておいてください。
ECR リポジトリの作成
こちらも特別設定する項目はありませんが、パイプラインでタグを上書きする関係上タグのイミュータビリティは無効化しておいてください(デフォルトで無効)
作成した後 URI のカラムにある URL みたいなものをメモしておいてください。
bitbucket でリポジトリの作成
いつも通りリポジトリを作成してください。
ローカルで下記の通りファイルを作成してください。
~/ ├ .pgpass ├ bitbucket-pipelines.yml ├ Dockerfile └ docker-entrypoint.sh.pgpass は postgres にパスワードを省略してアクセスするためのパスワードファイルですダ下記の通り記述してください。
hostname:port:database:username:passwordbitbucket-pipelines.yml は bitbucket のパイプラインの定義を記述するファイルです下記の通り記述してください。
execution-role-arn のところに先ほどメモしたロール ARNを記入してください。
# enable Docker for your repositoryoptions: docker: true
pipelines: default: - step: name: build-push image: atlassian/pipelines-awscli:latest deployment: test caches: - docker script: # aws login - eval $(aws ecr get-login --no-include-email --region ${AWS_DEFAULT_REGION}) # docker - export BUILD_ID=$BITBUCKET_BRANCH_$BITBUCKET_COMMIT_$BITBUCKET_BUILD_NUMBER - docker build -t ${AWS_REGISTRY_URL}:$BUILD_ID -t ${AWS_REGISTRY_URL}:development . - docker push ${AWS_REGISTRY_URL}
- step: name: deploy image: atlassian/pipelines-awscli:latest deployment: production script: - export BUILD_ID=$BITBUCKET_BRANCH_$BITBUCKET_COMMIT_$BITBUCKET_BUILD_NUMBER - export IMAGE_NAME="${AWS_REGISTRY_URL}:$BUILD_ID" # ECS variables - export ECS_CLUSTER_NAME="${BITBUCKET_REPO_OWNER}" - export ECS_SERVICE_NAME="${BITBUCKET_REPO_SLUG}" - export ECS_TASK_NAME="${BITBUCKET_REPO_SLUG}" # Create ECS cluster, task, service - aws ecs list-clusters | grep "${ECS_CLUSTER_NAME}" || aws ecs create-cluster --cluster-name "${ECS_CLUSTER_NAME}" # Updating the existing cluster, task, service - export TASK_VERSION=$(aws ecs register-task-definition --family "${ECS_TASK_NAME}" --execution-role-arn "" --network-mode "awsvpc" --requires-compatibilities "FARGATE" --cpu "256" --memory "512" --container-definitions "[{\"name\":\"${ECS_TASK_NAME}\",\"image\":\"${IMAGE_NAME}\",\"logConfiguration\":{\"logDriver\":\"awslogs\",\"options\":{\"awslogs-group\":\"/ecs\",\"awslogs-region\":\"${AWS_DEFAULT_REGION}\",\"awslogs-stream-prefix\":\"${ECS_TASK_NAME}\"}}}]" | jq --raw-output '.taskDefinition.revision') - echo "Registered ECS Task Definition:" "${TASK_VERSION}"Dockerfile は ECS でデプロイする用のコンテナ定義です下記の通り記述してください。
補足がある箇所は先ほどメモしたものから適宜いれてください。
FROM alpine
RUN apk --no-cache add postgresql-client python3RUN pip3 install awscliENV AWS_DEFAULT_REGION ap-northeast-1ENV AWS_ACCESS_KEY_ID {アクセスキーID}ENV AWS_SECRET_ACCESS_KEY {シークレットアクセスキー}RUN mkdir dumpWORKDIR /root/dumpADD .pgpass /root/.pgpassRUN chmod 0600 /root/.pgpassADD docker-entrypoint.sh /root/docker-entrypoint.shRUN chmod +x /root/docker-entrypoint.sh
CMD ["/root/docker-entrypoint.sh"]docker-entrypoint.sh は docker 起動時に実行するコマンド群ですいわゆる cron の中身です。
補足がある箇所は先ほどメモしたものから適宜いれてください。
保存構成的には最初のプレフィックスが削除周期次に DB 名最後にファイルの接頭辞が今回はダンプの周期を入れています。
#!/bin/sh
mkdir -p yearly/{DB名}pg_dump -Fc -h {DBのホスト} -U {ユーザー} {DB名} > yearly/{DB名}/weekly-`date "+%Y%m%d_%H%M%S"`.customaws s3 sync . s3://{S3のバケット}準備が完了したらいつもの通り先ほど作成したリポジトリにプッシュしてください。
bitbucket での pipeline の準備
先ほどプッシュしたリポジトリを bitbucket で開く
設定->PIPELINES->Settings に進みEnable Pipelinesを有効にする

次にRepository variablesを開く
下記の通り先ほどメモしたものから設定をする。

デプロイと cron の設定
デプロイの実行
引き続き bitbucket の画面で再度メニューからPipelinesを開く次にRun pipelineをクリックし下記の通り選択してRunをクリック

完了すると下記の様になるのでパイプラインが完了するのを待つ

次回以降ブランチに変更が入る度自動で実行されます。
AWS でスケジュールの作成
AWS ECS 上でリポジトリオーナー名でクラスタが作成されているのでそのクラスタを開く(クラスタ名が書かれているところをクリックすると開きます)。

タスクのスケジューリングのタブを開き作成をクリック

実行間隔等を設定しターゲットの部分は今回FARGATE用にタスクを作成したので起動タイプをFARGATEを選択タスク定義のファミリーはリポジトリ名と同名のタスクがあるのでそれを選択する。VPC とセキュリティグループは適宜設定してください。

補足
AWS_Cron 式のワイルドカード