Skip to content

Commit

Permalink
aws-cdk-acm: Initial external release
Browse files Browse the repository at this point in the history
Co-authored-by: Rico Huijbers <huijbers@amazon.com>
  • Loading branch information
Elad Ben-Israel and Rico Huijbers committed May 30, 2018
1 parent 0847a43 commit 284177d
Show file tree
Hide file tree
Showing 14 changed files with 21,002 additions and 0 deletions.
5 changes: 5 additions & 0 deletions packages/aws-cdk-acm/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
*.js
tsconfig.json
*.js.map
*.d.ts
dist
57 changes: 57 additions & 0 deletions packages/aws-cdk-acm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
## AWS Certificate Manager Construct Library

This package provides Constructs for provisioning and referencing certificates which
can be used in CloudFront and ELB.

### Validation

If certificates are created as part of a CloudFormation run, the
CloudFormation provisioning will not complete until domain ownership for the
certificate is completed. For email validation, this involves receiving an
email on one of a number of predefined domains and following the instructions
in the email. The email addresses use will be:

* admin@domain.com
* administrator@domain.com
* hostmaster@domain.com
* postmaster@domain.com
* webmaster@domain.com

DNS validation is possible in ACM, but is not currently available in CloudFormation.
A Custom Resource will be developed for this, but is not currently available.

Because of these blocks, it's probably better to provision your certificates either in a separate
stack from your main service, or provision them manually. In both cases, you'll import the
certificate into your stack afterwards.

### Provisioning

Provision a new certificate by creating an instance of `Certificate`. Email validation will be sent
to `example.com`:

```ts
const certificate = new Certificate(this, 'Certificate', {
domainName: 'test.example.com'
});
```

### Importing

Import a certificate either manually, if you know the ARN:

```ts
const certificate = Certificate.import(this, 'Certificate', {
certificteArn: new Arn("arn:aws:...")
});
```

Or use exporting and importing mechanisms between stacks:

```ts
const certRef = certStack.certificate.export();

const certificate = Certificate.import(this, 'Certificate', certRef);
```

> We should probably also make a Custom Resource that can looks up the certificate ARN
> by domain name by querying ACM.
53 changes: 53 additions & 0 deletions packages/aws-cdk-acm/lib/certificate-ref.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { Arn, Construct, Output } from "aws-cdk";

/**
* Represents the ARN of a certificate
*/
export class CertificateArn extends Arn {
}

/**
* Interface for certificate-like objects
*/
export abstract class CertificateRef extends Construct {
/**
* Import a certificate
*/
public static import(parent: Construct, name: string, props: CertificateRefProps) {
return new ImportedCertificate(parent, name, props);
}

public abstract readonly certificateArn: CertificateArn;

/**
* Export this certificate from the stack
*/
public export(): CertificateRefProps {
return {
certificateArn: new Output(this, 'Arn', { value: this.certificateArn }).makeImportValue()
};
}
}

/**
* A Certificate that has been imported from another stack
*/
class ImportedCertificate extends CertificateRef {
public readonly certificateArn: CertificateArn;

constructor(parent: Construct, name: string, props: CertificateRefProps) {
super(parent, name);

this.certificateArn = props.certificateArn;
}
}

/**
* Reference to an existing Certificate
*/
export interface CertificateRefProps {
/**
* The certificate's ARN
*/
certificateArn: CertificateArn;
}
84 changes: 84 additions & 0 deletions packages/aws-cdk-acm/lib/certificate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { Construct } from 'aws-cdk';
import { certificatemanager } from 'aws-cdk-resources';
import { CertificateArn, CertificateRef } from './certificate-ref';
import { apexDomain } from './util';

/**
* Properties for your certificate
*/
export interface CertificateProps {
/**
* Fully-qualified domain name to request a certificate for.
*
* May contain wildcards, such as ``*.domain.com``.
*/
domainName: string;

/**
* Alternative domain names on your certificate.
*
* Use this to register alternative domain names that represent the same site.
*/
subjectAlternativeNames?: string[];

/**
* What validation domain to use for every requested domain.
*
* Has to be a superdomain of the requested domain.
*
* @default Apex domain is used for every domain that's not overridden.
*/
validationDomains?: {[domainName: string]: string};
}

/**
* A certificate managed by Amazon Certificate Manager
*
* IMPORTANT: if you are creating a certificate as part of your stack, the stack
* will not complete creating until you read and follow the instructions in the
* email that you will receive.
*
* ACM will send validation emails to the following addresses:
*
* admin@domain.com
* administrator@domain.com
* hostmaster@domain.com
* postmaster@domain.com
* webmaster@domain.com
*
* For every domain that you register.
*/
export class Certificate extends CertificateRef {
/**
* The certificate's ARN
*/
public readonly certificateArn: CertificateArn;

constructor(parent: Construct, name: string, props: CertificateProps) {
super(parent, name);

const allDomainNames = [props.domainName].concat(props.subjectAlternativeNames || []);

const cert = new certificatemanager.CertificateResource(this, 'Resource', {
domainName: props.domainName,
subjectAlternativeNames: props.subjectAlternativeNames,
domainValidationOptions: allDomainNames.map(domainValidationOption),
});

this.certificateArn = cert.ref;

/**
* Return the domain validation options for the given domain
*
* Closes over props.
*/
function domainValidationOption(domainName: string): certificatemanager.CertificateResource.DomainValidationOptionProperty {
const overrideDomain = props.validationDomains && props.validationDomains[domainName];
return {
domainName,
validationDomain: overrideDomain || apexDomain(domainName)
};
}
}

}
2 changes: 2 additions & 0 deletions packages/aws-cdk-acm/lib/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './certificate';
export * from './certificate-ref';
Loading

0 comments on commit 284177d

Please sign in to comment.