Skip to content

Commit

Permalink
feat(aws-codedeploy): first classes for the CodeDeploy Construct Libr…
Browse files Browse the repository at this point in the history
…ary.

Includes ServerApplication and ServerDeploymentGroup.
  • Loading branch information
skinny85 committed Aug 29, 2018
1 parent 54c202a commit 1e0ffa7
Show file tree
Hide file tree
Showing 6 changed files with 306 additions and 18 deletions.
46 changes: 44 additions & 2 deletions packages/@aws-cdk/aws-codedeploy/README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,55 @@
## The CDK Construct Library for AWS CodeDeploy

### Applications

To create a new CodeDeploy Application that deploys to EC2/on-premise instances:

```ts
import codedeploy = require('@aws-cdk/aws-codedeploy');

const application = new codedeploy.ServerApplication(this, 'CodeDeployApplication', {
applicationName: 'MyApplication', // optional property
});
```

To import an already existing Application:

```ts
const application = codedeploy.ServerApplicationRef.import(this, 'ExistingCodeDeployApplication', {
applicationName: new codedeploy.ApplicationName('MyExistingApplication'),
});
```

### Deployment Groups

To create a new CodeDeploy Deployment Group that deploys to EC2/on-premise instances:

```ts
const deploymentGroup = new codedeploy.ServerDeploymentGroup(this, 'CodeDeployDeploymentGroup', {
application,
deploymentGroupName: 'MyDeploymentGroup',
});
```

All properties are optional - if you don't provide an Application,
one will be automatically created.

To import an already existing Deployment Group:

```ts
const deploymentGroup = codedeploy.ServerDeploymentGroupRef.import(this, 'ExistingCodeDeployDeploymentGroup', {
application,
deploymentGroupName: new codedeploy.DeploymentGroupName('MyExistingDeploymentGroup'),
});
```

### Use in CodePipeline

This module contains an Action that allows you to use CodeDeploy with AWS CodePipeline.
This module also contains an Action that allows you to use CodeDeploy with AWS CodePipeline.

Example:

