(aws_certificate_manager): ACM Certificate deletion fails with "ResourceInUseException" when used by API Gateway Custom Domain
- Dominant language
- TypeScript
- Stars
- 12.9k
- Forks
- 4.6k
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 83
Description
### Describe the bug
When destroying a CDK stack that contains an ACM Certificate used by an API Gateway Custom Domain, the deletion fails with `ResourceInUseException:
Certificate is in use` even though the Custom Domain should be deleted first.
This occurs because AWS doesn't immediately release the certificate association after the Custom Domain is deleted - there's an eventual consistency delay. CloudFormation then attempts to delete the certificate and fails.
### What We Tried
- Adding explicit dependency: customDomain.node.addDependency(certificate) - Does not work
- The dependency ensures CloudFormation deletes the Custom Domain first, but AWS doesn't immediately release the certificate association
### Regression Issue
- [x] Select this option if this issue appears to be a regression.
### Last Known Working CDK Library Version
_No response_
### Expected Behavior
Stack should destroy successfully, with the Custom Domain deleted before the Certificate.
### Current Behavior
Stack enters DELETE_FAILED state because the certificate is still reported as "in use" by AWS even after the Custom Domain resource has been deleted.
### Reproduction Steps
1. Deploy the minimal reproduction stack below
2. Run `cdk destroy --force`
3. Observe the deletion failure
```typescript
import * as cdk from 'aws-cdk-lib';
import { aws_certificatemanager, aws_route53, Stack, StackProps } from 'aws-cdk-lib';
import * as apigateway from 'aws-cdk-lib/aws-apigateway';
import { Construct } from 'constructs';
export class CertDeletionTestStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
const domain = 'example.com'; // Replace with your domain
const hostedZone = aws_route53.HostedZone.fromLookup(this, 'HostedZone', {
domainName: domain,
});
const domainName = `cert-test.${domain}`;
const certificate = new aws_certificatemanager.Certificate(this, 'Certificate', {
domainName,
validation: aws_certificatemanager.CertificateValidation.fromDns(hostedZone),
});
const api = new apigateway.RestApi(this, 'TestApi', {
restApiName: 'cert-deletion-test-api',
});
api.root.addMethod('GET', new apigateway.MockIntegration({}));
const customDomain = new apigateway.DomainName(this, 'CustomDomain', {
domainName,
certificate,
});
// This does NOT fix the issue - the problem is AWS-level eventual consistency
customDomain.node.addDependency(certificate);
customDomain.addApiMapping(api.deploymentStage);
}
}
const app = new cdk.App();
new CertDeletionTestStack(app, 'cert-deletion-test', {
env: {
account: process.env.CDK_DEFAULT_ACCOUNT,
region: 'eu-west-1',
},
});
```
```
Error Message
cert-deletion-test: destroy failed ToolkitError: The stack named cert-deletion-test is in a failed state. You may need to delete it from the AWS
console : DELETE_FAILED (The following resource(s) failed to delete: [CertificateXXXXXXXX]. ): Certificate
arn:aws:acm:eu-west-1:XXXXXXXXXXXX:certificate/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX in account XXXXXXXXXXXX is in use. (Service:
AWSCertificateManager; Status Code: 400; Error Code: ResourceInUseException; Request ID: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX; Proxy: null)
```
### Possible Solution
_No response_
### Additional Information/Context
This didn't use to be an issue, something changed around ~Oct 30th with CDK or AWS and we started to see this
### AWS CDK Library version (aws-cdk-lib)
2.231.0
### AWS CDK CLI version
2.1027.0 (build 5fc1b13)
### Node.js Version
22
### OS
macOS 26.1
### Language
TypeScript
### Language Version
_No response_
### Other information
_No response_
Contributor guide
Research direction
Start by reproducing the failure with the provided TypeScript stack, then inspect the aws_certificatemanager.Certificate and apigateway.DomainName entry points involved in deletion ordering. A complete fix should allow cdk destroy to delete the custom domain and subsequently remove the certificate without ResourceInUseException.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws, typescript
- Domain
- cloud, infrastructure
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100