-
Notifications
You must be signed in to change notification settings - Fork 9.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support issuance of ACM private certificate #6666
Conversation
aws/resource_aws_acm_certificate.go
Outdated
acmconn := meta.(*AWSClient).acmconn | ||
params := &acm.RequestCertificateInput{ | ||
DomainName: aws.String(d.Get("domain_name").(string)), | ||
ValidationMethod: aws.String(d.Get("validation_method").(string)), | ||
IdempotencyToken: aws.String(strconv.Itoa(rand.Int())), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering if using some sort of hash of the domain_name
(that fits in 32 characters or less) would be more suitable.
That is, one might not want to generate multiple certificates for the same domain if somehow the API request fails and has to retry multiple times within the hour.
From the RequestCertificate API documentation:
Customer chosen string that can be used to distinguish between calls to RequestCertificate. Idempotency tokens time out after one hour. Therefore, if you call RequestCertificate multiple times with the same idempotency token within one hour, ACM recognizes that you are requesting only one certificate and will issue only one. If you change the idempotency token for each call, ACM recognizes that you are requesting multiple certificates.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we may want to hash domain name + SANs + private CA ARN if it's a private cert.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@micbase Good question.
I was wondering if the goal of the token is to distinguish two (or possibly more) of the same calls to the RequestCertificate
API (i.e. with the exact same parameters) so that the same certificate ARN is returned to prevent creating a new certificate if the client was somehow not able to read the response (e.g. network issues).
That is whether changing one parameter (e.g. adding a SAN) is considered to a different "request" from AWS perspective even if you provide the same idempotency token.
So, I run the following command against two PCAs in a single region from a single account during the same hour and got some interesting results.
Requesting a certificate multiple times with the same token:
$ date && aws acm request-certificate --domain-name pr-6666.com --certificate-authority-arn arn:aws:acm-pca:region:1234:certificate-authority/1 --idempotency-token PR6666
Tue 5 Feb 2019 12:32:55 PST
{
"CertificateArn": "arn:aws:acm:region:1234:certificate/78d5b732-88a8-49af-8929-f28359eb8b75"
}
$ date && aws acm request-certificate --domain-name pr-6666.com --certificate-authority-arn arn:aws:acm-pca:region:1234:certificate-authority/1 --idempotency-token PR6666
Tue 5 Feb 2019 12:33:01 PST
{
"CertificateArn": "arn:aws:acm:region:1234:certificate/78d5b732-88a8-49af-8929-f28359eb8b75"
}
Then adding a SAN yet keeping the same token will generate a new certificate:
$ date && aws acm request-certificate --domain-name pr-6666.com --subject-alternative-names pr-6666.org --certificate-authority-arn arn:aws:acm-pca:region:1234:certificate-authority/1 --idempotency-token PR6666
Tue 5 Feb 2019 12:35:16 PST
{
"CertificateArn": "arn:aws:acm:region:1234:certificate/b75395d9-d9fe-4249-8b30-c7ac4d1fbfd0"
}
$ date && aws acm request-certificate --domain-name pr-6666.com --subject-alternative-names pr-6666.org --certificate-authority-arn arn:aws:acm-pca:region:1234:certificate-authority/1 --idempotency-token PR6666
Tue 5 Feb 2019 12:35:32 PST
{
"CertificateArn": "arn:aws:acm:region:1234:certificate/b75395d9-d9fe-4249-8b30-c7ac4d1fbfd0"
}
Then changing the certificate authority (same account, same region) somehow returns the same certificate (I consider that behaviour a bug):
$ date && aws acm request-certificate --domain-name pr-6666.com --subject-alternative-names pr-6666.org --certificate-authority-arn arn:aws:acm-pca:region:1234:certificate-authority/2 --idempotency-token PR6666
Tue 5 Feb 2019 12:36:05 PST
{
"CertificateArn": "arn:aws:acm:region:1234:certificate/b75395d9-d9fe-4249-8b30-c7ac4d1fbfd0"
}
Then adding one more SAN generates a new certificate:
$ date && aws acm request-certificate --domain-name pr-6666.com --subject-alternative-names pr-6666.org pr-6666.net --certificate-authority-arn arn:aws:acm-pca:region:1234:certificate-authority/2 --idempotency-token PR6666
Tue 5 Feb 2019 12:39:03 PST
{
"CertificateArn": "arn:aws:acm:region:1234:certificate/0d41f00a-25ce-492e-b6c4-1bb34b64da60"
}
$ date && aws acm request-certificate --domain-name pr-6666.com --subject-alternative-names pr-6666.org pr-6666.net --certificate-authority-arn arn:aws:acm-pca:region:1234:certificate-authority/2 --idempotency-token PR6666
Tue 5 Feb 2019 12:39:10 PST
{
"CertificateArn": "arn:aws:acm:region:1234:certificate/0d41f00a-25ce-492e-b6c4-1bb34b64da60"
}
And switching back to the original certificate authority do keep the same certificate (again kind of unexpected behaviour IMHO):
$ date && aws acm request-certificate --domain-name pr-6666.com --subject-alternative-names pr-6666.org pr-6666.net --certificate-authority-arn arn:aws:acm-pca:region:1234:certificate-authority/1 --idempotency-token PR6666
Tue 5 Feb 2019 12:39:30 PST
{
"CertificateArn": "arn:aws:acm:region:1234:certificate/0d41f00a-25ce-492e-b6c4-1bb34b64da60"
}
I would be keen to only have the domain name as part of the hash but it seems that adding the PCA ARN could work around that bug of getting the same certificate.
However this might be fixed eventually (if it is a bug and not a feature).
What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is the exact problem I encountered, apologize for not expressing it clearly in my initial PR.
IMO, using two different PCAs should generate different certs, so I used IdempotencyToken to work it around. I'm not sure if that's a bug or feature, more like a bug to me.
if ok { | ||
params.CertificateAuthorityArn = aws.String(caARN.(string)) | ||
} else { | ||
params.ValidationMethod = aws.String(d.Get("validation_method").(string)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The changes made to move the validation_method
argument from required to optional might require some extra validation to prevent calling the API for public certificate with the unsupported value NONE
(if such an argument is not set).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@micbase Any chance you can resolve the conflicts and look at my comments? If not I would be happy to take over by creating a separate PR based on your commits. |
@slaunay Sorry about the delay, will take a look this weekend. |
@slaunay I updated the branch, please take a look when you have time. |
I have reach to AWS about that token behaviour and they were able to reproduce it including with an invalid certificate authority ARN:
They also mentioned the same workaround of using a different token when the certificate authority changes, I'll provide an update once they get back to me. It would also be nice to have somebody with write access to the repo look at this PR now that is has no merge conflicts. |
Hey folks 👋 We typically use something like I guess more generally my question is whether its worth all the hassle trying to come up with the more complicated implementation (that may be potentially incorrect/buggy) for an atypical situation that we won't be able to easily test. For general networking issues, the AWS Go SDK should be automatically retrying with the provided |
It seems that the token is tied to the life cycle of the generated certificate as seen with the following test: Issuing a new certificate twice using the same token:
Deleting that certificate:
Reissuing the "same" certificate within the same hour using the same token result in a different ARN:
AWS support got back to me and here is their response that confirm the bug mentioned above:
True, the internal retry is a good first line of defence to avoid generating two certificates for the same domain during a single I would personally lean towards using only the domain name to compute the idempotency token and explicitly documenting that, knowing that it would currently return the same certificate ARN when changing the PCA. We could also expose the token to the end user as an attribute to set, maybe with a default to such hash for more flexibility but that seems convoluted to me. What do you guys think make sense? |
So when you using the same IdempotencyToken with different domain name, ACM will create new cert right? Why do we want to compute the token based on domain name? |
I believe the crux of the idempotency token is to deduplicate the exact same request (i.e. same domain name requested plus other properties) in case the client is retrying to prevent issuing a new certificate. Now for what to put in the token, I think it really depends on how bad you want to prevent a new certificate from getting issued:
|
@bflad What approach would you recommend? |
@bflad Do you have any suggestions on how to get this feature integrated into the AWS provider? |
I have a very similar looking PR at #9288 which I obviously raised because my poor searching didn't find this one somehow! Interestingly, you don't appear to have hit the issue I did whereby I need to wait for the cert to be in ISSUED state, otherwise things would die horribly due to various fields not being populated until that happens. I wonder if ACM PCA has different performance in different regions such that your tests never hit that condition? Anyway, would be really good if someone could review this and mine please so that we can get support upstream. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good, thanks, @micbase 🚀 The only minor changes on merge are changing IdempotencyToken
to use resource.PrefixedUniqueId()
which uses a monotonic counter to follow the conventions with the rest of the provider and having these new private certificates automatically retry while they sit in PENDING_VALIDATION
where certificate details such as domain name are filled in by the API.
Output from acceptance testing:
--- PASS: TestAccAWSAcmCertificate_imported_IpAddress (10.34s)
--- PASS: TestAccAWSAcmCertificate_wildcard (13.56s)
--- PASS: TestAccAWSAcmCertificate_dnsValidation (15.16s)
--- PASS: TestAccAWSAcmCertificate_privateCert (15.19s)
--- PASS: TestAccAWSAcmCertificate_imported_DomainName (15.45s)
--- PASS: TestAccAWSAcmCertificate_rootAndWildcardSan (16.29s)
--- PASS: TestAccAWSAcmCertificate_root_TrailingPeriod (16.29s)
--- PASS: TestAccAWSAcmCertificate_root (16.31s)
--- PASS: TestAccAWSAcmCertificate_san_TrailingPeriod (17.01s)
--- PASS: TestAccAWSAcmCertificate_san_multiple (18.08s)
--- PASS: TestAccAWSAcmCertificate_disableCTLogging (18.53s)
--- PASS: TestAccAWSAcmCertificate_wildcardAndRootSan (18.66s)
--- PASS: TestAccAWSAcmCertificate_san_single (21.37s)
--- PASS: TestAccAWSAcmCertificate_emailValidation (23.08s)
--- PASS: TestAccAWSAcmCertificate_tags (33.48s)
This has been released in version 2.23.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 for triage. Thanks! |
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 feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thanks! |
Fixes partial of #5550
For certificates issued by PCA, need a separate resource, and not covered in this PR
Changes proposed in this pull request:
Output from acceptance testing: