0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

CDK + ECS + Lambda runner のデプロイを Bash ウィザードに寄せた話

0
Posted at

はじめに

AWS CDK でインフラを管理し、ECS で Web/API を動かし、Lambda container image で runner を動かす構成では、デプロイ手順が増えがちです。

たとえば、1 回のリリースで必要になる操作はこれくらいあります。

  • Docker image を build する
  • ECR に push する
  • CDK deploy する
  • ECS service を再デプロイする
  • Lambda function の image tag を更新する
  • DB migration を流す
  • 環境ごとの suffix や context を切り替える
  • 本番操作だけ明示確認する

全部を README に書くだけだと、操作漏れや環境取り違えが起きます。

そこで、よく使う操作を Bash の deploy wizard に集約しました。

目的

wizard の目的は「何でも自動化すること」ではありません。

狙いは次です。

  • 環境ごとの操作入口を揃える
  • infra deploy と code deploy を分ける
  • 危険な操作には確認を入れる
  • .env のローカル設定で AWS 認証を壊さない
  • image tag と CDK context を揃える
  • よく使う運用コマンドを迷わず実行できる

コマンド入口

root の package.json から呼べるようにします。

{
  "scripts": {
    "wizard": "bash infra/scripts/wizard.sh",
    "wizard:dev": "bash infra/scripts/wizard.sh --env dev",
    "wizard:sandbox": "bash infra/scripts/wizard.sh --env sandbox",
    "wizard:prod": "bash infra/scripts/wizard.sh --env prod",
    "wizard:dev:migrate": "bash infra/scripts/wizard.sh --env dev migrate",
    "wizard:dev:seed": "bash infra/scripts/wizard.sh --env dev seed"
  }
}

開発者はまず pnpm wizard を覚えればよい形にします。

環境選択

対話実行では環境を選びます。

select_env() {
  echo "環境を選択してください:"
  echo "  1) dev"
  echo "  2) sstg"
  echo "  3) prod"
  echo "  4) dev + stg"

  read -p "選択 [1-4]: " choice

  case "$choice" in
    1) ENV_TARGETS=("dev") ;;
    2) ENV_TARGETS=("sandbox") ;;
    3) ENV_TARGETS=("prod") ;;
    4) ENV_TARGETS=("dev" "sandbox") ;;
    *) exit 1 ;;
  esac
}

dev + stg のように複数環境へ順番に反映する選択肢も用意しておくと、検証環境の同期が楽になります。

本番操作は明示確認する

本番環境では、ただの [Y/n] では弱いので、環境名を入力させます。

confirm_prod() {
  echo "本番環境への操作です。"
  read -p "確認: \"prod\" と入力してください: " answer

  if [[ "$answer" != "prod" ]]; then
    echo "キャンセルしました"
    exit 0
  fi
}

この手の確認は地味ですが、環境取り違えの最後の防波堤になります。

.env が AWS 認証を壊さないようにする

ローカル開発では .env に LocalStack 用の値が入ることがあります。

AWS_ACCESS_KEY_ID=test
AWS_SECRET_ACCESS_KEY=test
AWS_ENDPOINT_URL=http://localhost:4566

これを AWS デプロイ時にそのまま読んでしまうと、ECR push や CDK deploy が壊れます。

aws-vault などで認証済みの場合は、AWS 認証情報を退避してから .env を読み、認証情報だけ戻します。

if [ -f "$PROJECT_ROOT/.env" ] && [ -n "${AWS_VAULT:-}" ]; then
  SAVED_KEY_ID="${AWS_ACCESS_KEY_ID:-}"
  SAVED_SECRET="${AWS_SECRET_ACCESS_KEY:-}"
  SAVED_TOKEN="${AWS_SESSION_TOKEN:-}"

  set -a
  source "$PROJECT_ROOT/.env"
  set +a

  export AWS_ACCESS_KEY_ID="$SAVED_KEY_ID"
  export AWS_SECRET_ACCESS_KEY="$SAVED_SECRET"
  export AWS_SESSION_TOKEN="$SAVED_TOKEN"
fi

deploy action を分ける

全部を毎回 full deploy すると遅いです。

よく使う操作を分けます。

1) コード反映
   image build/push -> ECS/Lambda 反映

2) CDK deploy
   infra / runtime 設定の反映

3) full deploy
   CDK + build/push + migration + app 反映

4) DB migration

5) ECS service restart

6) Lambda runner 更新

7) logs / status / seed などの運用ツール

この分岐があるだけで、普段の反映がかなり速くなります。

CDK deploy の範囲も分ける

CDK stack が増えてくると、毎回全 stack を deploy するのは重くなります。

Runtime 系のみ:
  ECR
  ECS
  Lambda
  EventBridge
  Scheduler

全 stack:
  VPC
  RDS
  Cognito
  WAF
  Runtime 系
select_cdk_scope() {
  echo "CDK deploy 範囲:"
  echo "  1) Runtime 系のみ"
  echo "  2) 全 stack"

  read -p "選択 [1-2]: " choice
  case "$choice" in
    1) ACTION="cdk_deploy_app" ;;
    2) ACTION="cdk_deploy_all" ;;
  esac
}

ネットワークや DB を触る deploy と、アプリ実行基盤だけの deploy を分けておくと、心理的にも安全です。

まとめ

CDK + ECS + Lambda runner の構成では、デプロイ手順が増えます。

README に手順を書くことも大事ですが、毎回の操作は script に寄せた方が楽です。

やってよかったことは次です。

  • 環境選択を wizard にする
  • 本番だけ強い確認を入れる
  • .env と AWS 認証情報の衝突を避ける
  • STS で account id を補完する
  • deploy action を分ける
  • CDK deploy の範囲を分ける
  • image tag と CDK context を git sha で揃える
  • Lambda runner の更新対象を選べるようにする
  • LocalStack bootstrap は別 script にする

デプロイは「気合いで手順を守る」より、「間違いにくい入口を作る」方が長く効きます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?