問題
以下のように設定しているssl certificateのドメインを変更しようとすると
resource "google_compute_managed_ssl_certificate" "lb_certs" {
provider = google-beta
name = replace(each.value, ".", "-")
lifecycle { create_before_destroy = true }
for_each = local.workspace["certificates"]
managed {
domains = ["${each.value}."]
}
}
resource "google_compute_target_https_proxy" "base_https_proxy" {
name = "base-https"
url_map = google_compute_url_map.base.self_link
ssl_certificates = values(google_compute_managed_ssl_certificate.lb_certs).*.self_link
ssl_policy = google_compute_ssl_policy.ssl-policy-restricted.self_link
depends_on = [google_compute_managed_ssl_certificate.lb_certs]
}
すでにhttp proxyなどで参照されている場合、以下のresourceInUseByAnotherResource
が出てapplyに失敗する
Error: Error when reading or editing ManagedSslCertificate: googleapi: Error 400: The ssl_certificate resource 'projects/xxxx/global/sslCertificates/xxxxxx' is already being used by 'projects/xxxx/global/targetHttpsProxies/xxxx', resourceInUseByAnotherResource
原因
terraform applyで force replacement (xxxx must be replaced)の場合は先に削除が行われてから、新しいリソースが作成されるので、google_compute_target_https_proxy
のように 依存されている場合には失敗してしまう。
解決方法
こちらに乗っているものを使うと解決する。
1 create_before_destroy = true
を設定する
lifecycle {
create_before_destroy = true
}
これにより、削除よりも前に作成を実行するように順番を変更できる
ただしこれだけだと、nameが被ってError: Error creating ManagedSslCertificate: googleapi: Error 409: The resource 'projects/xxxxx/global/sslCertificates/xxxx' already exists, alreadyExists
のようなalreadyExistsのエラーになる
そのためdomainsに対応して変わる名前を作るようにする
2. domainsのリストに対応するnameのrandom idを生成する
locals {
managed_domains = list("test.example.com")
}
resource "random_id" "certificate" {
byte_length = 4
prefix = "issue6147-cert-"
keepers = {
domains = join(",", local.managed_domains)
}
}
resource "google_compute_managed_ssl_certificate" "cert" {
provider = google-beta
name = random_id.certificate.hex
lifecycle {
create_before_destroy = true
}
managed {
domains = local.managed_domains
}
}
これでdomainsが変更されたときだけrandom_idが変わるので、名前を変えてリソースを再作成することによりもともと出ていたエラーを回避することができる
最後に
すでに公式ドキュメントにこの例が載せられていた