Github Actions多AWS账户配置遇阻:CDKTF部署及状态访问失败
问题背景
我要在Github Actions上搭建支持多AWS账户的CI流水线:用dev账户部署开发基础设施,admin账户通过S3桶管理多项目Terraform状态。CDKTF部署时需要同时访问两个账户:一个是执行部署的AWS Provider,另一个是存储状态的S3桶。
第一次尝试:先后配置两个AWS角色
按照aws-actions/configure-aws-credentials文档配置,先后切换到dev和admin账户:
- name: Configure AWS Credentials for Dev uses: aws-actions/configure-aws-credentials@v1 with: aws-region: $AWS_REGION role-to-assume: ${{ secrets.CI_ROLE_ARN_DEV }} role-session-name: dev-session - name: Configure AWS Credentials for Admin uses: aws-actions/configure-aws-credentials@v1 with: aws-region: $AWS_REGION role-to-assume: ${{ secrets.CI_ROLE_ARN_ADMIN }} role-session-name: admin-session
但运行cdktf deploy时报错:failed to get shared config profile, dev——因为我的CDKTF代码里指定了Provider用dev配置文件:
const provider = new AwsProvider(this, 'aws-provider', { region: awsRegion, profile: 'dev' });
而且Github Actions里最后配置的是admin账户,aws sts get-caller-identity显示当前身份是admin,没法同时保留两个账户的配置文件。(本地用SSO登录两个配置文件后能正常部署)
第二次尝试:手动配置AWS凭证文件
参考StackOverflow方案,直接在CI里写入两个配置文件:
- name: Configure aws credentials run: | aws configure set aws_access_key_id ${{ secrets.AWS_ACCESS_KEY_ID_DEV }} --profile dev aws configure set aws_secret_access_key ${{ secrets.AWS_SECRET_ACCESS_KEY_DEV }} --profile dev aws configure set aws_access_key_id ${{ secrets.AWS_ACCESS_KEY_ID_ADMIN }} --profile admin aws configure set aws_secret_access_key ${{ secrets.AWS_SECRET_ACCESS_KEY_ADMIN }} admin cat "$AWS_SHARED_CREDENTIALS_FILE"
虽然凭证文件内容正确,但cdktf deploy还是报错:
error configuring S3 Backend: no valid credential sources for S3 Backend found.
同时用aws sts get-caller-identity --profile dev和--profile admin都返回:
An error occurred (InvalidClientTokenId) when calling the GetCallerIdentity operation: The security token included in the request is invalid.
解决方案
方法1:用aws-actions/configure-aws-credentials生成多配置文件
aws-actions/configure-aws-credentials默认只会覆盖当前环境凭证,不会生成配置文件。要生成多个有效配置,需要结合角色临时凭证和aws configure:
- 获取dev账户临时凭证,写入
dev配置文件:
- name: Get Dev Role Credentials id: dev-creds uses: aws-actions/configure-aws-credentials@v1 with: aws-region: $AWS_REGION role-to-assume: ${{ secrets.CI_ROLE_ARN_DEV }} role-session-name: dev-session output-credentials: true - name: Configure Dev Profile run: | aws configure set aws_access_key_id ${{ steps.dev-creds.outputs.aws-access-key-id }} --profile dev aws configure set aws_secret_access_key ${{ steps.dev-creds.outputs.aws-secret-access-key }} --profile dev aws configure set aws_session_token ${{ steps.dev-creds.outputs.aws-session-token }} --profile dev aws configure set region $AWS_REGION --profile dev
- 获取admin账户临时凭证,写入
admin配置文件:
- name: Get Admin Role Credentials id: admin-creds uses: aws-actions/configure-aws-credentials@v1 with: aws-region: $AWS_REGION role-to-assume: ${{ secrets.CI_ROLE_ARN_ADMIN }} role-session-name: admin-session output-credentials: true - name: Configure Admin Profile run: | aws configure set aws_access_key_id ${{ steps.admin-creds.outputs.aws-access-key-id }} --profile admin aws configure set aws_secret_access_key ${{ steps.admin-creds.outputs.aws-secret-access-key }} --profile admin aws configure set aws_session_token ${{ steps.admin-creds.outputs.aws-session-token }} --profile admin aws configure set region $AWS_REGION --profile admin
这样CDKTF就能通过profile: 'dev'访问部署账户,后端配置用profile: 'admin'访问状态存储账户。
方法2:CDKTF代码直接指定凭证(不依赖配置文件)
如果不想依赖AWS配置文件,可以在代码里直接传入临时凭证:
// 配置dev部署账户的Provider const devProvider = new AwsProvider(this, 'aws-provider-dev', { region: awsRegion, accessKey: process.env.AWS_ACCESS_KEY_ID_DEV, secretKey: process.env.AWS_SECRET_ACCESS_KEY_DEV, token: process.env.AWS_SESSION_TOKEN_DEV }); // 配置Terraform后端用admin账户 new TerraformBackend(this, 'backend', { backend: 's3', config: { bucket: 'your-admin-tf-state-bucket', key: 'dev-infra/terraform.tfstate', region: awsRegion, access_key: process.env.AWS_ACCESS_KEY_ID_ADMIN, secret_key: process.env.AWS_SECRET_ACCESS_KEY_ADMIN, session_token: process.env.AWS_SESSION_TOKEN_ADMIN } });
然后在Github Actions中获取两个账户的临时凭证,设置为环境变量:
- name: Get Dev Role Credentials id: dev-creds uses: aws-actions/configure-aws-credentials@v1 with: aws-region: $AWS_REGION role-to-assume: ${{ secrets.CI_ROLE_ARN_DEV }} role-session-name: dev-session output-credentials: true - name: Set Dev Env Vars run: | echo "AWS_ACCESS_KEY_ID_DEV=${{ steps.dev-creds.outputs.aws-access-key-id }}" >> $GITHUB_ENV echo "AWS_SECRET_ACCESS_KEY_DEV=${{ steps.dev-creds.outputs.aws-secret-access-key }}" >> $GITHUB_ENV echo "AWS_SESSION_TOKEN_DEV=${{ steps.dev-creds.outputs.aws-session-token }}" >> $GITHUB_ENV - name: Get Admin Role Credentials id: admin-creds uses: aws-actions/configure-aws-credentials@v1 with: aws-region: $AWS_REGION role-to-assume: ${{ secrets.CI_ROLE_ARN_ADMIN }} role-session-name: admin-session output-credentials: true - name: Set Admin Env Vars run: | echo "AWS_ACCESS_KEY_ID_ADMIN=${{ steps.admin-creds.outputs.aws-access-key-id }}" >> $GITHUB_ENV echo "AWS_SECRET_ACCESS_KEY_ADMIN=${{ steps.admin-creds.outputs.aws-secret-access-key }}" >> $GITHUB_ENV echo "AWS_SESSION_TOKEN_ADMIN=${{ steps.admin-creds.outputs.aws-session-token }}" >> $GITHUB_ENV
关键注意点
- 使用角色临时凭证时,必须同时配置
aws_session_token——之前的错误就是因为手动配置时漏掉了这个参数。 aws-actions/configure-aws-credentials的output-credentials: true参数会输出临时凭证,用于后续生成配置文件或环境变量。- 本地SSO登录会自动处理session token,但CI环境需要显式配置。
内容的提问来源于stack exchange,提问作者bogdanos

