terraform-provider-aws
terraform-provider-aws copied to clipboard
[Bug]: Re-importing certificate to ACM causes replace not update.
Terraform Core Version
1.3.7
AWS Provider Version
4.55.0
Affected Resource(s)
aws_acm_certificate
Expected Behavior
Terraform should update the certificate in place with a new private key and certificate body, maintaining the existing ARN.
Much like this CLI command
aws acm import-certificate --certificate fileb://cert.pem --certificate-chain fileb://cert-chain.pem --private-key fileb://private-key.pem --certificate-arn <Existing-ARN>
Actual Behavior
Terraform deletes the old certificate and creates a new one with the new private key and certificate body.
Relevant Error/Panic Output Snippet
No response
Terraform Configuration Files
The private key and certificate in the example below change when the certificate nears expiry.
resource "aws_acm_certificate" "cert" {
private_key = vault_pki_secret_backend_cert.cert.private_key
certificate_body = vault_pki_secret_backend_cert.cert.certificate
certificate_chain = vault_pki_secret_backend_cert.cert.ca_chain
tags = var.tags
}
Steps to Reproduce
- Create a certificate with the above configuration
- With a new certificate body (either from vault or from file) run
terraform apply
Debug Output
-/+ destroy and then create replacement
+/- create replacement and then destroy
Terraform will perform the following actions:
# module.vault_cert.aws_acm_certificate.cert must be replaced
-/+ resource "aws_acm_certificate" "cert" {
~ arn = "arn:aws:acm:<region>:<account-number>:certificate/<guid>" -> (known after apply)
Panic Output
No response
Important Factoids
No.
References
The providers update function looks to be here: https://github.com/hashicorp/terraform-provider-aws/blob/1525a37b100dbb2fc1d1d6aefc2905ffcb4f2229/internal/service/acm/certificate.go#L507
Terraform seems to be forcing recreate rather than the update in this function?
Would you like to implement a fix?
None
Community Note
Voting for Prioritization
- Please vote on this issue by adding a 👍 reaction to the original post to help the community and maintainers prioritize this request.
- Please see our prioritization guide for information on how we prioritize.
- Please do not leave "+1" or other comments that do not add relevant new information or questions, they generate extra noise for issue followers and do not help prioritize the request.
Volunteering to Work on This Issue
- If you are interested in working on this issue, please leave a comment.
- If this would be your first contribution, please review the contribution guide.
Hi @NoahCallaway! Are you able to post a bit more output from Terraform please? As you're on very recent versions of both Terraform and the provider, Terraform should tell you which of the attributes caused it to think that the resource needed replacing.
From a quick test here, using hashicorp/tls
to provide the relevant key material, I think it might be the transparency logging option that's causing the problem:
ca.tf
:
resource "tls_private_key" "cert" {
algorithm = "RSA"
}
resource "tls_cert_request" "cert" {
private_key_pem = tls_private_key.cert.private_key_pem
subject {
common_name = "cert.example.com"
organization = "ACME Examples, Inc"
}
}
resource "tls_locally_signed_cert" "cert" {
cert_request_pem = tls_cert_request.cert.cert_request_pem
ca_private_key_pem = tls_private_key.ca.private_key_pem
ca_cert_pem = tls_self_signed_cert.ca.cert_pem
validity_period_hours = 12
allowed_uses = [
"key_encipherment",
"digital_signature",
"server_auth",
]
}
resource "aws_acm_certificate" "cert" {
private_key = tls_private_key.cert.private_key_pem
certificate_body = tls_locally_signed_cert.cert.cert_pem
options {
certificate_transparency_logging_preference = "DISABLED"
}
}
cert.tf
:
resource "tls_private_key" "cert" {
algorithm = "RSA"
}
resource "tls_cert_request" "cert" {
private_key_pem = tls_private_key.cert.private_key_pem
subject {
common_name = "cert.example.com"
organization = "ACME Examples, Inc"
}
}
resource "tls_locally_signed_cert" "cert" {
cert_request_pem = tls_cert_request.cert.cert_request_pem
ca_private_key_pem = tls_private_key.ca.private_key_pem
ca_cert_pem = tls_self_signed_cert.ca.cert_pem
validity_period_hours = 12
allowed_uses = [
"key_encipherment",
"digital_signature",
"server_auth",
]
}
resource "aws_acm_certificate" "cert" {
private_key = tls_private_key.cert.private_key_pem
certificate_body = tls_locally_signed_cert.cert.cert_pem
}
- Create all resources:
$ terraform apply
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following
symbols:
+ create
Terraform will perform the following actions:
# aws_acm_certificate.cert will be created
+ resource "aws_acm_certificate" "cert" {
+ arn = (known after apply)
+ certificate_body = (known after apply)
+ domain_name = (known after apply)
+ domain_validation_options = (known after apply)
+ id = (known after apply)
+ key_algorithm = (known after apply)
+ not_after = (known after apply)
+ not_before = (known after apply)
+ pending_renewal = (known after apply)
+ private_key = (sensitive value)
+ renewal_eligibility = (known after apply)
+ renewal_summary = (known after apply)
+ status = (known after apply)
+ subject_alternative_names = (known after apply)
+ tags_all = (known after apply)
+ type = (known after apply)
+ validation_emails = (known after apply)
+ validation_method = (known after apply)
}
# tls_cert_request.cert will be created
+ resource "tls_cert_request" "cert" {
+ cert_request_pem = (known after apply)
+ id = (known after apply)
+ key_algorithm = (known after apply)
+ private_key_pem = (sensitive value)
+ subject {
+ common_name = "cert.example.com"
+ organization = "ACME Examples, Inc"
}
}
# tls_locally_signed_cert.cert will be created
+ resource "tls_locally_signed_cert" "cert" {
+ allowed_uses = [
+ "key_encipherment",
+ "digital_signature",
+ "server_auth",
]
+ ca_cert_pem = (known after apply)
+ ca_key_algorithm = (known after apply)
+ ca_private_key_pem = (sensitive value)
+ cert_pem = (known after apply)
+ cert_request_pem = (known after apply)
+ early_renewal_hours = 0
+ id = (known after apply)
+ is_ca_certificate = false
+ ready_for_renewal = false
+ set_subject_key_id = false
+ validity_end_time = (known after apply)
+ validity_period_hours = 12
+ validity_start_time = (known after apply)
}
# tls_private_key.ca will be created
+ resource "tls_private_key" "ca" {
+ algorithm = "RSA"
+ ecdsa_curve = "P224"
+ id = (known after apply)
+ private_key_openssh = (sensitive value)
+ private_key_pem = (sensitive value)
+ private_key_pem_pkcs8 = (sensitive value)
+ public_key_fingerprint_md5 = (known after apply)
+ public_key_fingerprint_sha256 = (known after apply)
+ public_key_openssh = (known after apply)
+ public_key_pem = (known after apply)
+ rsa_bits = 2048
}
# tls_private_key.cert will be created
+ resource "tls_private_key" "cert" {
+ algorithm = "RSA"
+ ecdsa_curve = "P224"
+ id = (known after apply)
+ private_key_openssh = (sensitive value)
+ private_key_pem = (sensitive value)
+ private_key_pem_pkcs8 = (sensitive value)
+ public_key_fingerprint_md5 = (known after apply)
+ public_key_fingerprint_sha256 = (known after apply)
+ public_key_openssh = (known after apply)
+ public_key_pem = (known after apply)
+ rsa_bits = 2048
}
# tls_self_signed_cert.ca will be created
+ resource "tls_self_signed_cert" "ca" {
+ allowed_uses = [
+ "key_encipherment",
+ "digital_signature",
+ "server_auth",
+ "cert_signing",
]
+ cert_pem = (known after apply)
+ early_renewal_hours = 0
+ id = (known after apply)
+ is_ca_certificate = true
+ key_algorithm = (known after apply)
+ private_key_pem = (sensitive value)
+ ready_for_renewal = false
+ set_authority_key_id = false
+ set_subject_key_id = false
+ validity_end_time = (known after apply)
+ validity_period_hours = 12
+ validity_start_time = (known after apply)
+ subject {
+ common_name = "example.com"
+ organization = "ACME Examples, Inc"
}
}
Plan: 6 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
tls_private_key.cert: Creating...
tls_private_key.ca: Creating...
tls_private_key.ca: Creation complete after 0s [id=80a77f9ccc78431954a0821224d60acc8504fcd8]
tls_self_signed_cert.ca: Creating...
tls_self_signed_cert.ca: Creation complete after 0s [id=55727894767933383695186811739252795667]
tls_private_key.cert: Creation complete after 0s [id=ecbac0d9f5b3c9ef697892b5a4476dd469843d7a]
tls_cert_request.cert: Creating...
tls_cert_request.cert: Creation complete after 0s [id=0264fc230ccc350f80723a1fa1dd5d53b3a7fffe]
tls_locally_signed_cert.cert: Creating...
tls_locally_signed_cert.cert: Creation complete after 0s [id=242375531891319981900019092251257633177]
aws_acm_certificate.cert: Creating...
aws_acm_certificate.cert: Creation complete after 0s [id=arn:aws:acm:eu-west-2:320797911953:certificate/b385c2fd-a847-4780-87e7-9347b17ee52d]
Apply complete! Resources: 6 added, 0 changed, 0 destroyed.
- Simulate a cert renewal:
$ terraform taint tls_private_key.cert
Resource instance tls_private_key.cert has been marked as tainted.
- Reproduce the issue; note what's logging the
# forces replacement
onaws_acm_certificate.cert
:
$ terraform plan
tls_private_key.cert: Refreshing state... [id=ecbac0d9f5b3c9ef697892b5a4476dd469843d7a]
tls_private_key.ca: Refreshing state... [id=80a77f9ccc78431954a0821224d60acc8504fcd8]
tls_cert_request.cert: Refreshing state... [id=0264fc230ccc350f80723a1fa1dd5d53b3a7fffe]
tls_self_signed_cert.ca: Refreshing state... [id=55727894767933383695186811739252795667]
tls_locally_signed_cert.cert: Refreshing state... [id=242375531891319981900019092251257633177]
aws_acm_certificate.cert: Refreshing state... [id=arn:aws:acm:eu-west-2:320797911953:certificate/b385c2fd-a847-4780-87e7-9347b17ee52d]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following
symbols:
-/+ destroy and then create replacement
Terraform will perform the following actions:
# aws_acm_certificate.cert must be replaced
-/+ resource "aws_acm_certificate" "cert" {
~ arn = "arn:aws:acm:eu-west-2:320797911953:certificate/b385c2fd-a847-4780-87e7-9347b17ee52d" -> (known after apply)
- certificate_authority_arn = "" -> null
~ certificate_body = <<-EOT
-----BEGIN CERTIFICATE-----
MIIDTDCCAjSgAwIBAgIRALZX1Ffb//T7jr7w45PceZkwDQYJKoZIhvcNAQELBQAw
MzEbMBkGA1UEChMSQUNNRSBFeGFtcGxlcywgSW5jMRQwEgYDVQQDEwtleGFtcGxl
LmNvbTAeFw0yMzAyMjgyMDE3MzlaFw0yMzAzMDEwODE3MzlaMDgxGzAZBgNVBAoT
EkFDTUUgRXhhbXBsZXMsIEluYzEZMBcGA1UEAxMQY2VydC5leGFtcGxlLmNvbTCC
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMRdV2iW2Sj0pMtUqbWObWOC
/pzogRcWdcBE9L9qwjHqSeK7QeqzAx5WOgIVVHcAVTil78rgUDgLPrK7Xx2nrKEB
iqJr+gf1NZoHTupUJNLVmGm6Od+u7o0li85GgswCCussh3hVOQ6XyoVPxHmMsOa0
vp9q9KsTy19erHSveQD+/xNkJ0QVaKRU0JcKuKOE2NnxLW6xW5zF62XUjLvpfRLQ
CNVR6dDNOBXyyZ7sUJlRRNvROulhHVbijoALLJFWEexiLY2Eyxrnx4eOR2DgNU2x
SN0maoCbkDTbm6SZDPteX0YJV7fDefjtI+nqSRdWFCdCx1HNaMOr9c5hQLTaNlsC
AwEAAaNWMFQwDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwG
A1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUKM7BnjfT2fvKfKc8qfJ/YJZMW3cwDQYJ
KoZIhvcNAQELBQADggEBALJ0z2SGnDJMsFdOWgUcVHaBUz+jS37uHJCrWB1hCDTl
zqHf0OU4nz09xizohSic2KrcaIyLR6NCb8IuUeuRgBfb7tNXtBuRK6Gu5gL+hWzz
zBSOrlQC45OHDkLa7W5zDIpuX7qJa57ob2e98H9uuPsA3RbCQeSic36WmBlDCSNo
ycSMP5tcYVWhzMFMTFVVAxGrjBCg0XOm0nnP0iiNT7MZgqS9aTqt9CHtBDfoADRD
WmyJnRUuk1W8+26VyTDMkKOiWdtPKKR3QgXa7MICoJB7j+elMR+QeRinJd+DIOer
6cHZjFe33kKa7MALqUThzeUn/Tn3MkzF0/QXe4yl56g=
-----END CERTIFICATE-----
EOT -> (known after apply)
~ domain_name = "cert.example.com" -> (known after apply)
~ domain_validation_options = [] -> (known after apply)
- early_renewal_duration = "" -> null
~ id = "arn:aws:acm:eu-west-2:320797911953:certificate/b385c2fd-a847-4780-87e7-9347b17ee52d" -> (known after apply)
~ key_algorithm = "RSA_2048" -> (known after apply)
~ not_after = "2023-03-01T08:17:39Z" -> (known after apply)
~ not_before = "2023-02-28T20:17:39Z" -> (known after apply)
~ pending_renewal = false -> (known after apply)
~ private_key = (sensitive value)
~ renewal_eligibility = "INELIGIBLE" -> (known after apply)
~ renewal_summary = [] -> (known after apply)
~ status = "ISSUED" -> (known after apply)
~ subject_alternative_names = [
- "cert.example.com",
] -> (known after apply)
- tags = {} -> null
~ tags_all = {} -> (known after apply)
~ type = "IMPORTED" -> (known after apply)
~ validation_emails = [] -> (known after apply)
~ validation_method = "NONE" -> (known after apply)
- options {
- certificate_transparency_logging_preference = "DISABLED" -> null # forces replacement
}
}
# tls_cert_request.cert must be replaced
-/+ resource "tls_cert_request" "cert" {
~ cert_request_pem = <<-EOT
-----BEGIN CERTIFICATE REQUEST-----
MIICfTCCAWUCAQAwODEbMBkGA1UEChMSQUNNRSBFeGFtcGxlcywgSW5jMRkwFwYD
VQQDExBjZXJ0LmV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAxF1XaJbZKPSky1SptY5tY4L+nOiBFxZ1wET0v2rCMepJ4rtB6rMDHlY6
AhVUdwBVOKXvyuBQOAs+srtfHaesoQGKomv6B/U1mgdO6lQk0tWYabo5367ujSWL
zkaCzAIK6yyHeFU5DpfKhU/EeYyw5rS+n2r0qxPLX16sdK95AP7/E2QnRBVopFTQ
lwq4o4TY2fEtbrFbnMXrZdSMu+l9EtAI1VHp0M04FfLJnuxQmVFE29E66WEdVuKO
gAsskVYR7GItjYTLGufHh45HYOA1TbFI3SZqgJuQNNubpJkM+15fRglXt8N5+O0j
6epJF1YUJ0LHUc1ow6v1zmFAtNo2WwIDAQABoAAwDQYJKoZIhvcNAQELBQADggEB
ALEoMx8BSizfmIWK+XZJflFs2OiVVl47xAfqnvLmrrjhdNmbaOzRPNnK/GY/How2
uGr9vI7nK23xTd4zO1JAui7fQIaEcMZpkGwzCWLYtoiAGFrycgEeUqVtlArSOfk5
dtoSvkWbQ95Yf7so/vNLZbtCnIiKjCbDuQYJIrT8UgXJtr1Lv8pp/PFifmjXBrNL
igikzDNYh+z34IvcR4D1l9S/cuw8ZOX24EudgMzmZm5lHfozGQCSm8IHPlBtzjHm
V+lNaxGcs8MCi7UuMUM8OBY6YTWRnZOGLRUBcflcR10V5AcMQ1FJc8I8UGOQt6ES
4Qtcm4jGpXoTwhb5RA10XT4=
-----END CERTIFICATE REQUEST-----
EOT -> (known after apply)
~ id = "0264fc230ccc350f80723a1fa1dd5d53b3a7fffe" -> (known after apply)
~ key_algorithm = "RSA" -> (known after apply)
~ private_key_pem = (sensitive value) # forces replacement
# (1 unchanged block hidden)
}
# tls_locally_signed_cert.cert must be replaced
-/+ resource "tls_locally_signed_cert" "cert" {
~ ca_key_algorithm = "RSA" -> (known after apply)
~ cert_pem = <<-EOT
-----BEGIN CERTIFICATE-----
MIIDTDCCAjSgAwIBAgIRALZX1Ffb//T7jr7w45PceZkwDQYJKoZIhvcNAQELBQAw
MzEbMBkGA1UEChMSQUNNRSBFeGFtcGxlcywgSW5jMRQwEgYDVQQDEwtleGFtcGxl
LmNvbTAeFw0yMzAyMjgyMDE3MzlaFw0yMzAzMDEwODE3MzlaMDgxGzAZBgNVBAoT
EkFDTUUgRXhhbXBsZXMsIEluYzEZMBcGA1UEAxMQY2VydC5leGFtcGxlLmNvbTCC
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMRdV2iW2Sj0pMtUqbWObWOC
/pzogRcWdcBE9L9qwjHqSeK7QeqzAx5WOgIVVHcAVTil78rgUDgLPrK7Xx2nrKEB
iqJr+gf1NZoHTupUJNLVmGm6Od+u7o0li85GgswCCussh3hVOQ6XyoVPxHmMsOa0
vp9q9KsTy19erHSveQD+/xNkJ0QVaKRU0JcKuKOE2NnxLW6xW5zF62XUjLvpfRLQ
CNVR6dDNOBXyyZ7sUJlRRNvROulhHVbijoALLJFWEexiLY2Eyxrnx4eOR2DgNU2x
SN0maoCbkDTbm6SZDPteX0YJV7fDefjtI+nqSRdWFCdCx1HNaMOr9c5hQLTaNlsC
AwEAAaNWMFQwDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwG
A1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUKM7BnjfT2fvKfKc8qfJ/YJZMW3cwDQYJ
KoZIhvcNAQELBQADggEBALJ0z2SGnDJMsFdOWgUcVHaBUz+jS37uHJCrWB1hCDTl
zqHf0OU4nz09xizohSic2KrcaIyLR6NCb8IuUeuRgBfb7tNXtBuRK6Gu5gL+hWzz
zBSOrlQC45OHDkLa7W5zDIpuX7qJa57ob2e98H9uuPsA3RbCQeSic36WmBlDCSNo
ycSMP5tcYVWhzMFMTFVVAxGrjBCg0XOm0nnP0iiNT7MZgqS9aTqt9CHtBDfoADRD
WmyJnRUuk1W8+26VyTDMkKOiWdtPKKR3QgXa7MICoJB7j+elMR+QeRinJd+DIOer
6cHZjFe33kKa7MALqUThzeUn/Tn3MkzF0/QXe4yl56g=
-----END CERTIFICATE-----
EOT -> (known after apply)
~ cert_request_pem = <<-EOT
-----BEGIN CERTIFICATE REQUEST-----
MIICfTCCAWUCAQAwODEbMBkGA1UEChMSQUNNRSBFeGFtcGxlcywgSW5jMRkwFwYD
VQQDExBjZXJ0LmV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAxF1XaJbZKPSky1SptY5tY4L+nOiBFxZ1wET0v2rCMepJ4rtB6rMDHlY6
AhVUdwBVOKXvyuBQOAs+srtfHaesoQGKomv6B/U1mgdO6lQk0tWYabo5367ujSWL
zkaCzAIK6yyHeFU5DpfKhU/EeYyw5rS+n2r0qxPLX16sdK95AP7/E2QnRBVopFTQ
lwq4o4TY2fEtbrFbnMXrZdSMu+l9EtAI1VHp0M04FfLJnuxQmVFE29E66WEdVuKO
gAsskVYR7GItjYTLGufHh45HYOA1TbFI3SZqgJuQNNubpJkM+15fRglXt8N5+O0j
6epJF1YUJ0LHUc1ow6v1zmFAtNo2WwIDAQABoAAwDQYJKoZIhvcNAQELBQADggEB
ALEoMx8BSizfmIWK+XZJflFs2OiVVl47xAfqnvLmrrjhdNmbaOzRPNnK/GY/How2
uGr9vI7nK23xTd4zO1JAui7fQIaEcMZpkGwzCWLYtoiAGFrycgEeUqVtlArSOfk5
dtoSvkWbQ95Yf7so/vNLZbtCnIiKjCbDuQYJIrT8UgXJtr1Lv8pp/PFifmjXBrNL
igikzDNYh+z34IvcR4D1l9S/cuw8ZOX24EudgMzmZm5lHfozGQCSm8IHPlBtzjHm
V+lNaxGcs8MCi7UuMUM8OBY6YTWRnZOGLRUBcflcR10V5AcMQ1FJc8I8UGOQt6ES
4Qtcm4jGpXoTwhb5RA10XT4=
-----END CERTIFICATE REQUEST-----
EOT -> (known after apply) # forces replacement
~ id = "242375531891319981900019092251257633177" -> (known after apply)
~ validity_end_time = "2023-03-01T08:17:39.462762461Z" -> (known after apply)
~ validity_start_time = "2023-02-28T20:17:39.462762461Z" -> (known after apply)
# (8 unchanged attributes hidden)
}
# tls_private_key.cert is tainted, so must be replaced
-/+ resource "tls_private_key" "cert" {
~ id = "ecbac0d9f5b3c9ef697892b5a4476dd469843d7a" -> (known after apply)
~ private_key_openssh = (sensitive value)
~ private_key_pem = (sensitive value)
~ private_key_pem_pkcs8 = (sensitive value)
~ public_key_fingerprint_md5 = "86:c5:ff:28:2e:ec:df:cf:91:6d:4f:a5:74:48:61:1e" -> (known after apply)
~ public_key_fingerprint_sha256 = "SHA256:ySMUc6mRrB5MWZ4Mf2FYQLQ41MmjDiuGu1mTQkQmZVg" -> (known after apply)
~ public_key_openssh = <<-EOT
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDEXVdoltko9KTLVKm1jm1jgv6c6IEXFnXARPS/asIx6kniu0HqswMeVjoCFVR3AFU4pe/K4FA4Cz6yu18dp6yhAYqia/oH9TWaB07qVCTS1Zhpujnfru6NJYvORoLMAgrrLId4VTkOl8qFT8R5jLDmtL6favSrE8tfXqx0r3kA/v8TZCdEFWikVNCXCrijhNjZ8S1usVucxetl1Iy76X0S0AjVUenQzTgV8sme7FCZUUTb0TrpYR1W4o6ACyyRVhHsYi2NhMsa58eHjkdg4DVNsUjdJmqAm5A025ukmQz7Xl9GCVe3w3n47SPp6kkXVhQnQsdRzWjDq/XOYUC02jZb
EOT -> (known after apply)
~ public_key_pem = <<-EOT
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxF1XaJbZKPSky1SptY5t
Y4L+nOiBFxZ1wET0v2rCMepJ4rtB6rMDHlY6AhVUdwBVOKXvyuBQOAs+srtfHaes
oQGKomv6B/U1mgdO6lQk0tWYabo5367ujSWLzkaCzAIK6yyHeFU5DpfKhU/EeYyw
5rS+n2r0qxPLX16sdK95AP7/E2QnRBVopFTQlwq4o4TY2fEtbrFbnMXrZdSMu+l9
EtAI1VHp0M04FfLJnuxQmVFE29E66WEdVuKOgAsskVYR7GItjYTLGufHh45HYOA1
TbFI3SZqgJuQNNubpJkM+15fRglXt8N5+O0j6epJF1YUJ0LHUc1ow6v1zmFAtNo2
WwIDAQAB
-----END PUBLIC KEY-----
EOT -> (known after apply)
# (3 unchanged attributes hidden)
}
Plan: 4 to add, 0 to change, 4 to destroy.
- If I now update my reproducer to have the relevant
options
block, i.e.:
cert.tf
:
resource "aws_acm_certificate" "cert" {
private_key = tls_private_key.cert.private_key_pem
certificate_body = tls_locally_signed_cert.cert.cert_pem
options {
certificate_transparency_logging_preference = "DISABLED"
}
}
The plan now shows the certificate ACM cert will be re-imported under the existing ARN:
$ terraform plan
tls_private_key.ca: Refreshing state... [id=80a77f9ccc78431954a0821224d60acc8504fcd8]
tls_private_key.cert: Refreshing state... [id=ecbac0d9f5b3c9ef697892b5a4476dd469843d7a]
tls_cert_request.cert: Refreshing state... [id=0264fc230ccc350f80723a1fa1dd5d53b3a7fffe]
tls_self_signed_cert.ca: Refreshing state... [id=55727894767933383695186811739252795667]
tls_locally_signed_cert.cert: Refreshing state... [id=242375531891319981900019092251257633177]
aws_acm_certificate.cert: Refreshing state... [id=arn:aws:acm:eu-west-2:320797911953:certificate/b385c2fd-a847-4780-87e7-9347b17ee52d]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following
symbols:
~ update in-place
-/+ destroy and then create replacement
Terraform will perform the following actions:
# aws_acm_certificate.cert will be updated in-place
~ resource "aws_acm_certificate" "cert" {
~ certificate_body = <<-EOT
-----BEGIN CERTIFICATE-----
MIIDTDCCAjSgAwIBAgIRALZX1Ffb//T7jr7w45PceZkwDQYJKoZIhvcNAQELBQAw
MzEbMBkGA1UEChMSQUNNRSBFeGFtcGxlcywgSW5jMRQwEgYDVQQDEwtleGFtcGxl
LmNvbTAeFw0yMzAyMjgyMDE3MzlaFw0yMzAzMDEwODE3MzlaMDgxGzAZBgNVBAoT
EkFDTUUgRXhhbXBsZXMsIEluYzEZMBcGA1UEAxMQY2VydC5leGFtcGxlLmNvbTCC
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMRdV2iW2Sj0pMtUqbWObWOC
/pzogRcWdcBE9L9qwjHqSeK7QeqzAx5WOgIVVHcAVTil78rgUDgLPrK7Xx2nrKEB
iqJr+gf1NZoHTupUJNLVmGm6Od+u7o0li85GgswCCussh3hVOQ6XyoVPxHmMsOa0
vp9q9KsTy19erHSveQD+/xNkJ0QVaKRU0JcKuKOE2NnxLW6xW5zF62XUjLvpfRLQ
CNVR6dDNOBXyyZ7sUJlRRNvROulhHVbijoALLJFWEexiLY2Eyxrnx4eOR2DgNU2x
SN0maoCbkDTbm6SZDPteX0YJV7fDefjtI+nqSRdWFCdCx1HNaMOr9c5hQLTaNlsC
AwEAAaNWMFQwDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwG
A1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUKM7BnjfT2fvKfKc8qfJ/YJZMW3cwDQYJ
KoZIhvcNAQELBQADggEBALJ0z2SGnDJMsFdOWgUcVHaBUz+jS37uHJCrWB1hCDTl
zqHf0OU4nz09xizohSic2KrcaIyLR6NCb8IuUeuRgBfb7tNXtBuRK6Gu5gL+hWzz
zBSOrlQC45OHDkLa7W5zDIpuX7qJa57ob2e98H9uuPsA3RbCQeSic36WmBlDCSNo
ycSMP5tcYVWhzMFMTFVVAxGrjBCg0XOm0nnP0iiNT7MZgqS9aTqt9CHtBDfoADRD
WmyJnRUuk1W8+26VyTDMkKOiWdtPKKR3QgXa7MICoJB7j+elMR+QeRinJd+DIOer
6cHZjFe33kKa7MALqUThzeUn/Tn3MkzF0/QXe4yl56g=
-----END CERTIFICATE-----
EOT -> (known after apply)
id = "arn:aws:acm:eu-west-2:320797911953:certificate/b385c2fd-a847-4780-87e7-9347b17ee52d"
~ private_key = (sensitive value)
tags = {}
# (17 unchanged attributes hidden)
# (1 unchanged block hidden)
}
# tls_cert_request.cert must be replaced
-/+ resource "tls_cert_request" "cert" {
~ cert_request_pem = <<-EOT
-----BEGIN CERTIFICATE REQUEST-----
MIICfTCCAWUCAQAwODEbMBkGA1UEChMSQUNNRSBFeGFtcGxlcywgSW5jMRkwFwYD
VQQDExBjZXJ0LmV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAxF1XaJbZKPSky1SptY5tY4L+nOiBFxZ1wET0v2rCMepJ4rtB6rMDHlY6
AhVUdwBVOKXvyuBQOAs+srtfHaesoQGKomv6B/U1mgdO6lQk0tWYabo5367ujSWL
zkaCzAIK6yyHeFU5DpfKhU/EeYyw5rS+n2r0qxPLX16sdK95AP7/E2QnRBVopFTQ
lwq4o4TY2fEtbrFbnMXrZdSMu+l9EtAI1VHp0M04FfLJnuxQmVFE29E66WEdVuKO
gAsskVYR7GItjYTLGufHh45HYOA1TbFI3SZqgJuQNNubpJkM+15fRglXt8N5+O0j
6epJF1YUJ0LHUc1ow6v1zmFAtNo2WwIDAQABoAAwDQYJKoZIhvcNAQELBQADggEB
ALEoMx8BSizfmIWK+XZJflFs2OiVVl47xAfqnvLmrrjhdNmbaOzRPNnK/GY/How2
uGr9vI7nK23xTd4zO1JAui7fQIaEcMZpkGwzCWLYtoiAGFrycgEeUqVtlArSOfk5
dtoSvkWbQ95Yf7so/vNLZbtCnIiKjCbDuQYJIrT8UgXJtr1Lv8pp/PFifmjXBrNL
igikzDNYh+z34IvcR4D1l9S/cuw8ZOX24EudgMzmZm5lHfozGQCSm8IHPlBtzjHm
V+lNaxGcs8MCi7UuMUM8OBY6YTWRnZOGLRUBcflcR10V5AcMQ1FJc8I8UGOQt6ES
4Qtcm4jGpXoTwhb5RA10XT4=
-----END CERTIFICATE REQUEST-----
EOT -> (known after apply)
~ id = "0264fc230ccc350f80723a1fa1dd5d53b3a7fffe" -> (known after apply)
~ key_algorithm = "RSA" -> (known after apply)
~ private_key_pem = (sensitive value) # forces replacement
# (1 unchanged block hidden)
}
# tls_locally_signed_cert.cert must be replaced
-/+ resource "tls_locally_signed_cert" "cert" {
~ ca_key_algorithm = "RSA" -> (known after apply)
~ cert_pem = <<-EOT
-----BEGIN CERTIFICATE-----
MIIDTDCCAjSgAwIBAgIRALZX1Ffb//T7jr7w45PceZkwDQYJKoZIhvcNAQELBQAw
MzEbMBkGA1UEChMSQUNNRSBFeGFtcGxlcywgSW5jMRQwEgYDVQQDEwtleGFtcGxl
LmNvbTAeFw0yMzAyMjgyMDE3MzlaFw0yMzAzMDEwODE3MzlaMDgxGzAZBgNVBAoT
EkFDTUUgRXhhbXBsZXMsIEluYzEZMBcGA1UEAxMQY2VydC5leGFtcGxlLmNvbTCC
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMRdV2iW2Sj0pMtUqbWObWOC
/pzogRcWdcBE9L9qwjHqSeK7QeqzAx5WOgIVVHcAVTil78rgUDgLPrK7Xx2nrKEB
iqJr+gf1NZoHTupUJNLVmGm6Od+u7o0li85GgswCCussh3hVOQ6XyoVPxHmMsOa0
vp9q9KsTy19erHSveQD+/xNkJ0QVaKRU0JcKuKOE2NnxLW6xW5zF62XUjLvpfRLQ
CNVR6dDNOBXyyZ7sUJlRRNvROulhHVbijoALLJFWEexiLY2Eyxrnx4eOR2DgNU2x
SN0maoCbkDTbm6SZDPteX0YJV7fDefjtI+nqSRdWFCdCx1HNaMOr9c5hQLTaNlsC
AwEAAaNWMFQwDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwG
A1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUKM7BnjfT2fvKfKc8qfJ/YJZMW3cwDQYJ
KoZIhvcNAQELBQADggEBALJ0z2SGnDJMsFdOWgUcVHaBUz+jS37uHJCrWB1hCDTl
zqHf0OU4nz09xizohSic2KrcaIyLR6NCb8IuUeuRgBfb7tNXtBuRK6Gu5gL+hWzz
zBSOrlQC45OHDkLa7W5zDIpuX7qJa57ob2e98H9uuPsA3RbCQeSic36WmBlDCSNo
ycSMP5tcYVWhzMFMTFVVAxGrjBCg0XOm0nnP0iiNT7MZgqS9aTqt9CHtBDfoADRD
WmyJnRUuk1W8+26VyTDMkKOiWdtPKKR3QgXa7MICoJB7j+elMR+QeRinJd+DIOer
6cHZjFe33kKa7MALqUThzeUn/Tn3MkzF0/QXe4yl56g=
-----END CERTIFICATE-----
EOT -> (known after apply)
~ cert_request_pem = <<-EOT
-----BEGIN CERTIFICATE REQUEST-----
MIICfTCCAWUCAQAwODEbMBkGA1UEChMSQUNNRSBFeGFtcGxlcywgSW5jMRkwFwYD
VQQDExBjZXJ0LmV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEAxF1XaJbZKPSky1SptY5tY4L+nOiBFxZ1wET0v2rCMepJ4rtB6rMDHlY6
AhVUdwBVOKXvyuBQOAs+srtfHaesoQGKomv6B/U1mgdO6lQk0tWYabo5367ujSWL
zkaCzAIK6yyHeFU5DpfKhU/EeYyw5rS+n2r0qxPLX16sdK95AP7/E2QnRBVopFTQ
lwq4o4TY2fEtbrFbnMXrZdSMu+l9EtAI1VHp0M04FfLJnuxQmVFE29E66WEdVuKO
gAsskVYR7GItjYTLGufHh45HYOA1TbFI3SZqgJuQNNubpJkM+15fRglXt8N5+O0j
6epJF1YUJ0LHUc1ow6v1zmFAtNo2WwIDAQABoAAwDQYJKoZIhvcNAQELBQADggEB
ALEoMx8BSizfmIWK+XZJflFs2OiVVl47xAfqnvLmrrjhdNmbaOzRPNnK/GY/How2
uGr9vI7nK23xTd4zO1JAui7fQIaEcMZpkGwzCWLYtoiAGFrycgEeUqVtlArSOfk5
dtoSvkWbQ95Yf7so/vNLZbtCnIiKjCbDuQYJIrT8UgXJtr1Lv8pp/PFifmjXBrNL
igikzDNYh+z34IvcR4D1l9S/cuw8ZOX24EudgMzmZm5lHfozGQCSm8IHPlBtzjHm
V+lNaxGcs8MCi7UuMUM8OBY6YTWRnZOGLRUBcflcR10V5AcMQ1FJc8I8UGOQt6ES
4Qtcm4jGpXoTwhb5RA10XT4=
-----END CERTIFICATE REQUEST-----
EOT -> (known after apply) # forces replacement
~ id = "242375531891319981900019092251257633177" -> (known after apply)
~ validity_end_time = "2023-03-01T08:17:39.462762461Z" -> (known after apply)
~ validity_start_time = "2023-02-28T20:17:39.462762461Z" -> (known after apply)
# (8 unchanged attributes hidden)
}
# tls_private_key.cert is tainted, so must be replaced
-/+ resource "tls_private_key" "cert" {
~ id = "ecbac0d9f5b3c9ef697892b5a4476dd469843d7a" -> (known after apply)
~ private_key_openssh = (sensitive value)
~ private_key_pem = (sensitive value)
~ private_key_pem_pkcs8 = (sensitive value)
~ public_key_fingerprint_md5 = "86:c5:ff:28:2e:ec:df:cf:91:6d:4f:a5:74:48:61:1e" -> (known after apply)
~ public_key_fingerprint_sha256 = "SHA256:ySMUc6mRrB5MWZ4Mf2FYQLQ41MmjDiuGu1mTQkQmZVg" -> (known after apply)
~ public_key_openssh = <<-EOT
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDEXVdoltko9KTLVKm1jm1jgv6c6IEXFnXARPS/asIx6kniu0HqswMeVjoCFVR3AFU4pe/K4FA4Cz6yu18dp6yhAYqia/oH9TWaB07qVCTS1Zhpujnfru6NJYvORoLMAgrrLId4VTkOl8qFT8R5jLDmtL6favSrE8tfXqx0r3kA/v8TZCdEFWikVNCXCrijhNjZ8S1usVucxetl1Iy76X0S0AjVUenQzTgV8sme7FCZUUTb0TrpYR1W4o6ACyyRVhHsYi2NhMsa58eHjkdg4DVNsUjdJmqAm5A025ukmQz7Xl9GCVe3w3n47SPp6kkXVhQnQsdRzWjDq/XOYUC02jZb
EOT -> (known after apply)
~ public_key_pem = <<-EOT
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxF1XaJbZKPSky1SptY5t
Y4L+nOiBFxZ1wET0v2rCMepJ4rtB6rMDHlY6AhVUdwBVOKXvyuBQOAs+srtfHaes
oQGKomv6B/U1mgdO6lQk0tWYabo5367ujSWLzkaCzAIK6yyHeFU5DpfKhU/EeYyw
5rS+n2r0qxPLX16sdK95AP7/E2QnRBVopFTQlwq4o4TY2fEtbrFbnMXrZdSMu+l9
EtAI1VHp0M04FfLJnuxQmVFE29E66WEdVuKOgAsskVYR7GItjYTLGufHh45HYOA1
TbFI3SZqgJuQNNubpJkM+15fRglXt8N5+O0j6epJF1YUJ0LHUc1ow6v1zmFAtNo2
WwIDAQAB
-----END PUBLIC KEY-----
EOT -> (known after apply)
# (3 unchanged attributes hidden)
}
Plan: 3 to add, 1 to change, 3 to destroy.
Hi @mattburgess, thanks for looking into this.
Yes, apologies I've been slightly stingy with my plan output as didn't want to share anything I shouldn't. You've recreated my issue exactly.
With my existing configuration, I'm also seeing the certificate transparency logging option as the reason for replacement - I should have spotted this earlier apologies.
Section from the plan on aws_acm_certificate.cert
resource shown below.
# module.vault_cert.aws_acm_certificate.cert must be replaced
-/+ resource "aws_acm_certificate" "cert" {
~ arn = "arn:aws:acm:eu-west-2:<account-number>:certificate/<guid>" -> (known after apply)
- certificate_authority_arn = "" -> null
~ certificate_body = <<-EOT
.............
~ type = "IMPORTED" -> (known after apply)
~ validation_emails = [] -> (known after apply)
~ validation_method = "NONE" -> (known after apply)
# (1 unchanged attribute hidden)
- options {
- certificate_transparency_logging_preference = "DISABLED" -> null # forces replacement
}
}
Adding the options as you did in cert.tf
looks like it fixed my issue when I run the plan as below.
# module.vault_cert.aws_acm_certificate.cert will be updated in-place
~ resource "aws_acm_certificate" "cert" {
~ certificate_body = <<-EOT
However, once the apply is run I get a conflict error:
╷
│ Error: Conflicting configuration arguments
│
│ with module.vault_cert.aws_acm_certificate.cert,
│ on vault_pki_cert_to_acm/main.tf line 24, in resource "aws_acm_certificate" "cert":
│ 24: certificate_transparency_logging_preference = "DISABLED"
│
│ "options.0.certificate_transparency_logging_preference": conflicts with certificate_body
Thanks again for your help.
It looks like I might be able to workaround this issue by adding the lifecycle block to ignore changes to the options.
The following allows me to re-import the certificate successfully without changing the ARN.
resource "aws_acm_certificate" "cert" {
private_key = vault_pki_secret_backend_cert.cert.private_key
certificate_body = vault_pki_secret_backend_cert.cert.certificate
certificate_chain = vault_pki_secret_backend_cert.cert.ca_chain
lifecycle {
ignore_changes = [
options,
]
}
tags = var.tags
}
This functionality has been released in v4.58.0 of the Terraform AWS Provider. Please see the Terraform documentation on provider versioning or reach out if you need any assistance upgrading.
For further feature requests or bug reports with this functionality, please create a new GitHub issue following the template. Thank you!
I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.