如何在Terraform config和Packer模板之间共享配置?

问题描述 投票:0回答:1

如何在Terraform配置和Packer模板之间共享配置?

目前我有一个 .tfvars 文件。

aws_region="us-east-1"
aws_access_key="non-sense"
...

和一个Packer模板。

{
  "variables": {
    "aws_access_key": "non-sense",
    "aws_secret_key": "key",
....
  },

有没有可能让这两个模板都使用相同的 .env 文件或类似的东西?

请不要把范围缩小到只有AWS配置--比方说我需要重用镜像的名字。

amazon-web-services terraform packer iaas
1个回答
3
投票

这2个系统之间没有办法直接共享正常的配置,但在你的具体情况下,这没关系,因为无论如何你不应该把你的凭证硬编码到配置文件中。

Packer和Terraform(以及AWS生态系统中的几乎所有东西)都会允许你将 通过不同的方式连锁供应凭证 之间有一个优先级,如果设置了多个。

AWS SDK for Go 需要凭证(访问密钥和秘密访问密钥)来签署对 AWS 的请求。您可以根据您的特定用例,在多个不同位置指定您的凭证。 有关获取凭证的信息,请参阅设置。

当您在不提供任何凭证参数的情况下初始化新服务客户端时,SDK 会使用默认的凭证提供者链来查找 AWS 凭证。SDK 使用链中第一个无误返回凭证的提供者。默认的提供者链按以下顺序查找凭证。

  1. 环境变量

  2. 共享凭证文件。

  3. 如果您的应用程序运行在 Amazon EC2 实例上,则应查找 Amazon EC2 的 IAM 角色。

  4. 如果您的应用程序使用 ECS 任务定义或 RunTask API 操作,则为任务的 IAM 角色。

SDK会自动检测并使用内置的提供者,而不需要手动配置。例如,如果您对 Amazon EC2 实例使用 IAM 角色,您的应用程序将自动使用实例的凭证。您不需要在应用程序中手动配置凭证。

作为最佳实践,AWS 建议您按以下顺序指定凭证。

  1. 如果您的应用程序使用ECS任务定义或RunTask API操作,请为任务使用IAM角色。

  2. 为Amazon EC2使用IAM角色(如果您的应用程序在Amazon EC2实例上运行)。

    IAM 角色为实例上的应用程序提供临时的安全凭证以进行 AWS 调用。IAM 角色提供了在多个 Amazon EC2 实例上分发和管理凭证的简单方法。

  3. 使用共享凭证文件。

    该凭证文件与其他 SDK 和 AWS CLI 使用的文件相同。如果您已经在使用共享凭证文件,您也可以将其用于此目的。

  4. 使用环境变量。

    如果你在Amazon EC2实例以外的机器上进行开发工作,设置环境变量很有用。

这允许您在本地开发时使用您的个人凭证(可以通过设置环境变量 AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY 或使用 ~/.aws/credentials 文件),然后当你在AWS中运行Packer或Terraform时自动使用IAM角色,这样STS就可以为你管理轮流的短期凭证。


如果你想在Packer和Terraform之间共享镜像的ID,那么你应该使用 Terraform数据源 这样Terraform就可以自动选择你用Packer制作的最新图像。

举个例子,你可能有这样的东西。

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"
        ]
      }
    }
  ]
}

例子.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"
  }
}

如果你希望避免重复使用字符串 ubuntu/20.04/base/ 在上述Packer和Terraform代码之间,不幸的是,除了使用变量之外,并没有其他选择。包装机地形 并让一些更高级别的系统(比如shell脚本)将相同的变量传入每个变量。这感觉有点笨拙,但看起来会像这样。

packer.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"
  }
}

1
投票

如果你是用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 vs my-vars.tfvars:

template_name    = "my-template-001"
subnet_id        = "subnet-1234567"

如果您想让PackerTF自动加载这个文件,只需添加一个步骤,将其重命名为 my-vars.auto.pkrvars.hclmy-vars.auto.tfvars 在您的脚本内。

© www.soinside.com 2019 - 2024. All rights reserved.