如何在 Terraform config 和 Packer 模板之间共享配置?
目前我有一个.tfvars
文件:
aws_region="us-east-1"
aws_access_key="non-sense"
...
和一个打包程序模板:
{
"variables": {
"aws_access_key": "non-sense",
"aws_secret_key": "key",
....
},
他们俩是否有可能使用相同的.env
文件或类似的东西?
请不要将其缩小到仅 AWS 配置 - 假设我需要重用映像的名称。
没有办法直接在这两个系统之间共享正常配置,但在您的特定情况下,这没关系,因为无论如何您都不应该将凭据硬编码到配置文件中。
Packer 和 Terraform(以及 AWS 生态系统中的几乎所有内容(都允许您通过一系列不同的方式提供凭证,如果设置了多个,则它们之间具有优先权。
适用于 Go 的 AWS 开发工具包需要凭证(访问密钥和密钥( 访问密钥(对 AWS 的请求进行签名。您可以指定您的凭据 在几个不同的位置,具体取决于您的特定用例。 有关获取凭据的信息,请参阅设置。
在未提供任何服务客户端的情况下初始化新服务客户端时 凭据参数,SDK 使用默认凭据提供程序 链以查找 AWS 凭证。SDK 使用 返回凭据且没有错误的链。默认提供程序 链按以下顺序查找凭据:
环境变量。
共享凭据文件。
如果您的应用程序在 Amazon EC2 实例上运行,则 IAM 角色 亚马逊 EC2.
如果您的应用程序使用 ECS 任务定义或运行任务 API 操作,任务的 IAM 角色。
SDK 会自动检测并使用内置提供程序,无需 需要手动配置。例如,如果您将 IAM 角色用于 Amazon EC2 实例,您的应用程序会自动使用 实例的凭据。您无需手动配置 应用程序中的凭据。
作为最佳实践,AWS 建议您在 以下顺序:
如果您的应用程序使用 ECS 任务,请使用 IAM 角色执行任务 定义或运行任务 API 操作。
对 Amazon EC2 使用 IAM 角色(如果您的应用程序在 Amazon EC2 实例(。
IAM 角色为实例上的应用程序提供临时安全性 用于进行 AWS 调用的凭证。IAM 角色提供了一种简单的方法来 在多个 Amazon EC2 实例上分发和管理凭证。
使用共享凭据文件。
此凭证文件与其他开发工具包和 AWS 使用的凭证文件相同 如果您已经在使用共享凭证文件,则还可以 将其用于此目的。
使用环境变量。
如果您正在进行开发,设置环境变量很有用 在 Amazon EC2 实例以外的计算机上工作。
这允许您在本地开发时使用您的个人凭证(通过设置环境变量AWS_ACCESS_KEY_ID
和AWS_SECRET_ACCESS_KEY
或使用~/.aws/credentials
文件(,然后在 AWS 中运行 Packer 或 Terraform 时自动使用 IAM 角色,以便 STS 可以为您管理轮换的短期凭证。
如果要在Packer和Terraform之间共享映像的ID,则应使用Terraform数据源,以便Terraform可以自动选择使用Packer生成的最新映像。
例如,您可能有这样的东西:
帕克.json
{
"builders": [
{
"ami_name": "ubuntu/20.04/base/{{isotime | clean_resource_name}}",
"source_ami_filter": {
"filters": {
"name": "ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*",
"root-device-type": "ebs",
"virtualization-type": "hvm"
},
"most_recent": true,
"owners": [
"099720109477"
]
}
}
]
}
instance.tf
data "aws_ami" "ubuntu" {
most_recent = true
filter {
name = "name"
values = ["ubuntu/20.04/base/*"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
owners = ["self"]
}
resource "aws_instance" "web" {
ami = data.aws_ami.ubuntu.id
instance_type = "t2.micro"
tags = {
Name = "HelloWorld"
}
}
如果您希望避免在上面的示例 Packer 和 Terraform 代码之间复制字符串ubuntu/20.04/base/
,那么不幸的是,除了对 Packer 和 Terraform 使用变量并让一些更高级别的系统(例如 shell 脚本(将相同的变量传递给每个之外,实际上没有其他选择。这感觉有点尴尬,但看起来像这样:
帕克.json
{
"variables": {
"ami_base_name": ""
},
"builders": [
{
"ami_name": "{{user `ami_base_name`}}/{{isotime | clean_resource_name}}",
"source_ami_filter": {
"filters": {
"name": "ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*",
"root-device-type": "ebs",
"virtualization-type": "hvm"
},
"most_recent": true,
"owners": [
"099720109477"
]
}
}
]
}
instance.tf
variable "ami_base_name" {}
data "aws_ami" "ubuntu" {
most_recent = true
filter {
name = "name"
values = ["${var.ami_base_name}/*"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
owners = ["self"]
}
resource "aws_instance" "web" {
ami = data.aws_ami.ubuntu.id
instance_type = "t2.micro"
tags = {
Name = "HelloWorld"
}
}
如果你使用带有HCL而不是JSON的Packer,你会发现它有一些类似的方法,例如var文件。
Packer(HCL(和TF允许我们定义变量如下:
variable "template_name" {
type = string
default = "my-demo-packer"
}
variable "subnet_id" {
type = string
}
然后使用纯文本文件加载值:my-vars.pkrvars.hcl
vsmy-vars.tfvars
:
template_name = "my-template-001"
subnet_id = "subnet-1234567"
如果您希望 Packer/TF 自动加载此文件,只需添加一个步骤即可将其重命名为my-vars.auto.pkrvars.hcl
并在脚本中my-vars.auto.tfvars
。