在使用 Terraform 创作了各种资源之后,将它们传递到 EC2 实例的方法如下:

最近通常情况下,我们会使用Terraform创建AWS资源,然后再使用Ansible进行EC2实例的配置。但是经常会出现这样的情况,我们希望在EC2实例内部使用由Terraform创建的AWS资源信息。

比如以下的例子。

    • RDS 接続情報

 

    SES クレデンシャル

如果有一定的命名规则或固定的名称,我认为可以直接在Terraform的tf文件和Ansible的playbook中进行编写。但如果是随机生成的,

    1. 使用Terraform创建资源

 

    通过目测将其添加到Ansible库存中

需要像这样做,显得有点不够高雅。

解決這個問題的方法有很多,但以下是其中一種選擇…

土地造成的清单

    https://github.com/adammck/terraform-inventory

使用 Terraform tfstate 文件作为 Ansible 动态清单。然而,由于可能不支持远程后端,所以似乎无法使用。

如果不使用Terraform的远程后端,可能可以使用吗?

本地执行供应者。

    https://www.terraform.io/docs/provisioners/local-exec.html

使用 Terraform 的 local-exec 推送程序,将创建的资源信息写入本地文件中。

resource "aws_iam_access_key" "smtp" {
  user = "${aws_iam_user.smtp.name}"
  provisioner "local-exec" {
    command = "echo '${aws_iam_access_key.smtp.id}:${aws_iam_access_key.smtp.ses_smtp_password}' > smtp_credential.txt"
  }
}

我从来没有使用过这个,但我觉得这个只会在创建资源时才会执行,所以如果要与其他人共享代码的话是不行的。

或者将使用local-exec provisioner创建的文件包含在存储库中?因为我想要处理SES凭证之类的东西,所以这是困难的。

远程执行配置构建者

    https://www.terraform.io/docs/provisioners/remote-exec.html

使用 Terraform 的 remote-exec 配置,在创建的 EC2 实例上写入文件。

resource "aws_instance" "web" {
  # ...

  provisioner "remote-exec" {
    inline = [
      "echo '${aws_iam_access_key.smtp.id}:${aws_iam_access_key.smtp.ses_smtp_password}' > smtp_credential.txt",
    ]
  }
}

我没用过这个,但除非不使用Ansible只用Terraform单独完成,否则同时使用会很麻烦。

将Terraform的资源保存在某处。

将 Terraform 资源保存到一个可后续引用的位置。

比如说S3之类的。

resource "aws_s3_bucket_object" "secret" {
  bucket = "oreore-bucket"
  key    = "secret"
  content = <<EOS
SMTP_USERNAME=${aws_iam_access_key.smtp.id}
SMTP_PASSWORD=${aws_iam_access_key.smtp.ses_smtp_password}
EOS
}

可能在SSM的参数存储中也可以。

resource "aws_ssm_parameter" "secret" {
  name  = "/oreore/smtp/username"
  type  = "SecureString"
  value = "${aws_iam_access_key.smtp.id}"
}

resource "aws_ssm_parameter" "secret" {
  name  = "/oreore/smtp/password"
  type  = "SecureString"
  value = "${aws_iam_access_key.smtp.ses_smtp_password}"
}

将其放入EC2实例的用户数据,并写入/etc/environment文件中。

将数据放入EC2实例的用户数据中,使用cloud-init将其写入/etc/environment等目录中。

resource "aws_instance" "redmine" {
  # ...

  user_data = <<EOS
#cloud-config
timezone: "Asia/Tokyo"
write_files:
  - path: "/etc/environment"
    content: |
      SMTP_USERNAME=${aws_iam_access_key.smtp.id}
      SMTP_PASSWORD=${aws_iam_access_key.smtp.ses_smtp_password}
EOS
}

最后

你需要考虑如何使用存储在 S3 或 SSM 参数存储中的值,但如果是从 EC2 用户数据的 /etc/environment 中获取,你可以很容易地通过 Ansible 进行引用。

- name: generate sasl_passwd
  copy:
    dest: /etc/postfix/sasl_passwd
    mode: 0600
    content: |
      email-smtp.us-west-2.amazonaws.com:587 {{ansible_env.SMTP_USERNAME}}:{{ansible_env.SMTP_PASSWORD}}
  notify:
    - postmap sasl_passwd
    - postfix restart

然而,使用Terraform时,如果EC2用户数据发生更改,则会尝试重新创建实例,并且仅在实例启动时才能使用cloud-init进行写入。因此,如果存在从S3或SSM Parameter store获取值的Dynamic Inventory,它可能更具操作性。

广告
将在 10 秒后关闭
bannerAds