Terraform:传递 AWS 系统管理器参数存储变量时,Terraform AWS 提供商凭证无效

Posted

技术标签:

【中文标题】Terraform:传递 AWS 系统管理器参数存储变量时,Terraform AWS 提供商凭证无效【英文标题】:Invalid Terraform AWS provider credentials when passing AWS system manager parameter store variables 【发布时间】:2020-12-26 09:12:47 【问题描述】:

背景:

我正在使用 AWS CodeBuild buildspec.yml 遍历 GitHub 存储库中的目录,以使用 Terraform 应用 IaC。为了访问 Terraform AWS 提供商所需的凭证,我使用 AWS 系统管理器参数存储来检索 buildspec.yml 中的访问密钥和密钥。

问题:

系统管理器参数存储屏蔽了访问和密钥 env 值,因此当 Terraform AWS 提供商继承它们时,提供商会输出凭证无效:

Error: error configuring Terraform AWS Provider: error validating provider credentials: error calling sts:GetCallerIdentity: InvalidClientTokenId: The security token included in the request is invalid.
    status code: 403, request id: xxxx

重现问题:

创建系统管理器参数存储变量(TF_VAR_AWS_ACCESS_KEY_ID=access, TF_AWS_SECRET_ACCESS_KEY=secret)

使用以下命令创建 AWS CodeBuild 项目:

 "source": 
                "type": "NO_SOURCE",

"environment": 
                "type": "LINUX_CONTAINER",
                "image": "aws/codebuild/standard:4.0",
                "computeType": "BUILD_GENERAL1_SMALL"

buildspec.yml 带有以下内容:(修改为创建 .tf 文件而不是从 github 获取)

version: 0.2
env:
  shell: bash
  parameter-store:
    TF_VAR_AWS_ACCESS_KEY_ID: TF_AWS_ACCESS_KEY_ID
    TF_VAR_AWS_SECRET_ACCESS_KEY: TF_AWS_SECRET_ACCESS_KEY
phases:
  install:
    commands:
      - wget https://releases.hashicorp.com/terraform/0.12.28/terraform_0.12.28_linux_amd64.zip -q
      - unzip terraform_0.12.28_linux_amd64.zip && mv terraform /usr/local/bin/
      - printf "provider "aws" \n\taccess_key = var.AWS_ACCESS_KEY_ID\n\tsecret_key = var.AWS_SECRET_ACCESS_KEY\n\tversion    = \"~> 3.2.0\"\n" >> provider.tf
      - printf "variable "AWS_ACCESS_KEY_ID" \nvariable "AWS_SECRET_ACCESS_KEY" " > vars.tf
      - printf "resource \"aws_s3_bucket\" \"test\" \n\tbucket = \"test\"\n\tacl = \"private\"\n" >> s3.tf
      - terraform init
      - terraform plan

尝试:

    通过 terraform -vars 选项传递凭据:
terraform plan -var="AWS_ACCESS_KEY_ID=$TF_VAR_AWS_ACCESS_KEY_ID" -var="AWS_ACCESS_KEY_ID=$TF_VAR_AWS_SECRET_ACCESS_KEY"

但我收到相同的无效凭据错误

    在 buildspec.yml 中导出系统管理器参数存储凭据:
commands:
  - export AWS_ACCESS_KEY_ID=$TF_VAR_AWS_ACCESS_KEY_ID
  - export AWS_SECRET_ACCESS_KEY=$TF_VAR_AWS_SECRET_ACCESS_KEY

这会导致重复的掩码变量和上述相同的错误。 printenv buildspec.yml 中的输出:

AWS_ACCESS_KEY_ID=***
TF_VAR_AWS_ACCESS_KEY_ID=***
AWS_SECRET_ACCESS_KEY=***
TF_VAR_AWS_SECRET_ACCESS_KEY=***

可能的解决途径:

以某种方式成功地将 MASKED 参数存储凭据值传递到 Terraform(首选) 使用不同的方法将敏感凭证传递给 Terraform AWS 提供商,例如AWS 密钥管理器、IAM 角色等。 取消屏蔽参数存储变量以传递到 aws 提供程序(可能首先破坏了使用 aws 系统管理器的目的)

