Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(certificatemanager): requesting private certificates issued by P…
…rivate Certificate Authority (#16315) Support requesting private certificates issued by Private Certificate Authority. Similar to the existing construct named `Certificate`, a new construct `PrivateCertificate` was introduced. There are two main differences between them. `PrivateCertificate` has an additional property `certificateAuthority` to specify the Private certificate authority (CA) that will be used to issue the certificate. The validation options are removed because no validation is necessary for private certificates. Closes #10076. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
- Loading branch information
Showing
5 changed files
with
188 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
66 changes: 66 additions & 0 deletions
66
packages/@aws-cdk/aws-certificatemanager/lib/private-certificate.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import * as acmpca from '@aws-cdk/aws-acmpca'; | ||
import { Construct } from 'constructs'; | ||
import { ICertificate } from './certificate'; | ||
import { CertificateBase } from './certificate-base'; | ||
import { CfnCertificate } from './certificatemanager.generated'; | ||
|
||
/** | ||
* Properties for your private certificate | ||
*/ | ||
export interface PrivateCertificateProps { | ||
/** | ||
* Fully-qualified domain name to request a private certificate for. | ||
* | ||
* May contain wildcards, such as ``*.domain.com``. | ||
*/ | ||
readonly domainName: string; | ||
|
||
/** | ||
* Alternative domain names on your private certificate. | ||
* | ||
* Use this to register alternative domain names that represent the same site. | ||
* | ||
* @default - No additional FQDNs will be included as alternative domain names. | ||
*/ | ||
readonly subjectAlternativeNames?: string[]; | ||
|
||
/** | ||
* Private certificate authority (CA) that will be used to issue the certificate. | ||
*/ | ||
readonly certificateAuthority: acmpca.ICertificateAuthority; | ||
} | ||
|
||
/** | ||
* A private certificate managed by AWS Certificate Manager | ||
* | ||
* @resource AWS::CertificateManager::Certificate | ||
*/ | ||
export class PrivateCertificate extends CertificateBase implements ICertificate { | ||
/** | ||
* Import a certificate | ||
*/ | ||
public static fromCertificateArn(scope: Construct, id: string, certificateArn: string): ICertificate { | ||
class Import extends CertificateBase { | ||
public readonly certificateArn = certificateArn; | ||
} | ||
|
||
return new Import(scope, id); | ||
} | ||
|
||
/** | ||
* The certificate's ARN | ||
*/ | ||
public readonly certificateArn: string; | ||
|
||
constructor(scope: Construct, id: string, props: PrivateCertificateProps) { | ||
super(scope, id); | ||
|
||
const cert = new CfnCertificate(this, 'Resource', { | ||
domainName: props.domainName, | ||
subjectAlternativeNames: props.subjectAlternativeNames, | ||
certificateAuthorityArn: props.certificateAuthority.certificateAuthorityArn, | ||
}); | ||
|
||
this.certificateArn = cert.ref; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
102 changes: 102 additions & 0 deletions
102
packages/@aws-cdk/aws-certificatemanager/test/private-certificate.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
import '@aws-cdk/assert-internal/jest'; | ||
import * as acmpca from '@aws-cdk/aws-acmpca'; | ||
import { Duration, Lazy, Stack } from '@aws-cdk/core'; | ||
import { PrivateCertificate } from '../lib'; | ||
|
||
test('private certificate authority', () => { | ||
const stack = new Stack(); | ||
|
||
new PrivateCertificate(stack, 'Certificate', { | ||
domainName: 'test.example.com', | ||
certificateAuthority: acmpca.CertificateAuthority.fromCertificateAuthorityArn(stack, 'CA', | ||
'arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/023077d8-2bfa-4eb0-8f22-05c96deade77'), | ||
}); | ||
|
||
expect(stack).toHaveResource('AWS::CertificateManager::Certificate', { | ||
DomainName: 'test.example.com', | ||
CertificateAuthorityArn: 'arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/023077d8-2bfa-4eb0-8f22-05c96deade77', | ||
}); | ||
}); | ||
|
||
test('private certificate authority with subjectAlternativeNames', () => { | ||
const stack = new Stack(); | ||
|
||
new PrivateCertificate(stack, 'Certificate', { | ||
domainName: 'test.example.com', | ||
subjectAlternativeNames: ['extra.example.com'], | ||
certificateAuthority: acmpca.CertificateAuthority.fromCertificateAuthorityArn(stack, 'CA', | ||
'arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/023077d8-2bfa-4eb0-8f22-05c96deade77'), | ||
}); | ||
|
||
expect(stack).toHaveResource('AWS::CertificateManager::Certificate', { | ||
DomainName: 'test.example.com', | ||
SubjectAlternativeNames: ['extra.example.com'], | ||
CertificateAuthorityArn: 'arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/023077d8-2bfa-4eb0-8f22-05c96deade77', | ||
}); | ||
}); | ||
|
||
test('private certificate authority with multiple subjectAlternativeNames', () => { | ||
const stack = new Stack(); | ||
|
||
new PrivateCertificate(stack, 'Certificate', { | ||
domainName: 'test.example.com', | ||
subjectAlternativeNames: ['*.test.example.com', '*.foo.test.example.com', 'bar.test.example.com'], | ||
certificateAuthority: acmpca.CertificateAuthority.fromCertificateAuthorityArn(stack, 'CA', | ||
'arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/023077d8-2bfa-4eb0-8f22-05c96deade77'), | ||
}); | ||
|
||
expect(stack).toHaveResource('AWS::CertificateManager::Certificate', { | ||
DomainName: 'test.example.com', | ||
SubjectAlternativeNames: ['*.test.example.com', '*.foo.test.example.com', 'bar.test.example.com'], | ||
CertificateAuthorityArn: 'arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/023077d8-2bfa-4eb0-8f22-05c96deade77', | ||
}); | ||
}); | ||
|
||
test('private certificate authority with tokens', () => { | ||
const stack = new Stack(); | ||
|
||
const certificateAuthority = Lazy.string({ | ||
produce: () => 'arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/023077d8-2bfa-4eb0-8f22-05c96deade77', | ||
}); | ||
|
||
const domainName = Lazy.string({ | ||
produce: () => 'test.example.com', | ||
}); | ||
|
||
const domainNameAlternative = Lazy.string({ | ||
produce: () => 'extra.example.com', | ||
}); | ||
|
||
new PrivateCertificate(stack, 'Certificate', { | ||
domainName, | ||
subjectAlternativeNames: [domainNameAlternative], | ||
certificateAuthority: acmpca.CertificateAuthority.fromCertificateAuthorityArn(stack, 'CA', certificateAuthority), | ||
}); | ||
|
||
expect(stack).toHaveResource('AWS::CertificateManager::Certificate', { | ||
DomainName: 'test.example.com', | ||
SubjectAlternativeNames: ['extra.example.com'], | ||
CertificateAuthorityArn: 'arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/023077d8-2bfa-4eb0-8f22-05c96deade77', | ||
}); | ||
}); | ||
|
||
test('metricDaysToExpiry', () => { | ||
const stack = new Stack(); | ||
|
||
const certificate = new PrivateCertificate(stack, 'Certificate', { | ||
domainName: 'test.example.com', | ||
certificateAuthority: acmpca.CertificateAuthority.fromCertificateAuthorityArn(stack, 'CA', | ||
'arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/023077d8-2bfa-4eb0-8f22-05c96deade77'), | ||
}); | ||
|
||
expect(stack.resolve(certificate.metricDaysToExpiry().toMetricConfig())).toEqual({ | ||
metricStat: { | ||
dimensions: [{ name: 'CertificateArn', value: stack.resolve(certificate.certificateArn) }], | ||
metricName: 'DaysToExpiry', | ||
namespace: 'AWS/CertificateManager', | ||
period: Duration.days(1), | ||
statistic: 'Minimum', | ||
}, | ||
renderingProperties: expect.anything(), | ||
}); | ||
}); |