Terraform 在创建资源后触发模块
Terraform tigger a module after a resouce is created
对 Terraform 很陌生,所以请提供您得到的所有简单建议。
我想设置一个 RKE-Cluster using/getting Digital Ocean 新创建的 Droplet IP 地址。我已经设置了一个 local_file 来在 RKE 模块中创建一个 txt 文件(这是一种非常奇怪的方式,但不确定我还能做什么。)当我尝试 terraform plan 它时,我得到
on modules/rke/rke.tf line 14, in data "template_file" "rkeip":
│ 14: template = file("${path.module}/rkeip.txt")
│ ├────────────────
│ │ path.module is "modules/rke"
│
│ Invalid value for "path" parameter: no file exists at modules/rke/rkeip.txt; this function works only with files
│ that are distributed as part of the configuration source code, so if this file will be created by a resource in
│ this configuration you must instead obtain this result from an attribute of that resource.
这是我的 Droplet 文件的样子
terraform {
required_providers {
digitalocean = {
source = "digitalocean/digitalocean"
version = "~> 2.0"
}
}
}
variable "do_token" {}
variable "ssh_key_name" {}
provider "digitalocean" {
token = var.do_token
}
data "digitalocean_ssh_key" "default" {
name = "${var.ssh_key_name}"
}
#this installs Docker
data "template_file" "cloud-yaml" {
template = file("${path.module}/modules/cloud.yaml")
}
resource "digitalocean_droplet" "terra" {
image = "ubuntu-20-04-x64"
name = "terra"
region = "sfo3"
size = "s-1vcpu-1gb"
ssh_keys = ["${data.digitalocean_ssh_key.default.fingerprint}"]
user_data = data.template_file.cloud-yaml.rendered
}
resource "local_file" "rkeip" {
content = "${digitalocean_droplet.terra.ipv4_address}"
filename = "${path.module}/modules/rke/rkeip.txt"
}
module "RKE" {
source = "./modules/rke/"
}
和我的 RKE 模块
terraform {
required_providers {
rke = {
source = "rancher/rke"
version = "1.2.4"
}
}
}
data "template_file" "rkeip" {
template = file("${path.module}/rkeip.txt")
}
provider "rke" {
log_file = "rke_debug.log"
}
resource "rke_cluster" "test" {
nodes {
address = data.template_file.rkeip.rendered
user = "root"
role = ["controlplane", "etcd", "worker"]
ssh_key = file("~/.ssh/id_rsa")
}
}
我尝试在 rke.tf 和 droplet.tf 中使用 depends_on,但仍然出现同样的错误。
您的 RKE 模块与路径中的“rke”目录的大小写不同。您认为这可能与此有关吗?
resource "local_file" "rkeip" {
content = "${digitalocean_droplet.terra.ipv4_address}"
filename = "${path.module}/modules/rke/rkeip.txt"
}
module "RKE" {
source = "./modules/rke/"
}
我会更进一步说,如果您所做的只是传递子模块需要的值,请将其作为变量传递。创建静态文件来传递信息是一种 IAC 反模式 IMO。
请注意,“depends_on”是作为最后的手段使用的,并且应该包括说明为什么需要这种变通办法的符号。
好吧,看来 Terraform 的 rke 不能通过一次性的液滴来完成,所以我决定使用 Provisioners 来处理所有的小步骤,所以对于处于类似位置的人来说,这是我补充的droplet.tf.
中的代码
resource "null_resource" "rke" {
connection {
host = "${digitalocean_droplet.terra.ipv4_address}"
type = "ssh"
user = "root"
private_key = file("${path.module}/YOURDOKEY")
agent = false
}
provisioner "file" {
source = "${path.module}/keys.sh"
destination = "/root/keys.sh"
}
provisioner "remote-exec" {
inline = [
"chmod +x /root/keys.sh",
"./keys.sh",
"rm keys.sh",
"wget https://github.com/rancher/rke/releases/download/v1.3.2/rke_linux-amd64",
"mv rke_linux-amd64 rke",
"chmod +x rke",
"printf '%s\n' 'nodes:' ' - address:' ' user: root' ' docker_socket: /var/run/docker.sock' ' role:' ' - controlplane' ' - etcd' ' - worker' ' ssh_key_path: ~/.ssh/id_rsa' >cluster.yml",
"myip=$(curl ifconfig.co)",
"sed -i \"s/address:/address: $myip/\" cluster.yml",
]
}
}
不幸的是,如果您在 remote-exec 中尝试 ./rke up,它会抛出一个错误,因此您必须 运行 它在 droplet 中。
我还制作了 keys.sh 来绕过内联错误,因为它不喜欢这些命令。如果您成功地放置了这些命令而没有任何错误,请随时发表评论。
#!/bin/bash
# keys.sh
# create ssh keys without direct input
ssh-keygen -t rsa -b 4096 -N '' <<<$'\n'
# so the droplet can ssh itself
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
sed -i '/AllowTcpForwarding/d' /etc/ssh/sshd_config
echo "AllowTcpForwarding yes" >> /etc/ssh/sshd_config
# not needed but I wanted to see the output
grep AllowTcpForwarding /etc/ssh/sshd_config
这是为了修复 rke 中的 docker 个错误。
对 Terraform 很陌生,所以请提供您得到的所有简单建议。
我想设置一个 RKE-Cluster using/getting Digital Ocean 新创建的 Droplet IP 地址。我已经设置了一个 local_file 来在 RKE 模块中创建一个 txt 文件(这是一种非常奇怪的方式,但不确定我还能做什么。)当我尝试 terraform plan 它时,我得到
on modules/rke/rke.tf line 14, in data "template_file" "rkeip":
│ 14: template = file("${path.module}/rkeip.txt")
│ ├────────────────
│ │ path.module is "modules/rke"
│
│ Invalid value for "path" parameter: no file exists at modules/rke/rkeip.txt; this function works only with files
│ that are distributed as part of the configuration source code, so if this file will be created by a resource in
│ this configuration you must instead obtain this result from an attribute of that resource.
这是我的 Droplet 文件的样子
terraform {
required_providers {
digitalocean = {
source = "digitalocean/digitalocean"
version = "~> 2.0"
}
}
}
variable "do_token" {}
variable "ssh_key_name" {}
provider "digitalocean" {
token = var.do_token
}
data "digitalocean_ssh_key" "default" {
name = "${var.ssh_key_name}"
}
#this installs Docker
data "template_file" "cloud-yaml" {
template = file("${path.module}/modules/cloud.yaml")
}
resource "digitalocean_droplet" "terra" {
image = "ubuntu-20-04-x64"
name = "terra"
region = "sfo3"
size = "s-1vcpu-1gb"
ssh_keys = ["${data.digitalocean_ssh_key.default.fingerprint}"]
user_data = data.template_file.cloud-yaml.rendered
}
resource "local_file" "rkeip" {
content = "${digitalocean_droplet.terra.ipv4_address}"
filename = "${path.module}/modules/rke/rkeip.txt"
}
module "RKE" {
source = "./modules/rke/"
}
和我的 RKE 模块
terraform {
required_providers {
rke = {
source = "rancher/rke"
version = "1.2.4"
}
}
}
data "template_file" "rkeip" {
template = file("${path.module}/rkeip.txt")
}
provider "rke" {
log_file = "rke_debug.log"
}
resource "rke_cluster" "test" {
nodes {
address = data.template_file.rkeip.rendered
user = "root"
role = ["controlplane", "etcd", "worker"]
ssh_key = file("~/.ssh/id_rsa")
}
}
我尝试在 rke.tf 和 droplet.tf 中使用 depends_on,但仍然出现同样的错误。
您的 RKE 模块与路径中的“rke”目录的大小写不同。您认为这可能与此有关吗?
resource "local_file" "rkeip" {
content = "${digitalocean_droplet.terra.ipv4_address}"
filename = "${path.module}/modules/rke/rkeip.txt"
}
module "RKE" {
source = "./modules/rke/"
}
我会更进一步说,如果您所做的只是传递子模块需要的值,请将其作为变量传递。创建静态文件来传递信息是一种 IAC 反模式 IMO。
请注意,“depends_on”是作为最后的手段使用的,并且应该包括说明为什么需要这种变通办法的符号。
好吧,看来 Terraform 的 rke 不能通过一次性的液滴来完成,所以我决定使用 Provisioners 来处理所有的小步骤,所以对于处于类似位置的人来说,这是我补充的droplet.tf.
中的代码resource "null_resource" "rke" {
connection {
host = "${digitalocean_droplet.terra.ipv4_address}"
type = "ssh"
user = "root"
private_key = file("${path.module}/YOURDOKEY")
agent = false
}
provisioner "file" {
source = "${path.module}/keys.sh"
destination = "/root/keys.sh"
}
provisioner "remote-exec" {
inline = [
"chmod +x /root/keys.sh",
"./keys.sh",
"rm keys.sh",
"wget https://github.com/rancher/rke/releases/download/v1.3.2/rke_linux-amd64",
"mv rke_linux-amd64 rke",
"chmod +x rke",
"printf '%s\n' 'nodes:' ' - address:' ' user: root' ' docker_socket: /var/run/docker.sock' ' role:' ' - controlplane' ' - etcd' ' - worker' ' ssh_key_path: ~/.ssh/id_rsa' >cluster.yml",
"myip=$(curl ifconfig.co)",
"sed -i \"s/address:/address: $myip/\" cluster.yml",
]
}
}
不幸的是,如果您在 remote-exec 中尝试 ./rke up,它会抛出一个错误,因此您必须 运行 它在 droplet 中。
我还制作了 keys.sh 来绕过内联错误,因为它不喜欢这些命令。如果您成功地放置了这些命令而没有任何错误,请随时发表评论。
#!/bin/bash
# keys.sh
# create ssh keys without direct input
ssh-keygen -t rsa -b 4096 -N '' <<<$'\n'
# so the droplet can ssh itself
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
sed -i '/AllowTcpForwarding/d' /etc/ssh/sshd_config
echo "AllowTcpForwarding yes" >> /etc/ssh/sshd_config
# not needed but I wanted to see the output
grep AllowTcpForwarding /etc/ssh/sshd_config
这是为了修复 rke 中的 docker 个错误。