Skip to content
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(codedeploy): Model ECS deployment resources and pipeline action #4600

Merged
merged 5 commits into from
Oct 25, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions packages/@aws-cdk/aws-codedeploy/lib/ecs/application.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { Construct, IResource, Resource } from '@aws-cdk/core';
import { CfnApplication } from "../codedeploy.generated";
import { arnForApplication } from "../utils";

/**
* Represents a reference to a CodeDeploy Application deploying to Amazon ECS.
*
* If you're managing the Application alongside the rest of your CDK resources,
* use the {@link EcsApplication} class.
*
* If you want to reference an already existing Application,
* or one defined in a different CDK Stack,
* use the {@link EcsApplication#fromEcsApplicationName} method.
*/
export interface IEcsApplication extends IResource {
/** @attribute */
readonly applicationArn: string;

/** @attribute */
readonly applicationName: string;
}

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

/**
* A CodeDeploy Application that deploys to an Amazon ECS service.
*
* @resource AWS::CodeDeploy::Application
*/
export class EcsApplication extends Resource implements IEcsApplication {
/**
* Import an Application defined either outside the CDK, or in a different CDK Stack.
*
* @param scope the parent Construct for this new Construct
* @param id the logical ID of this new Construct
* @param ecsApplicationName the name of the application to import
* @returns a Construct representing a reference to an existing Application
*/
public static fromEcsApplicationName(scope: Construct, id: string, ecsApplicationName: string): IEcsApplication {
class Import extends Resource implements IEcsApplication {
public applicationArn = arnForApplication(ecsApplicationName);
public applicationName = ecsApplicationName;
}

return new Import(scope, id);
}

public readonly applicationArn: string;
public readonly applicationName: string;

constructor(scope: Construct, id: string, props: EcsApplicationProps = {}) {
super(scope, id, {
physicalName: props.applicationName,
});

const resource = new CfnApplication(this, 'Resource', {
applicationName: this.physicalName,
computePlatform: 'ECS'
clareliguori marked this conversation as resolved.
Show resolved Hide resolved
});

this.applicationName = this.getResourceNameAttribute(resource.ref);
this.applicationArn = this.getResourceArnAttribute(arnForApplication(resource.ref), {
service: 'codedeploy',
resource: 'application',
resourceName: this.physicalName,
sep: ':',
});
}
}
65 changes: 65 additions & 0 deletions packages/@aws-cdk/aws-codedeploy/lib/ecs/deployment-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import cdk = require('@aws-cdk/core');
import { arnForDeploymentConfig } from '../utils';

/**
* The Deployment Configuration of an ECS Deployment Group.
* The default, pre-defined Configurations are available as constants on the {@link EcsDeploymentConfig} class
* (for example, `EcsDeploymentConfig.AllAtOnce`).
*
* Note: CloudFormation does not currently support creating custom ECS configs outside
* of using a custom resource. You can import custom deployment config created outside the
* CDK or via a custom resource with {@link EcsDeploymentConfig#import}.
*/
export interface IEcsDeploymentConfig {
readonly deploymentConfigName: string;
readonly deploymentConfigArn: string;
}

/**
* Properties of a reference to a CodeDeploy ECS Deployment Configuration.
*
* @see EcsDeploymentConfig#import
*/
export interface EcsDeploymentConfigImportProps {
/**
* The physical, human-readable name of the custom CodeDeploy ECS Deployment Configuration
* that we are referencing.
*/
readonly deploymentConfigName: string;
}

/**
* A custom Deployment Configuration for an ECS Deployment Group.
*
* Note: This class currently stands as namespaced container of the default configurations
* until CloudFormation supports custom ECS Deployment Configs. Until then it is closed
* (private constructor) and does not extend {@link cdk.Construct}
*
* @resource AWS::CodeDeploy::DeploymentConfig
*/
export class EcsDeploymentConfig {
public static readonly ALL_AT_ONCE = deploymentConfig('CodeDeployDefault.ECSAllAtOnce');

/**
* Import a custom Deployment Configuration for an ECS Deployment Group defined outside the CDK.
*
* @param _scope the parent Construct for this new Construct
* @param _id the logical ID of this new Construct
* @param props the properties of the referenced custom Deployment Configuration
* @returns a Construct representing a reference to an existing custom Deployment Configuration
*/
public static import(_scope: cdk.Construct, _id: string, props: EcsDeploymentConfigImportProps): IEcsDeploymentConfig {
clareliguori marked this conversation as resolved.
Show resolved Hide resolved
return deploymentConfig(props.deploymentConfigName);
}

private constructor() {
// nothing to do until CFN supports custom ECS deployment configurations
}
}

function deploymentConfig(name: string): IEcsDeploymentConfig {
return {
deploymentConfigName: name,
deploymentConfigArn: arnForDeploymentConfig(name)
clareliguori marked this conversation as resolved.
Show resolved Hide resolved
};
}
102 changes: 102 additions & 0 deletions packages/@aws-cdk/aws-codedeploy/lib/ecs/deployment-group.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import cdk = require('@aws-cdk/core');

import { arnForDeploymentGroup } from '../utils';
import { IEcsApplication } from './application';
import { EcsDeploymentConfig, IEcsDeploymentConfig } from './deployment-config';

/**
* Interface for an ECS deployment group.
*/
export interface IEcsDeploymentGroup extends cdk.IResource {
/**
* The reference to the CodeDeploy ECS Application that this Deployment Group belongs to.
*/
readonly application: IEcsApplication;

/**
* The physical name of the CodeDeploy Deployment Group.
* @attribute
*/
readonly deploymentGroupName: string;

/**
* The ARN of this Deployment Group.
* @attribute
*/
readonly deploymentGroupArn: string;

/**
* The Deployment Configuration this Group uses.
*/
readonly deploymentConfig: IEcsDeploymentConfig;
}

/**
* Note: This class currently stands as a namespaced container for importing an ECS
skinny85 marked this conversation as resolved.
Show resolved Hide resolved
* Deployment Group defined outside the CDK app until CloudFormation supports provisioning
* ECS Deployment Groups. Until then it is closed (private constructor) and does not
* extend {@link cdk.Construct}.
*
* @resource AWS::CodeDeploy::DeploymentGroup
*/
export class EcsDeploymentGroup {
/**
* Import an ECS Deployment Group defined outside the CDK app.
*
* @param scope the parent Construct for this new Construct
* @param id the logical ID of this new Construct
* @param attrs the properties of the referenced Deployment Group
* @returns a Construct representing a reference to an existing Deployment Group
*/
public static fromEcsDeploymentGroupAttributes(
scope: cdk.Construct,
id: string,
attrs: EcsDeploymentGroupAttributes): IEcsDeploymentGroup {
return new ImportedEcsDeploymentGroup(scope, id, attrs);
}

private constructor() {
// nothing to do until CFN supports ECS deployment groups
}
}

/**
* Properties of a reference to a CodeDeploy ECS Deployment Group.
*
* @see EcsDeploymentGroup#fromEcsDeploymentGroupAttributes
*/
export interface EcsDeploymentGroupAttributes {
/**
* The reference to the CodeDeploy ECS Application
* that this Deployment Group belongs to.
*/
readonly application: IEcsApplication;

/**
* The physical, human-readable name of the CodeDeploy ECS Deployment Group
* that we are referencing.
*/
readonly deploymentGroupName: string;

/**
* The Deployment Configuration this Deployment Group uses.
*
* @default EcsDeploymentConfig.ALL_AT_ONCE
*/
readonly deploymentConfig?: IEcsDeploymentConfig;
}

class ImportedEcsDeploymentGroup extends cdk.Resource implements IEcsDeploymentGroup {
public readonly application: IEcsApplication;
public readonly deploymentGroupName: string;
public readonly deploymentGroupArn: string;
public readonly deploymentConfig: IEcsDeploymentConfig;

constructor(scope: cdk.Construct, id: string, props: EcsDeploymentGroupAttributes) {
super(scope, id);
this.application = props.application;
this.deploymentGroupName = props.deploymentGroupName;
this.deploymentGroupArn = arnForDeploymentGroup(props.application.applicationName, props.deploymentGroupName);
this.deploymentConfig = props.deploymentConfig || EcsDeploymentConfig.ALL_AT_ONCE;
}
}
3 changes: 3 additions & 0 deletions packages/@aws-cdk/aws-codedeploy/lib/ecs/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './application';
export * from './deployment-config';
export * from './deployment-group';
1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-codedeploy/lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './rollback-config';
export * from './ecs';
export * from './lambda';
export * from './server';

Expand Down
28 changes: 28 additions & 0 deletions packages/@aws-cdk/aws-codedeploy/test/ecs/test.application.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { expect, haveResource } from '@aws-cdk/assert';
import cdk = require('@aws-cdk/core');
import { Test } from 'nodeunit';
import codedeploy = require('../../lib');

export = {
"CodeDeploy ECS Application": {
"can be created"(test: Test) {
const stack = new cdk.Stack();
new codedeploy.EcsApplication(stack, 'MyApp');
expect(stack).to(haveResource('AWS::CodeDeploy::Application', {
ComputePlatform: 'ECS'
clareliguori marked this conversation as resolved.
Show resolved Hide resolved
}));
test.done();
},
"can be created with explicit name"(test: Test) {
const stack = new cdk.Stack();
new codedeploy.EcsApplication(stack, 'MyApp', {
applicationName: 'my-name',
});
expect(stack).to(haveResource('AWS::CodeDeploy::Application', {
ApplicationName: 'my-name',
ComputePlatform: 'ECS'
clareliguori marked this conversation as resolved.
Show resolved Hide resolved
}));
test.done();
},
}
};
clareliguori marked this conversation as resolved.
Show resolved Hide resolved
24 changes: 24 additions & 0 deletions packages/@aws-cdk/aws-codedeploy/test/ecs/test.deployment-group.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import cdk = require('@aws-cdk/core');
import { Test } from 'nodeunit';
import codedeploy = require('../../lib');
import { EcsDeploymentConfig } from '../../lib';

export = {
"CodeDeploy ECS DeploymentGroup": {
'imported with fromEcsDeploymentGroupAttributes': {
'defaults the Deployment Config to AllAtOnce'(test: Test) {
const stack = new cdk.Stack();

const ecsApp = codedeploy.EcsApplication.fromEcsApplicationName(stack, 'EA', 'EcsApplication');
const importedGroup = codedeploy.EcsDeploymentGroup.fromEcsDeploymentGroupAttributes(stack, 'EDG', {
application: ecsApp,
deploymentGroupName: 'EcsDeploymentGroup',
});

test.equal(importedGroup.deploymentConfig, EcsDeploymentConfig.ALL_AT_ONCE);

test.done();
},
},
},
};
Loading