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

如何通过Terraform在EC2上安全配置AWS CLI(GitLab流水线场景)

解决方案:通过Terraform安全配置EC2上的AWS CLI

核心结论

绝对不建议手动传递AWS密钥,AWS官方最佳实践是使用IAM实例角色——EC2启动后会自动获取临时凭证,无需aws configure或硬编码密钥,完全规避密钥泄露风险。如果有特殊场景需要使用固定密钥,可通过SSM Parameter Store安全存储并读取,但仍优先推荐IAM角色方案。


方案1:IAM实例角色(推荐)

通过Terraform创建IAM角色并关联到EC2实例,EC2会自动从元数据服务获取临时AWS凭证,AWS CLI默认会使用这些凭证,无需任何手动配置。

1. Terraform配置IAM角色与权限

# 创建允许EC2扮演的IAM角色
resource "aws_iam_role" "s3_scanner_role" {
  name = "s3-scanner-ec2-role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Principal = {
          Service = "ec2.amazonaws.com"
        }
      }
    ]
  })
}

# 附加S3操作所需的最小权限(按需缩小资源范围)
resource "aws_iam_role_policy" "s3_scanner_policy" {
  name = "s3-scanner-policy"
  role = aws_iam_role.s3_scanner_role.id

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect = "Allow"
        Action = [
          "s3:ListAllMyBuckets",
          "s3:ListBucket",
          "s3:GetObject",
          "s3:PutObject"
        ]
        Resource = [
          "arn:aws:s3:::your-script-bucket/*",  # 脚本所在桶
          "arn:aws:s3:::your-result-bucket/*",  # 结果存储桶
          "arn:aws:s3:::*"                      # 扫描所有桶的权限(可按需限制)
        ]
      }
    ]
  })
}

# 创建实例配置文件(关联IAM角色到EC2)
resource "aws_iam_instance_profile" "s3_scanner_profile" {
  name = "s3-scanner-instance-profile"
  role = aws_iam_role.s3_scanner_role.name
}

2. Terraform配置EC2实例(自动执行脚本)

通过user_data自动完成脚本下载、执行、结果上传,无需手动操作:

resource "aws_instance" "s3_scanner" {
  ami           = "ami-0c55b159cbfafe1f0" # 替换为你所在区域的Amazon Linux 2 AMI
  instance_type = "t2.micro"
  iam_instance_profile = aws_iam_instance_profile.s3_scanner_profile.name

  user_data = <<-EOF
              #!/bin/bash
              # Amazon Linux 2默认已预装AWS CLI,若用其他系统需自行安装
              # yum install -y aws-cli

              # 从S3复制脚本到本地
              aws s3 cp s3://your-script-bucket/path/to/scan-s3.sh /tmp/scan-s3.sh
              chmod +x /tmp/scan-s3.sh

              # 执行脚本并保存结果到S3
              /tmp/scan-s3.sh > /tmp/s3-scan-result.txt
              aws s3 cp /tmp/s3-scan-result.txt s3://your-result-bucket/results/s3-scan-$(date +%Y%m%d%H%M).txt

              # 执行完成后自动关机,方便Terraform销毁
              shutdown -h now
              EOF

  tags = {
    Name = "s3-scanner-instance"
  }
}

3. GitLab流水线集成

在GitLab CI/CD配置中,按以下流程执行:

  • 初始化Terraform并执行terraform apply启动EC2及相关资源
  • 等待EC2执行完脚本并关机(可通过aws ec2 wait instance-stopped命令等待)
  • 执行terraform destroy销毁所有资源,节约成本

方案2:SSM Parameter Store(特殊场景备用)

如果必须使用固定AWS密钥,可将密钥存储在SSM Parameter Store的加密参数中,通过IAM权限让EC2读取并配置CLI。

1. 预配置SSM参数

在AWS控制台创建两个SecureString类型的参数:

  • /s3-scanner/aws_access_key_id:存储你的AWS Access Key ID
  • /s3-scanner/aws_secret_access_key:存储你的AWS Secret Access Key

2. Terraform配置权限与EC2

给IAM角色添加SSM参数读取权限,并在user_data中配置CLI:

# 新增SSM参数读取权限到IAM角色
resource "aws_iam_role_policy" "ssm_parameter_access" {
  name = "ssm-parameter-access"
  role = aws_iam_role.s3_scanner_role.id

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect = "Allow"
        Action = ["ssm:GetParameter"]
        Resource = [
          "arn:aws:ssm:${var.aws_region}:${var.aws_account_id}:parameter/s3-scanner/*"
        ]
      }
    ]
  })
}

# EC2实例的user_data修改为以下内容
user_data = <<-EOF
            #!/bin/bash
            yum install -y aws-cli

            # 从SSM读取密钥并配置AWS CLI
            export AWS_ACCESS_KEY_ID=$(aws ssm get-parameter --name "/s3-scanner/aws_access_key_id" --with-decryption --query "Parameter.Value" --output text)
            export AWS_SECRET_ACCESS_KEY=$(aws ssm get-parameter --name "/s3-scanner/aws_secret_access_key" --with-decryption --query "Parameter.Value" --output text)
            aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID
            aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY
            aws configure set region ${var.aws_region}

            # 后续脚本下载、执行、结果上传步骤同方案1
            EOF

内容的提问来源于stack exchange,提问作者Krystian junior DevOps

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 06:41:28