Tech Racho エンジニアの「?」を「!」に。
  • インフラ

AWS CodeBuildからECSへexecute-commandする

構成

CodeBuildからVPC内のリソースにアクセスするためには以下のような構成をとる場合が多いと思います。

プライベートサブネットを作成して、インターネット接続のためにNAT gatewayを配置:

この他にVPC外のCodeBuildからexecute-commandを経由してVPC内リソースにアクセスする方法もあります。
ECSのコンテナを立てる時間があるので、build時間が1~2分長くなりますが、Nat gatewayは0.062USD/hourくらいかかるので料金の節約になります。

設定例

ここでは例として、VPC内で./bin/rails db:migrateをexecute-commandを利用して実行します。

  • buildspec.yml
version: 0.2
phases:
  install:
    commands:
      # session-manager-pluginを入れておく
      - curl https://s3.amazonaws.com/session-manager-downloads/plugin/latest/ubuntu_64bit/session-manager-plugin.deb -o /tmp/session-manager-plugin.deb
      - dpkg -i /tmp/session-manager-plugin.deb
  pre_build:
    commands:
      - BASE_URI=xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com
      - aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin $BASE_URI
      - REPOSITORY_URI=$BASE_URI/$ENV-example:latest
  build:
    commands:
      - docker build -t $REPOSITORY_URI .
      - docker push $REPOSITORY_URI
  post_build:
    commands:
      - ./db-migrate.sh
  • db-migrate.sh
#!/bin/bash
set -euxo pipefail
# taskが残留しないように1時間で落ちるようにしておく
cat <<EOF > /tmp/overrides.json
  {
    "containerOverrides": [
      {
        "name": "app",
        "command": ["sleep", "1h"]
      }
    ]
  }
EOF
task_arn=$(aws ecs run-task --cluster example-cluster --count 1 --launch-type FARGATE \
        --enable-execute-command \
        --network-configuration "awsvpcConfiguration={subnets=[subnet-xxxxxxxx,subnet-xxxxxxxx,subnet-xxxxxxxx],securityGroups=[sg-xxxxxxxxxxxxxxxxx],assignPublicIp=ENABLED}" \
        --task-definition example \
        --output json \
        --overrides file:///tmp/overrides.json | jq -r .tasks[0].containers[0].taskArn)
echo "wait for task running"
until [ "$(aws ecs describe-tasks --cluster example-cluster --tasks $task_arn | jq -r .tasks[0].containers[0].lastStatus)" = "RUNNING" ]
do
    echo -n "."
    sleep 30
done
# RUNNINGになっても、しばらく待たないと、execute-commandできない
sleep 30
# 実行
aws ecs execute-command \
    --cluster example-cluster \
    --task $task_arn \
    --interactive \
    --command "./bin/rails db:migrate"
# 停止
aws ecs stop-task --cluster example-cluster --task $task_arn

関連記事

AWS Organizationで一括請求を使うときの不満点


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。