在使用 Terraform 创作了各种资源之后,将它们传递到 EC2 实例的方法如下:
最近通常情况下,我们会使用Terraform创建AWS资源,然后再使用Ansible进行EC2实例的配置。但是经常会出现这样的情况,我们希望在EC2实例内部使用由Terraform创建的AWS资源信息。
比如以下的例子。
-
- RDS 接続情報
- SES クレデンシャル
如果有一定的命名规则或固定的名称,我认为可以直接在Terraform的tf文件和Ansible的playbook中进行编写。但如果是随机生成的,
-
- 使用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,它可能更具操作性。