RDS+ECSで定期的にダンプをS3に保存してみる

概要

AWSにてRDSの定期ダンプを取得したかったのでECSにあるcron的な機能を使ってダンプを定期取得する設定をしてみた ECSで動かす定期実行用のコンテナのイメージやタスクも管理を自動化してみた 今回postgresが対象ですmysql等は適宜dockerfileを変更してください

前提条件

  • AWSのアカウント取得済み
  • RDS構築済み
  • bitbucketのアカウント取得済み

準備

IAMユーザーの作成

今回bitbucket pipelineからのデプロイとダンプデータS3へのアップロード用にユーザーを作成する。 通常はデプロイとS3でユーザーを分けた方がいいのだが今回は管理コストの面で一つで作成します。

IAMを開き左メニューにあるユーザーを開くその後ユーザーの追加を開くと下記の様な画面になる ユーザー名を適宜入力,アクセスの種類をプログラムによるアクセスに制限 console.aws.amazon.com_iam_home_.png AmazonECS_FullAccess,AmazonEC2ContainerRegistryFullAccess,AmazonS3FullAccessを選択(今回CLIで同一ユーザーを使いたかったので広に権限取ってあります。わかる人は適宜絞ってください。) console.aws.amazon.com_iam_home_ (1).png その後特に設定項目はないのでユーザーの作成まで進む 最後にこのような画面が表示されるのでアクセスキーIDとシークレットアクセスキーをメモしておいてください。シークレットアクセスキーに関しては追加発行できますが二度と再表示できないので絶対にメモしておいてください。 console.aws.amazon.com_iam_home_ (2).png

IAMロールの作成

タスクを実行するためのロールだが自動で作られるものではあるのだがECSを全く使っていない場合は作成されていないので手動で作成する。 (ecsTaskExecutionRoleと最後に付くロールが既にある場合はそのARNをメモしておいてください) IAMを開き左メニューにあるロールを開くその後ロールの作成を開くと下記の様な画面になる Elastic Container Serviceを選択次にElastic Container Service Taskを選択次へ console.aws.amazon.com_iam_home_region=ap-northeast-1 (1).png AmazonECSTaskExecutionRolePolicyを選択その後特に設定項目はないのでロールの作成まで進む console.aws.amazon.com_iam_home_region=ap-northeast-1 (2).png 作成が完了したら元の画面に戻ってくるので先ほど作成したロールを開く下記画面のロール ARNをメモしておいてください。 console.aws.amazon.com_iam_home_region=ap-northeast-1 (4).png

バケットの作成

特別設定する項目はありません。適宜設定の上作成しておいてください。 その際作成した名前をメモしておいてください。

ECRリポジトリの作成

こちらも特別設定する項目はありませんが、パイプラインでタグを上書きする関係上タグのイミュータビリティは無効化しておいてください(デフォルトで無効) 作成した後URIのカラムにあるURLみたいなものをメモしておいてください。

bitbucketでリポジトリの作成

いつも通りリポジトリを作成してください。 ローカルで下記の通りファイルを作成してください。

~/
 ├ .pgpass
 ├ bitbucket-pipelines.yml
 ├ Dockerfile
 └ docker-entrypoint.sh

.pgpassはpostgresにパスワードを省略してアクセスするためのパスワードファイルですダ下記の通り記述してください。

hostname:port:database:username:password

bitbucket-pipelines.ymlはbitbucketのパイプラインの定義を記述するファイルです下記の通り記述してください。 execution-role-arnのところに先ほどメモしたロール ARNを記入してください。

# enable Docker for your repository
options:
  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 python3
RUN pip3 install awscli
ENV AWS_DEFAULT_REGION ap-northeast-1
ENV AWS_ACCESS_KEY_ID {アクセスキーID}
ENV AWS_SECRET_ACCESS_KEY {シークレットアクセスキー}
RUN mkdir dump
WORKDIR /root/dump
ADD .pgpass /root/.pgpass
RUN chmod 0600 /root/.pgpass
ADD docker-entrypoint.sh /root/docker-entrypoint.sh
RUN 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"`.custom
aws s3 sync . s3://{S3のバケット}

準備が完了したらいつもの通り先ほど作成したリポジトリにプッシュしてください。

bitbucketでのpipelineの準備

先ほどプッシュしたリポジトリをbitbucketで開く 設定->PIPELINES->Settingsに進みEnable Pipelinesを有効にする bitbucket.org_j-roi_dump_admin_addon_admin_pipelines_settings.png 次にRepository variablesを開く 下記の通り先ほどメモしたものから設定をする。 bitbucket.org_j-roi_dump_admin_addon_admin_pipelines_repository-variables.png

デプロイとcronの設定

デプロイの実行

引き続きbitbucketの画面で再度メニューからPipelinesを開く次にRun pipelineをクリックし下記の通り選択してRunをクリック bitbucket.org_j-roi_dump_addon_pipelines_home.png 完了すると下記の様になるのでパイプラインが完了するのを待つ bitbucket.org_j-roi_dump_addon_pipelines_home (1).png 次回以降ブランチに変更が入る度自動で実行されます。

AWSでスケジュールの作成

AWS ECS上でリポジトリオーナー名でクラスタが作成されているのでそのクラスタを開く(クラスタ名が書かれているところをクリックすると開きます)。 ap-northeast-1.console.aws.amazon.com_ecs_home_region=ap-northeast-1.png タスクのスケジューリングのタブを開き作成をクリック ap-northeast-1.console.aws.amazon.com_ecs_home_region=ap-northeast-1 (1).png 実行間隔等を設定しターゲットの部分は今回FARGATE用にタスクを作成したので起動タイプをFARGATEを選択タスク定義のファミリーはリポジトリ名と同名のタスクがあるのでそれを選択する。VPCとセキュリティグループは適宜設定してください。 ap-northeast-1.console.aws.amazon.com_ecs_home_region=ap-northeast-1 (2).png 補足:Cron式を選択したときに躓いたのだがbusybox cron等のcron式とは違う模様下記を参考にいたしました。 https://qiita.com/da-sugi/items/ef3bb45a8a99a4acacb1

Edit this page

株式会社ユニヴァ・ペイキャスト/MIS

木更津高専6ヶ月中退→ウェブマーケの会社でウェブエンジニア→SESでウェブ関係色々→決済代行会社の中の人

関連項目