CircleCIでcdk deployしようとしてAWSの認証でハマった2点


追記 2021/09/15
* ハマり2の解決策で追加すべきものを追加
* おまけハマりを追加

はじめに

CircleCIからaws cdkでデプロイ仕様とした時に、AWSの認証関連でハマった2点です。
CircleCIでの実行ですが、多分どのパイプラインサービスでも同じだと思います。

前提

  • CircleCI用のIAMユーザー circleci-user を作成しCredentialsを生成しておく。
  • circleci-user は必要最低限の権限とする。
  • CloudFormation実行用のIAM Role CFn-Roleを作成してcdkのオプションで指定する。

ハマり1:cdkではProfileが必要

AWS_DEFAULT_REGION=ap-northeast-1
AWS_ACCESS_KEY_ID=AKxxxxxxxxxxxxxxxxxxxxx
AWS_SECRET_ACCESS_KEY=xxxxxxxxxxxxxxxx

npm run cdk -- deploy --require-approval never

と実行しても以下のようなエラーになる。

DynamoCdkStack: deploying...

 ❌  DynamoCdkStack failed: Error: Unable to resolve AWS account to use. It must be either configured when you define your CDK Stack, or through the environment
    at SdkProvider.resolveEnvironment (/home/circleci/work/Dynamo-CDK/node_modules/aws-cdk/lib/api/aws-auth/sdk-provider.ts:208:13)

ハマり1の解決:Profileを設定する

どうやらProfileの設定は必須のようなので作成する。

AWS_PROFILE_NAME=prd
aws --profile ${AWS_PROFILE_NAME} configure set aws_access_key_id ${AWS_ACCESS_KEY_ID}
aws --profile ${AWS_PROFILE_NAME} configure set aws_secret_access_key ${AWS_SECRET_ACCESS_KEY}
aws --profile ${AWS_PROFILE_NAME} configure set region ${AWS_DEFAULT_REGION}

npm run cdk -- deploy --require-approval never --profile ${AWS_PROFILE_NAME}

ハマり2: --role-arnを指定しても途中までは実行ユーザーの権限

最小権限の原則に則り circleci-user にはiam:PassRoleのみを設定して、cdkのオプションに--role-arnを指定したのですが、権限足りないエラーになりました。

npm run cdk deploy --role-arn" "************************************************************************** --require-approval never --profile ${AWS_PROFILE_NAME}

DynamoCdkStack: deploying...

 ❌  DynamoCdkStack failed: AccessDenied: User: arn:aws:iam::123456789012:user/circleci-user is not authorized to perform: cloudformation:DescribeStacks on resource: arn:aws:cloudformation:ap-northeast-1:123456789012:stack/CDKToolkit/*
    at Request.extractError (/home/circleci/work/Dynamo-CDK/node_modules/aws-cdk/node_modules/aws-sdk/lib/protocol/query.js:50:29)

ハマり2の解決:実行ユーザーにはいくつか権限が必要

cdkの--role-arnはターゲットとするStackに対する操作には使用されるが事前の「CDKToolkit」スタックからの情報取得やChangesetの作成までは実行ユーザーの権限で行われるようです。

circleci-userに以下の権限を付与します。

  • ManagedPolicyの AWSCloudFormationReadOnlyAccess
  • CDKToolkitスタック(cdk bootstrapで作成される)で作成されるS3Bucketに対する書き込み権限
  • cloudformation:CreateChangeSet/ExecuteChangeSet/DeleteChangeSet権限(これは事前にStack名がわからないのでResource:*

おまけハマり:謎のエラー

 failed: Error: This stack uses assets, so the toolkit stack must be deployed to the environment (Run "cdk bootstrap aws://unknown-account/unknown-region")

なんじゃこりゃ?と思ったらcdk bootstrapをそのAWSアカウントで実行していなかったためでした。