基于GitHub Actions+Terraform删除AWS成员账户默认VPC报错排查
解决AWS Landing Zone多OU环境下Terraform local-exec凭证缺失问题
问题根源
GitHub Actions通过OIDC获取的AWS凭证未传递到null_resource的local-exec环境中,导致aws sts assume-role无法找到有效凭证;同时local-exec默认不会继承Terraform的AWS环境变量,需显式配置。
解决步骤
1. 显式传递AWS凭证到local-exec
在Terraform中定义凭证变量,并将其注入local-exec的环境变量:
# 定义从GitHub Actions传入的AWS凭证变量 variable "aws_access_key_id" { type = string } variable "aws_secret_access_key" { type = string } variable "aws_session_token" { type = string } variable "member_account_ids" { type = list(string) description = "成员账户ID列表" } # 批量处理成员账户的null_resource resource "null_resource" "delete_default_vpcs" { for_each = toset(var.member_account_ids) provisioner "local-exec" { # 注入AWS凭证环境变量 environment = { AWS_ACCESS_KEY_ID = var.aws_access_key_id AWS_SECRET_ACCESS_KEY = var.aws_secret_access_key AWS_SESSION_TOKEN = var.aws_session_token MEMBER_ACCOUNT_ID = each.value } command = "./delete_default_vpc.sh ${each.value}" } }
2. 完善删除默认VPC的脚本
delete_default_vpc.sh需先扮演成员账户的OrganizationAccountAccessRole,再清理默认VPC及其依赖资源:
#!/bin/bash set -e MEMBER_ACCOUNT_ID=$1 # 扮演成员账户的OrganizationAccountAccessRole ASSUME_ROLE_RESPONSE=$(aws sts assume-role \ --role-arn "arn:aws:iam::${MEMBER_ACCOUNT_ID}:role/OrganizationAccountAccessRole" \ --role-session-name "delete-default-vpc-session") # 提取临时凭证并设置环境变量 export AWS_ACCESS_KEY_ID=$(echo "$ASSUME_ROLE_RESPONSE" | jq -r '.Credentials.AccessKeyId') export AWS_SECRET_ACCESS_KEY=$(echo "$ASSUME_ROLE_RESPONSE" | jq -r '.Credentials.SecretAccessKey') export AWS_SESSION_TOKEN=$(echo "$ASSUME_ROLE_RESPONSE" | jq -r '.Credentials.SessionToken') # 查询默认VPC DEFAULT_VPC_ID=$(aws ec2 describe-vpcs --filters "Name=is-default,Values=true" --query 'Vpcs[0].VpcId' --output text) if [ "$DEFAULT_VPC_ID" != "None" ]; then # 删除依赖资源:子网、互联网网关 SUBNET_IDS=$(aws ec2 describe-subnets --filters "Name=vpc-id,Values=$DEFAULT_VPC_ID" --query 'Subnets[*].SubnetId' --output text) if [ -n "$SUBNET_IDS" ]; then aws ec2 delete-subnets --subnet-ids $SUBNET_IDS fi IGW_IDS=$(aws ec2 describe-internet-gateways --filters "Name=attachment.vpc-id,Values=$DEFAULT_VPC_ID" --query 'InternetGateways[*].InternetGatewayId' --output text) if [ -n "$IGW_IDS" ]; then aws ec2 detach-internet-gateway --internet-gateway-id $IGW_IDS --vpc-id $DEFAULT_VPC_ID aws ec2 delete-internet-gateways --internet-gateway-ids $IGW_IDS fi # 删除默认VPC aws ec2 delete-vpc --vpc-id $DEFAULT_VPC_ID echo "账户${MEMBER_ACCOUNT_ID}的默认VPC ${DEFAULT_VPC_ID}已删除" else echo "账户${MEMBER_ACCOUNT_ID}无默认VPC" fi
3. 确保权限配置正确
- 流水线角色权限:
AWS_PIPELINE_ROLE_ARN_ABC需拥有sts:AssumeRole权限,目标资源为所有成员账户的OrganizationAccountAccessRole:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::*:role/OrganizationAccountAccessRole" } ] }
- 成员账户角色信任:确认
OrganizationAccountAccessRole的信任策略允许流水线角色所在账户(或直接指定流水线角色ARN)扮演它,Landing Zone默认已配置此信任,但需验证。
4. GitHub Actions工作流传递变量
在GitHub Actions中,将OIDC获取的凭证传递给Terraform:
- name: 配置AWS凭证 id: aws-oidc uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ secrets.AWS_PIPELINE_ROLE_ARN_ABC }} aws-region: us-east-1 - name: Terraform Apply run: | terraform apply -auto-approve \ -var "aws_access_key_id=${{ steps.aws-oidc.outputs.access-key-id }}" \ -var "aws_secret_access_key=${{ steps.aws-oidc.outputs.secret-access-key }}" \ -var "aws_session_token=${{ steps.aws-oidc.outputs.session-token }}" \ -var "member_account_ids=[\"123456789012\", \"234567890123\"]"
注意事项
- 确保运行环境安装了
jq工具,用于解析AWS CLI的JSON输出 - 批量操作前先测试单个账户,避免误操作
- 处理默认VPC不存在的情况,防止脚本中断
- 流水线角色需在主账户(或拥有跨账户权限的账户)中创建
内容的提问来源于stack exchange,提问作者user24607112
相关产品推荐
相关产品推荐

