-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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
feat(certificatemanager): deprecate DnsValidatedCertificate #21982
Conversation
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 seems almost too good to be true. Is it really that simple?
Small nit on the example (probably need to transport the string value itself instead of the StringParameter
object).
// save the certificate in an SSM parameter so it can be looked up later | ||
const output = new StringParameter(east1Stack, 'CertificateArn', { | ||
// generate a physical name for cross region reference | ||
parameterName: `${Names.uniqueResourceName(cert, {})}Parameter`, |
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.
If this empty object is really required, mind making that optional as well?
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.
In the uniqueResourceName
method?
region: 'us-east-1', | ||
physicalResourceId: PhysicalResourceId.fromResponse('Parameter.Value'), | ||
parameters: { | ||
Name: output.parameterName, |
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.
Is this going to work? As in, is going to reference the actual hard-coded parameter name? (As opposed to generating an illegal cross-stack reference?)
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.
Yeah it works since I'm creating a physical name for the parameter.
}); | ||
|
||
const lookedUpCert = acm.Certificate.fromCertificateArn(east2Stack, 'Cert', lookup.getResponseField('Parameter.Value')); |
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.
Don't forget to add a stack dependency
The solution reads to me as cross region use is not supported. I’d be annoyed to have to create a stack in us-east-1 just because the certificate has to be there, while the actual cloudfront distribution can be created in a stack in (in our case) eu-west-1. Sure, it works, but it seems to be a regression in functionality before the equivalent functionality is actually implemented ‘natively’. In practice, we never deploy cloudfront without creating a certificate, so this will always need to be split between several stacks. I get that having to use a custom resource is not great, so if deprecation means more available time for a real fix, I'd be all for it. |
Yeah cross region is technically not supported by CloudFormation in this case. There is an open issue in their roadmap for the Certificate resource to work cross region, which is what the long term solution should be.
Deprecation means that it may be removed in the next major version of CDK (v3.0.0), so it will continue to be available until then. It also means that we will not work on enhancements. |
hmm looks like |
@@ -65,6 +65,7 @@ export interface DnsValidatedCertificateProps extends CertificateProps { | |||
* validated using DNS validation against the specified Route 53 hosted zone. | |||
* | |||
* @resource AWS::CertificateManager::Certificate | |||
* @deprecated use {@link Certificate} instead |
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.
@corymhall Does this flag result in an annotation at synth time? e.g. to warn users and nudge them towards the new shiny Cfn functionality.
As stated in #8934 I do not believe that we should deprecate this until we find a viable replacement for multi-region certificates. I understand that this will likely be removed in 3.0.0, which is some time away, however I ask that we put a blocker on this particular feature until we have discussed and found a solution that we're happy that will allow customers to deploy their CloudFront distributions. Short of feature request enhancements to either ACM or CloudFormation here are some possible solutions (ideally more than one).
|
Name: output.parameterName, | ||
}, | ||
}, | ||
policy: AwsCustomResourcePolicy.fromSdkCalls({ resources: ['*'] }), |
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.
@corymhall Simply curious - any reason we can't scope this down to a single SSM parameter?
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.
In theory, yes, since we're using a named parameter. If I were doing this in native CFN I'd do it using the following Fn::Sub...
arn:${AWS::Partition}:ssm:us-east-1:${AWS::AccountId}:parameter/${output.parameterName}
For best practice we should probably limit the policy scope to this resource.
Now that the official CloudFormation resource `AWS::CertificateManager::Certificate` (CDK's `Certificate` construct) supports DNS validation we do not want to recommend using the `DnsValidatedCertificate` construct. The `DnsValidatedCertificate` construct uses CloudFormation custom resources to perform the certificate creation and this creates a lot of maintenance burden on our team (see the list of linked issues). Currently the primary use case for using `DnsValidatedCertificate` over `Certificate` is for cross region use cases. For this use case I have updated the README to have our suggested solution. fixes #8934, #2914, #20698, #17349, #15217, #14519
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.
Just one question inline but I also want to ask about tests for this one. It looks like no new tests were added, just adjusted from test
to testDeprecated
. Is there a reason to not add new tests?
@TheRealAmazonKendra I should have included it in the description, but I added tests in previous PRs to test the new recommended behavior so this PR is only deprecating the existing behavior. Tests added: aws-cdk/packages/@aws-cdk/aws-route53-patterns/test/bucket-website-target.test.ts Lines 157 to 294 in ba14612
https://github.com/aws/aws-cdk/blob/main/packages/%40aws-cdk/aws-route53-patterns/test/integ.hosted-redirect-same-region.ts https://github.com/aws/aws-cdk/blob/main/packages/%40aws-cdk/aws-cloudfront/test/integ.cloudfront-cross-region-cert.ts |
Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
Is the multi-stack solution for Cloudfront supposed to be definitive? It's really cumbersome when applied on our codebase, and if there's a possibility to wait for a better solution we'll endure the annoying deprecation notices. |
I think issue #8934 might be incorrectly marked as fixed with this PR. It doesn't seem to me that Cloudformation supports cross-account ACM validation. There is no field to pass a role to Cloudformation for the cross-account call. |
@corymhall / @jskrt do you happen to know when using Certificate instead of DnsValidatedCertificate - is it possible to specify the location of the certificate. |
@damogallagher I think I asked essentially the same question here #23952. |
The answer to @damogallagher's question is "no". We now need to create a separate |
Deprecation of this resource without addressing cross-region references in an automatic way is going to make this difficult for a lot of customers. |
It sucks that this creates a new Certificate with a new ARN that then also needs to be validated. We just can not make this change. Please do not deprecate this as it means we would not be able to update to V3 when that eventually drops. Maybe changing the name to include "Legacy" or something like that is an acceptable solution? |
The only additional requirement that you have now is to explicitly create a stack in CloudFormation is a regional service. In order to create a resource in a specific region, you must create a stack in that region. I 100% agree that it is not a great experience to be allowed to create a CloudFront distribution in any region, but are required to create an ACM certificate in |
Why is that a problem? |
I 100% understand why you want to deprecate to it and I am all for the advantages it brings. My problem comes in that we have:
There is no strong dependency between these. What is going to happen when we switch to the new Cert CFN construct?
When I say multiple, it is about 4+ regions, with easily 100+ stacks per region spread over three different AWS accounts. As I am writing this, I think the problem is that the old It should rather be approached from a multistage migration standpoint. Where you:
Am I maybe missing something and completely overthinking it? |
You could definitely do this in a multistage deployment process. CloudFormation first applies all updates before applying any deletions, so if you were to do it in a single operation it will first create the certificate and then update the CloudFront distributions to reference the new certificate and then delete the old certificate. |
Okay that is good to know(or remember 😅)
The problem here is that the Cert and let's use the CloudFront for this example, is not in the same stack. CloudFormation does not know about where the Cert ARN is used because the Cert ARN is stored in an SSM parameter and then read by the other stacks. Basically:
Because these are not in the same stack and not in the same deployment, CFN can not know this weak reference (not CFN Exports) relationship exists so I fear that when it tries to delete the Cert it will either succeed and then the CloudFronts and ALBs will break? Or it will prevent the deletion of the cert because it is "in use" of which I think is complicated to determine so I am not sure if AWS actually does this check. If they don't and the cert is deleted what happens to the resources that depended on it? |
As mentioned by a number of people, |
What about https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_certificatemanager.DnsValidatedCertificate.html#cleanuproute53records ? Currently we really like this feature for our disaster recovery tests where we just deploy and destroy our stacks. |
Just to let everybody realize how disrupting this change is: in order to use I understand the reasons of the deprecation, but it's waaaay too early. |
@rehanvdm Maybe I'm missing something here, but wouldn't the solution be the same for any instance of replacing a resource with "weak" references, ie create the new cert alongside the old one, update the SSM value, redeploy the new stacks, then remove the old cert? It's obviously extra steps, but that just seems like the limitations you incur by relying on ARN references, no? |
@luxaritas Yes, 100% correct. But the assumption that this deprecation is based on is wrong:
My problem is that the deprecation is pointing to the new Certificate construct and is positioning it as a drop-in replacement. When it is not, certificates will get destroyed, this might be fine if your cert and the service using the cert is in the same stack, then the logic above holds. But for many, a cert is used across many applications/stacks/regions, so this is not the case and you will only realize this once it is too late. Removing just that one line, as in the PR would have been my suggestion as well. It will prompt people to actually go and investigate and scrutinize their architecture to decide if they can just use the new construct or do a migration as I mentioned. |
Ah, so your concern is not so much around the deprecation as how the forward-migration is described? It's still useful for it to be clear that |
I think a long term solution to this will be to manage stack policies as part of CDK. By utilizing this feature, we can get users to mark a construct with constraints, like preventing deletion or replacement update. That way, if a consumer updates a construct with a new one and it isn't a slot in replacement, the update will fail due to a policy violation, which will encourage the customer to think about migration and, when ready, provide an override clause. I'll talk internally to the CDK team about modeling this. |
@taylorb-syd From a user level that would also be awesome if that means I could get extra protections on say an EC2 instance such that I don't get surprised by it being replaced by changing a property I didn't expect to lead to replacement. I didn't know I needed this until now 🙂 |
I'm a little confused (came here following breadcrumbs around the construct being deprecated). Could you just have two certificates active for a while in the CDK code? e.g. "add new class, keep old, deploy". Wait till everything changes over to new class, "remove old class, deploy" ? Intuitively that's how I'd deal with the migration - curious now as to whether that would work for you (I'm not up against the grindstone on this one yet, so have the luxury of being curious). |
Ditto this 👆. What's the replacement for this now deprecated and seemingly non-existing feature which was previously available please? Thanks. |
Now that the official CloudFormation resource
AWS::CertificateManager::Certificate
(CDK'sCertificate
construct) supports DNS validation we do not want to recommend using theDnsValidatedCertificate
construct.The
DnsValidatedCertificate
construct uses CloudFormation custom resources to perform the certificate creation and this creates a lot of maintenance burden on our team (see the list of linked issues). Currently the primary use case for usingDnsValidatedCertificate
overCertificate
is for cross region use cases. For this use case I have updated the README to have our suggested solution.The example in the README is tested in this integration test
fixes #8934, #2914, #20698, #17349, #15217, #14519
All Submissions:
Adding new Unconventional Dependencies:
New Features
yarn integ
to deploy the infrastructure and generate the snapshot (i.e.yarn integ
without--dry-run
)?By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license