如何通过Terraform和cloud-init安全访问AWS Secrets Manager密钥
实现方案
你不需要手动生成TTL10分钟的临时凭证,EC2实例关联IAM实例profile后,会自动获取EC2服务颁发的临时凭证,默认有效期6小时,完全覆盖cloud-init的执行窗口期,也可以通过IAM角色的最大会话时长配置调整到你需要的10分钟。
步骤1:补全IAM角色配置
首先给aws_iam_role添加信任策略,允许EC2服务扮演该角色,再附加仅允许访问指定Secret的权限策略:
resource "aws_iam_role" "my_instance_iam_role" { name = "my_instance_iam_role" path = "/development/" # 信任策略:允许EC2服务扮演该角色 assume_role_policy = jsonencode({ Version = "2012-10-17" Statement = [ { Action = "sts:AssumeRole" Effect = "Allow" Principal = { Service = "ec2.amazonaws.com" } } ] }) # 可选:设置最大会话时长为10分钟,单位秒 max_session_duration = 600 tags = { Environment = "dev" } } # 附加权限策略:仅允许读取指定的Secret resource "aws_iam_role_policy" "secret_access_policy" { name = "secret-access-policy" role = aws_iam_role.my_instance_iam_role.id policy = jsonencode({ Version = "2012-10-17" Statement = [ { Action = "secretsmanager:GetSecretValue" Effect = "Allow" Resource = aws_secretsmanager_secret.my_password_secret.arn } ] }) }
步骤2:修改cloud-init脚本拉取密码
Amazon Linux 2默认预装AWS CLI,直接通过CLI调用Secrets Manager接口获取密码即可,无需手动调用底层API:
data "cloudinit_config" "my_instance_1" { gzip = true base64_encode = true part { content_type = "text/x-shellscript" filename = "setup-script.sh" content = <<EOF #!/usr/bin/env bash # 从Secrets Manager拉取密码,仅保留密码值 my_password=$(aws secretsmanager get-secret-value --secret-id /development/my_password --query SecretString --output text) server_password=$my_password /opt/srv/bin/install.sh # 可选:执行完安装后清除内存中的密码变量,避免泄露 unset my_password server_password EOF } }
额外安全优化建议
- 如果你的实例AMI没有预装AWS CLI,可以在脚本开头先执行
yum install -y awscli安装 - 安装脚本执行完成后,建议清空bash历史记录,避免密码被留存:
history -c && rm -f ~/.bash_history - 不需要长期保留Secret访问权限的话,可以在cloud-init执行完成后,通过Terraform移除实例的IAM实例profile关联,或者删除对应的权限策略
内容的提问来源于stack exchange,提问作者adamretter
相关产品推荐
相关产品推荐

