You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 09:10:55