【问题讨论】:

【参考方案1】:

使用不同的方法将敏感凭证传递给 Terraform AWS 提供商,例如AWS 密钥管理器、IAM 角色等。

通常,您无需硬编码 AWS 凭证即可使 terraform 正常工作。相反,CodeBuild IAM 角色 应该足以用于 terraform,如 terraform docs 中所述。

考虑到这一点,我验证以下内容有效,并使用 CodeBuild 项目中的 terraform 创建了请求的存储桶。使用 S3 权限 修改了默认 CB 角色以允许创建存储桶。

version: 0.2
phases:
  install:
    commands:
      - wget https://releases.hashicorp.com/terraform/0.12.28/terraform_0.12.28_linux_amd64.zip -q
      - unzip terraform_0.12.28_linux_amd64.zip && mv terraform /usr/local/bin/
      - printf "resource \"aws_s3_bucket\" \"test\" \n\tbucket = \"test-43242-efdfdfd-4444334\"\n\tacl = \"private\"\n" >> s3.tf
      - terraform init
      - terraform plan
      - terraform apply -auto-approve

【讨论】:

【参考方案2】:

我在 Ubuntu 20.04 上使用 Terraform 时遇到了同样的问题。

我已经使用 aws configure 命令配置了 AWS CLI,并为我在 AWS 上创建的 terraform 用户提供了 IAM 凭证。

但是,当我运行命令时:

terraform plan

我得到错误:

错误:配置 Terraform AWS 提供商时出错:验证提供商凭据时出错:调用 sts:GetCallerIdentity 时出错:InvalidClientTokenId:请求中包含的安全令牌无效。 状态码:403,请求ID:17268b96-6451-4527-8b17-0312f49eec51

这是我修复它的方法

这个问题是由于我的 AWS CLI 使用 aws configure 命令配置错误造成的。我输入了 AWS 访问密钥 ID 我要输入 AWS 秘密访问密钥 并且还输入了 AWS 秘密访问密钥 我要输入AWS 访问密钥 ID

我必须运行以下命令才能使用我在 AWS 上创建的 terraform 用户的 IAM 凭据正确重新配置 AWS CLI:

aws configure

您可以通过运行一个简单的 was cli 命令来确认它没有问题:

aws s3 ls

如果您遇到如下错误,则说明您仍未正确设置:

调用 ListBuckets 操作时发生错误 (InvalidAccessKeyId):我们的记录中不存在您提供的 AWS 访问密钥 ID。

就是这样。

我希望这会有所帮助

【讨论】:

谢谢,我在使用 Terraform 云时遇到了同样的问题,把信任放在了错误的方向!有趣的是,错误消息是status code: 400, request id: ...【参考方案3】:

我遇到了 403 错误。 问题是 - 您应该从示例代码中删除 。

provider "aws"  
   access_key = "YOUR ACCESS KEY" 
   secret_key = "YOUR SECRET KEY"
   region = "eu-west-1"

它应该看起来像,

provider "aws"  
   access_key = "YOUR ACCESS KEY" 
   secret_key = "YOUR SECRET KEY"
   region = "eu-west-1"

【讨论】:

【参考方案4】:

好吧,我的情况很愚蠢,但它可能会有所帮助:

所以在下载 .csv 文件后,我使用 aws configure 复制粘贴密钥。

在密钥的中间有一个“+”。在编辑器中我使用双击复制,但是遇到非字母数字字符时会停止,这意味着只复制了秘密访问密钥的第一部分。

确保您已尽职尽责地复制了完整的密钥。

【讨论】:

以上是关于Terraform:传递 AWS 系统管理器参数存储变量时,Terraform AWS 提供商凭证无效的主要内容,如果未能解决你的问题,请参考以下文章

terraform - 将 vpc_id 参数从不同的 VPC 传递到多个子网

Terraform - 具有编程访问权限的 AWS IAM 用户

如何使用 terraform 将 aws ec2 私有 ips 传递给模板文件

将命令行参数传递给 AWS Fargate 容器

terraform - 从文件中定义 aws api 网关请求参数?

如何将“–kubelet-extra-args”传递给 Terraform aws_eks_node_group 创建的 AWS EKS 节点组?