【代码分享】使用 terraform, 在 Let's Encrypt 上申请托管在 cloudflare 上的域名对应的证书

发布时间 2023-07-14 17:07:49作者: ahfuzhang

作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢!


序列图

运行的流程可以抽象为上图。

直接贴代码:

  • letsencrypt.tf
terraform {
  required_providers {
    acme = {
      source  = "vancluever/acme"
      version = "~> 2.0"
    }
  }
}

provider "acme" {
  server_url = "https://acme-staging-v02.api.letsencrypt.org/directory"
}

resource "tls_private_key" "private_key" {
  algorithm = "RSA"
}

resource "acme_registration" "reg" {
  account_key_pem = tls_private_key.private_key.private_key_pem
  email_address   = "nobody@ahfu-zhang.com"
}

resource "acme_certificate" "certificate" {
  account_key_pem = acme_registration.reg.account_key_pem
  common_name     = "ahfu-zhang.com"
  #subject_alternative_names = ["www2.ahfu-zhang.com"]

  dns_challenge {
    provider = "cloudflare"
    config = {
      CLOUDFLARE_DNS_API_TOKEN = "在 cloudflare 站点上申请 token"
      #CF_ZONE_API_TOKEN        = "xxxxx"
      # 上面一行一定不要加,加了就会出现错误: cloudflare: failed to find zone ahfu-zhang.com: ListZonesContext command failed
      CLOUDFLARE_TTL = "150" #cloudflare: invalid TTL, TTL (60) must be greater than 120
    }
  }
}

output "certificate_pem" {
  description = "The certificate in PEM format."
  value       = acme_certificate.certificate.certificate_pem
}

output "fullchain_pem" {
  description = "The certificate concatenated with the intermediate certificate of the issuer."
  value = join("", [
    acme_certificate.certificate.certificate_pem,
    acme_certificate.certificate.issuer_pem
  ])
}

output "issuer_pem" {
  description = "The intermediate certificate of the issuer."
  value       = acme_certificate.certificate.issuer_pem
}

output "private_key_pem" {
  description = "The certificate's private key, in PEM format."
  #value       = tls_private_key.certificate.private_key_pem
  value     = tls_private_key.private_key.private_key_pem
  sensitive = true
}

执行命令来运行:

terraform init
terraform validate && terraform plan
terraform apple -auto-approve