terraform 在本地配置 cloudflared 隧道

terraform provisioning locally cloudflared tunnel

我尝试在没有任何云实例的情况下使用 terraform - 仅适用于使用构造的本地安装 cloudflared 隧道:

    resource "null_resource" "tunell_install" {
  triggers = {
    always_run = timestamp()
  }
  provisioner "local-exec" {
    command = "/home/uzer/script/tunnel.sh"
  }
}

而是这样的:

provider "google" {
  project    = var.gcp_project_id
}

但在 运行

之后
$ terraform apply -auto-approve

已成功创建 /etc/cloudflared/cert.json,内容为:

{
    "AccountTag"   : "${account}",
    "TunnelID"     : "${tunnel_id}",
    "TunnelName"   : "${tunnel_name}",
    "TunnelSecret" : "${secret}"
}

但我不理解这里必须是值而不是变量? instance.tf 中的 metadata_startup_script 似乎仅适用于 Google 实例。如何更改它以使用 terraform 在本地安装 CF 隧道和 运行 隧道?也许还需要使用 templatefile 但在其他 .tf 文件中?当前代码块metadata_startup_script:

  // This is where we configure the server (aka instance). Variables like web_zone take a terraform variable and provide it to the server so that it can use them as a local variable
  metadata_startup_script = templatefile("./server.tpl",
    {
      web_zone    = var.cloudflare_zone,
      account     = var.cloudflare_account_id,
      tunnel_id   = cloudflare_argo_tunnel.auto_tunnel.id,
      tunnel_name = cloudflare_argo_tunnel.auto_tunnel.name,
      secret      = random_id.tunnel_secret.b64_std
    })

server.tpl 文件的内容:

# Script to install Cloudflare Tunnel 
# cloudflared configuration
cd
# The package for this OS is retrieved 
wget https://bin.equinox.io/c/VdrWdbjqyF/cloudflared-stable-linux-amd64.deb
sudo dpkg -i cloudflared-stable-linux-amd64.deb
# A local user directory is first created before we can install the tunnel as a system service 
mkdir ~/.cloudflared
touch ~/.cloudflared/cert.json
touch ~/.cloudflared/config.yml
# Another herefile is used to dynamically populate the JSON credentials file 
cat > ~/.cloudflared/cert.json << "EOF"
{
    "AccountTag"   : "${account}",
    "TunnelID"     : "${tunnel_id}",
    "TunnelName"   : "${tunnel_name}",
    "TunnelSecret" : "${secret}"
}
EOF
# Same concept with the Ingress Rules the tunnel will use 
cat > ~/.cloudflared/config.yml << "EOF"
tunnel: ${tunnel_id}
credentials-file: /etc/cloudflared/cert.json
logfile: /var/log/cloudflared.log
loglevel: info

ingress:
  - hostname: ssh.${web_zone}
    service: ssh://localhost:22
  - hostname: "*"
    service: hello-world
EOF
# Now we install the tunnel as a systemd service 
sudo cloudflared service install
# The credentials file does not get copied over so we'll do that manually 
sudo cp -via ~/.cloudflared/cert.json /etc/cloudflared/
# Now we can start the tunnel 
sudo service cloudflared start

在argo.tf中存在这个代码:

data "template_file" "init" {
  template = file("server.tpl")
  vars = {
    web_zone    = var.cloudflare_zone,
    account     = var.cloudflare_account_id,
    tunnel_id   = cloudflare_argo_tunnel.auto_tunnel.id,
    tunnel_name = cloudflare_argo_tunnel.auto_tunnel.name,
    secret      = random_id.tunnel_secret.b64_std
  }
}

如果您询问如何在本地创建文件并填充值,这里有一个示例:

resource "local_file" "cloudflare_tunnel_script" {
  content = templatefile("${path.module}/server.tpl",
    {
      web_zone    = "webzone"
      account     = "account"
      tunnel_id   = "id"
      tunnel_name = "name"
      secret      = "secret"
    }
  )
  filename = "${path.module}/server.sh"
}

为此,您必须为上面列出的所有模板变量分配实际值。据我所知,已经有关于如何为这些值使用变量的示例。换句话说,您可以使用标准变量而不是对模板变量的值进行硬编码:

resource "local_file" "cloudflare_tunnel_script" {
  content = templatefile("${path.module}/server.tpl",
    {
      web_zone    = var.cloudflare_zone
      account     = var.cloudflare_account_id
      tunnel_id   = cloudflare_argo_tunnel.auto_tunnel.id
      tunnel_name = cloudflare_argo_tunnel.auto_tunnel.name
      secret      = random_id.tunnel_secret.b64_std
    }
  )
  filename = "${path.module}/server.sh"
}

此代码将填充所有值并在与 运行 Terraform 代码所在的同一目录中创建一个 server.sh 脚本。

您可以用您想要的 null_resource 补充此代码:

resource "null_resource" "tunnel_install" {
  depends_on = [
    local_file.cloudflare_tunnel_script,
  ]

  triggers = {
    always_run = timestamp()
  }

  provisioner "local-exec" {
    command = "${path.module}/server.sh"
  }
}