```ts
import codedeploy = require('@aws-cdk/aws-codedeploy');
import codepipeline = require('@aws-cdk/aws-codepipeline');

const pipeline = new codepipeline.Pipeline(this, 'MyPipeline', {
Expand Down
106 changes: 106 additions & 0 deletions packages/@aws-cdk/aws-codedeploy/lib/application.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import cdk = require('@aws-cdk/cdk');
import { ApplicationName, cloudformation } from './codedeploy.generated';

export class ApplicationArn extends cdk.Arn {}

/**
* Properties of a reference to a CodeDeploy EC2/on-premise Application.
*
* @see ServerApplicationRef#import
* @see ServerApplicationRef#export
*/
export interface ServerApplicationRefProps {
/**
* The physical, human-readable name of the CodeDeploy EC2/on-premise Application we're referencing.
* The Application must be in the same account and region as the root Stack.
*/
applicationName: ApplicationName;
}

/**
* Represents a reference to a CodeDeploy Application deploying to EC2/on-premise instances.
*
* If you're managing the Application alongside the rest of your CDK resources,
* use the {@link ServerApplication} class.
*
* If you want to reference an already existing Application,
* or one defined in a different CDK Stack,
* use the {@link #import} method.
*/
export abstract class ServerApplicationRef extends cdk.Construct {
/**
* Import an Application defined either outside the CDK,
* or in a different CDK Stack and exported using the {@link #export} method.
*
* @param parent the parent Construct for this new Construct
* @param id the logical ID of this new Construct
* @param props the properties of the referenced Application
* @returns a Construct representing a reference to an existing Application
*/
public static import(parent: cdk.Construct, id: string, props: ServerApplicationRefProps): ServerApplicationRef {
return new ImportedServerApplicationRef(parent, id, props);
}

public abstract readonly applicationArn: ApplicationArn;

public abstract readonly applicationName: ApplicationName;

public export(): ServerApplicationRefProps {
return {
applicationName: new cdk.Output(this, 'ApplicationName', { value: this.applicationName }).makeImportValue(),
};
}
}

class ImportedServerApplicationRef extends ServerApplicationRef {
public readonly applicationArn: ApplicationArn;
public readonly applicationName: ApplicationName;

constructor(parent: cdk.Construct, id: string, props: ServerApplicationRefProps) {
super(parent, id);

this.applicationName = props.applicationName;
this.applicationArn = applicationName2Arn(this.applicationName);
}
}

/**
* Construction properties for {@link ServerApplication}.
*/
export interface ServerApplicationProps {
/**
* The physical, human-readable name of the CodeDeploy Application.
*
* @default an auto-generated name will be used
*/
applicationName?: string;
}

/**
* A CodeDeploy Application that deploys to EC2/on-premise instances.
*/
export class ServerApplication extends ServerApplicationRef {
public readonly applicationArn: ApplicationArn;
public readonly applicationName: ApplicationName;

constructor(parent: cdk.Construct, id: string, props?: ServerApplicationProps) {
super(parent, id);

const resource = new cloudformation.ApplicationResource(this, 'Resource', {
applicationName: props && props.applicationName,
computePlatform: 'Server',
});

this.applicationName = resource.ref;
this.applicationArn = applicationName2Arn(this.applicationName);
}
}

function applicationName2Arn(applicationName: ApplicationName): ApplicationArn {
return cdk.Arn.fromComponents({
service: 'codedeploy',
resource: 'application',
resourceName: applicationName,
sep: ':',
});
}
144 changes: 144 additions & 0 deletions packages/@aws-cdk/aws-codedeploy/lib/deployment-group.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import cdk = require("@aws-cdk/cdk");
import iam = require("../../aws-iam/lib/role");
import { ServerApplication, ServerApplicationRef } from "./application";
import { ApplicationName, cloudformation, DeploymentGroupName } from './codedeploy.generated';

export class DeploymentGroupArn extends cdk.Arn {}

/**
* Properties of a reference to a CodeDeploy EC2/on-premise Deployment Group.
*
* @see ServerDeploymentGroupRef#import
* @see ServerDeploymentGroupRef#export
*/
export interface ServerDeploymentGroupRefProps {
/**
* The reference to the CodeDeploy EC2/on-premise Application
* that this Deployment Group belongs to.
*/
application: ServerApplicationRef;

/**
* The physical, human-readable name of the CodeDeploy EC2/on-premise Deployment Group
* that we are referencing.
*/
deploymentGroupName: DeploymentGroupName;
}

/**
* Represents a reference to a CodeDeploy EC2/on-premise Deployment Group.
*
* If you're managing the Deployment Group alongside the rest of your CDK resources,
* use the {@link ServerDeploymentGroup} class.
*
* If you want to reference an already existing Deployment Group,
* or one defined in a different CDK Stack,
* use the {@link #import} method.
*/
export abstract class ServerDeploymentGroupRef extends cdk.Construct {
/**
* Import an EC2/on-premise Deployment Group defined either outside the CDK,
* or in a different CDK Stack and exported using the {@link #export} method.
*
* @param parent the parent Construct for this new Construct
* @param id the logical ID of this new Construct
* @param props the properties of the referenced Deployment Group
* @returns a Construct representing a reference to an existing Deployment Group
*/
public static import(parent: cdk.Construct, id: string, props: ServerDeploymentGroupRefProps): ServerDeploymentGroupRef {
return new ImportedServerDeploymentGroupRef(parent, id, props);
}

public abstract readonly application: ServerApplicationRef;
public abstract readonly deploymentGroupName: DeploymentGroupName;
public abstract readonly deploymentGroupArn: DeploymentGroupArn;

public export(): ServerDeploymentGroupRefProps {
return {
application: this.application,
deploymentGroupName: new cdk.Output(this, 'DeploymentGroupName', {
value: this.deploymentGroupName
}).makeImportValue(),
};
}
}

class ImportedServerDeploymentGroupRef extends ServerDeploymentGroupRef {
public readonly application: ServerApplicationRef;
public readonly deploymentGroupName: DeploymentGroupName;
public readonly deploymentGroupArn: DeploymentGroupArn;

constructor(parent: cdk.Construct, id: string, props: ServerDeploymentGroupRefProps) {
super(parent, id);

this.application = props.application;
this.deploymentGroupName = props.deploymentGroupName;
this.deploymentGroupArn = deploymentGroupName2Arn(props.application.applicationName,
props.deploymentGroupName);
}
}

/**
* Construction properties for {@link ServerDeploymentGroup}.
*/
export interface ServerDeploymentGroupProps {
/**
* The CodeDeploy EC2/on-premise Application this Deployment Group belongs to.
* If you don't provide one, a new Application will be created.
*/
application?: ServerApplicationRef;

/**
* The service Role of this Deployment Group.
* If you don't provide one, a new Role will be created.
*/
role?: iam.Role;

/**
* The physical, human-readable name of the CodeDeploy Deployment Group.
*
* @default an auto-generated name will be used
*/
deploymentGroupName?: string;
}

/**
* A CodeDeploy Deployment Group that deploys to EC2/on-premise instances.
*/
export class ServerDeploymentGroup extends ServerDeploymentGroupRef {
public readonly application: ServerApplicationRef;
public readonly role: iam.Role;
public readonly deploymentGroupArn: DeploymentGroupArn;
public readonly deploymentGroupName: DeploymentGroupName;

constructor(parent: cdk.Construct, id: string, props: ServerDeploymentGroupProps) {
super(parent, id);

this.application = props.application || new ServerApplication(this, 'Application');

this.role = props.role || new iam.Role(this, 'Role', {
assumedBy: new cdk.ServicePrincipal('codedeploy.amazonaws.com'),
managedPolicyArns: ['arn:aws:iam::aws:policy/service-role/AWSCodeDeployRole'],
});

const resource = new cloudformation.DeploymentGroupResource(this, 'Resource', {
applicationName: this.application.applicationName,
deploymentGroupName: props.deploymentGroupName,
serviceRoleArn: this.role.roleArn,
});

this.deploymentGroupName = resource.ref;
this.deploymentGroupArn = deploymentGroupName2Arn(this.application.applicationName,
this.deploymentGroupName);
}
}

function deploymentGroupName2Arn(applicationName: ApplicationName,
deploymentGroupName: DeploymentGroupName): DeploymentGroupArn {
return cdk.Arn.fromComponents({
service: 'codedeploy',
resource: 'deploymentgroup',
resourceName: new cdk.FnJoin('/', [applicationName, deploymentGroupName]),
sep: ':',
});
}
2 changes: 2 additions & 0 deletions packages/@aws-cdk/aws-codedeploy/lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export * from './application';
export * from './deployment-group';
export * from './pipeline-action';

// AWS::CodeDeploy CloudFormation Resources:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"Resources": {
"CodeDeployApplication": {
"CodeDeployApplicationE587C27C": {
"Type": "AWS::CodeDeploy::Application",
"Properties": {
"ApplicationName": "IntegTestDeployApp",
"ComputePlatform": "Server"
}
},
"CodeDeployGroupRole9EDBB624": {
"CodeDeployGroupRole1D304F7A": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
Expand All @@ -27,13 +27,15 @@
]
}
},
"CodeDeployGroup": {
"CodeDeployGroup58220FC8": {
"Type": "AWS::CodeDeploy::DeploymentGroup",
"Properties": {
"ApplicationName": "IntegTestDeployApp",
"ApplicationName": {
"Ref": "CodeDeployApplicationE587C27C"
},
"ServiceRoleArn": {
"Fn::GetAtt": [
"CodeDeployGroupRole9EDBB624",
"CodeDeployGroupRole1D304F7A",
"Arn"
]
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import codedeploy = require('@aws-cdk/aws-codedeploy');
import iam = require('@aws-cdk/aws-iam');
import s3 = require('@aws-cdk/aws-s3');
import cdk = require('@aws-cdk/cdk');
import codepipeline = require('../lib');
Expand All @@ -8,19 +7,12 @@ const app = new cdk.App(process.argv);

const stack = new cdk.Stack(app, 'aws-cdk-codepipeline-codedeploy');

new codedeploy.cloudformation.ApplicationResource(stack, 'CodeDeployApplication', {
const application = new codedeploy.ServerApplication(stack, 'CodeDeployApplication', {
applicationName: 'IntegTestDeployApp',
computePlatform: 'Server',
});

const deploymentGroupRole = new iam.Role(stack, 'CodeDeployGroupRole', {
assumedBy: new cdk.ServicePrincipal('codedeploy.amazonaws.com'),
managedPolicyArns: ['arn:aws:iam::aws:policy/service-role/AWSCodeDeployRole'],
});

new codedeploy.cloudformation.DeploymentGroupResource(stack, 'CodeDeployGroup', {
applicationName: 'IntegTestDeployApp',
serviceRoleArn: deploymentGroupRole.roleArn,
new codedeploy.ServerDeploymentGroup(stack, 'CodeDeployGroup', {
application,
deploymentGroupName: 'IntegTestDeploymentGroup',
});

Expand Down

0 comments on commit 1e0ffa7

Please sign in to comment.