Skip to content

Commit

Permalink
feat(aws-codedeploy): Deployment Configuration Construct.
Browse files Browse the repository at this point in the history
Part of the work on a AWS Construct Library for CodeDeploy.
  • Loading branch information
skinny85 committed Aug 31, 2018
1 parent feae63c commit 21deb67
Show file tree
Hide file tree
Showing 6 changed files with 233 additions and 2 deletions.
32 changes: 32 additions & 0 deletions packages/@aws-cdk/aws-codedeploy/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,38 @@ const deploymentGroup = codedeploy.ServerDeploymentGroupRef.import(this, 'Existi
});
```

### Deployment Configurations

You can also pass a Deployment Configuration when creating the Deployment Group:

```ts
const deploymentGroup = new codedeploy.ServerDeploymentGroup(this, 'CodeDeployDeploymentGroup', {
deploymentConfiguration: codedeploy.PredefinedServerDeploymentConfiguration.AllAtOnce,
});
```

The default Deployment Configuration is `PredefinedServerDeploymentConfiguration.OneAtATime`.

You can also create a custom Deployment Configuration:

```ts
const deploymentConfiguration = new codedeploy.CustomServerDeploymentConfiguration(this, 'DeploymentConfiguration', {
deploymentConfigurationName: 'MyDeploymentConfiguration', // optional property
minimumHealthyHosts: { // required property
representation: codedeploy.HostsRepresentation.PERCENT,
value: 75,
},
});
```

Or import an existing one:

```ts
const deploymentConfiguration = codedeploy.CustomServerDeploymentConfigurationRef.import(this, 'ExistingDeploymentConfiguration', {
deploymentConfigurationName: new codedeploy.DeploymentConfigurationName('MyExistingDeploymentConfiguration'),
});
```

### Use in CodePipeline

This module also contains an Action that allows you to use CodeDeploy with AWS CodePipeline.
Expand Down
155 changes: 155 additions & 0 deletions packages/@aws-cdk/aws-codedeploy/lib/deployment-configuration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
import cdk = require('@aws-cdk/cdk');
import { cloudformation } from './codedeploy.generated';

export class DeploymentConfigurationName extends cdk.CloudFormationToken {}

export class DeploymentConfigurationArn extends cdk.Arn {}

/**
* Represents a Deployment Configuration for an EC2/on-premise Deployment Group.
*/
export interface ServerDeploymentConfiguration {
readonly deploymentConfigurationName: DeploymentConfigurationName;
readonly deploymentConfigurationArn: DeploymentConfigurationArn;
}

/**
* Pre-defined Deployment Configurations for an EC2/on-premise Deployment Group.
*
* @see https://docs.aws.amazon.com/codedeploy/latest/userguide/deployment-configurations.html#deployment-configuration-server
* @see #OneAtATime
* @see #HalfAtATime
* @see #AllAtOnce
*/
export class PredefinedServerDeploymentConfiguration implements ServerDeploymentConfiguration {
public static readonly OneAtATime = new PredefinedServerDeploymentConfiguration('CodeDeployDefault.OneAtATime');
public static readonly HalfAtATime = new PredefinedServerDeploymentConfiguration('CodeDeployDefault.HalfAtATime');
public static readonly AllAtOnce = new PredefinedServerDeploymentConfiguration('CodeDeployDefault.AllAtOnce');

public readonly deploymentConfigurationName: DeploymentConfigurationName;
public readonly deploymentConfigurationArn: DeploymentConfigurationArn;

private constructor(deploymentConfigurationName: string) {
this.deploymentConfigurationName = new DeploymentConfigurationName(deploymentConfigurationName);
this.deploymentConfigurationArn = deploymentConfigurationName2Arn(this.deploymentConfigurationName);
}
}

export interface CustomServerDeploymentConfigurationRefProps {
/**
* The physical, human-readable name of the custom CodeDeploy EC2/on-premise Deployment Configuration
* that we are referencing.
*/
readonly deploymentConfigurationName: DeploymentConfigurationName;
}

/**
* Reference to a custom Deployment Configuration for an EC2/on-premise Deployment Group.
*/
export abstract class CustomServerDeploymentConfigurationRef extends cdk.Construct
implements ServerDeploymentConfiguration {
/**
* Import a custom Deployment Configuration for 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 custom Deployment Configuration
* @returns a Construct representing a reference to an existing custom Deployment Configuration
*/
public static import(parent: cdk.Construct, id: string, props: CustomServerDeploymentConfigurationRefProps):
CustomServerDeploymentConfigurationRef {
return new ImportedCustomServerDeploymentConfigurationRef(parent, id, props);
}

public abstract readonly deploymentConfigurationName: DeploymentConfigurationName;
public abstract readonly deploymentConfigurationArn: DeploymentConfigurationArn;

public export(): CustomServerDeploymentConfigurationRefProps {
return {
deploymentConfigurationName: new cdk.Output(this, 'DeploymentConfigurationName', {
value: this.deploymentConfigurationName,
}).makeImportValue(),
};
}
}

class ImportedCustomServerDeploymentConfigurationRef extends CustomServerDeploymentConfigurationRef {
public readonly deploymentConfigurationName: DeploymentConfigurationName;
public readonly deploymentConfigurationArn: DeploymentConfigurationArn;

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

this.deploymentConfigurationName = props.deploymentConfigurationName;
this.deploymentConfigurationArn = deploymentConfigurationName2Arn(this.deploymentConfigurationName);
}
}

/**
* The possible representations of a healthy-host value -
* either percent-based, or an absolute number.
*/
export enum HostsRepresentation {
NUMBER = 'HOST_COUNT',
PERCENTAGE = 'FLEET_PERCENT'
}

export interface MinimumHealthyHosts {
readonly representation: HostsRepresentation;

readonly value: number;
}

/**
* Construction properties of {@link CustomServerDeploymentConfiguration}.
*/
export interface CustomServerDeploymentConfigurationProps {
/**
* The physical, human-readable name of the Deployment Configuration.
*
* @default a name will be auto-generated
*/
deploymentConfigurationName?: string;

/**
* The minimum healhty hosts setting for this EC2/on-premise Deployment Configuration.
*/
minimumHealthyHosts: MinimumHealthyHosts;
}

/**
* A custom Deployment Configuration for an EC2/on-premise Deployment Group.
*/
export class CustomServerDeploymentConfiguration extends CustomServerDeploymentConfigurationRef {
public readonly deploymentConfigurationName: DeploymentConfigurationName;
public readonly deploymentConfigurationArn: DeploymentConfigurationArn;
public readonly minimumHealthyHosts: MinimumHealthyHosts;

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

this.minimumHealthyHosts = props.minimumHealthyHosts;

const resource = new cloudformation.DeploymentConfigResource(this, 'Resource', {
deploymentConfigName: props.deploymentConfigurationName,
minimumHealthyHosts: {
type: this.minimumHealthyHosts.representation.toString(),
value: this.minimumHealthyHosts.value,
},
});

this.deploymentConfigurationName = resource.ref;
this.deploymentConfigurationArn = deploymentConfigurationName2Arn(this.deploymentConfigurationName);
}
}

function deploymentConfigurationName2Arn(deploymentConfigurationName: DeploymentConfigurationName):
DeploymentConfigurationArn {
return cdk.Arn.fromComponents({
service: 'codedeploy',
resource: 'deploymentconfig',
resourceName: deploymentConfigurationName,
sep: ':',
});
}
27 changes: 25 additions & 2 deletions packages/@aws-cdk/aws-codedeploy/lib/deployment-group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ 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';
import { PredefinedServerDeploymentConfiguration, ServerDeploymentConfiguration } from "./deployment-configuration";

export class DeploymentGroupArn extends cdk.Arn {}

Expand All @@ -23,6 +24,13 @@ export interface ServerDeploymentGroupRefProps {
* that we are referencing.
*/
deploymentGroupName: DeploymentGroupName;

/**
* The Deployment Configuration this Deployment Group uses.
*
* @default PredefinedServerDeploymentConfiguration#OneAtATime
*/
deploymentConfiguration?: ServerDeploymentConfiguration;
}

/**
Expand Down Expand Up @@ -52,6 +60,12 @@ export abstract class ServerDeploymentGroupRef extends cdk.Construct {
public abstract readonly application: ServerApplicationRef;
public abstract readonly deploymentGroupName: DeploymentGroupName;
public abstract readonly deploymentGroupArn: DeploymentGroupArn;
public readonly deploymentConfiguration: ServerDeploymentConfiguration;

constructor(parent: cdk.Construct, id: string, deploymentConfiguration?: ServerDeploymentConfiguration) {
super(parent, id);
this.deploymentConfiguration = deploymentConfiguration || PredefinedServerDeploymentConfiguration.OneAtATime;
}

public export(): ServerDeploymentGroupRefProps {
return {
Expand All @@ -69,7 +83,7 @@ class ImportedServerDeploymentGroupRef extends ServerDeploymentGroupRef {
public readonly deploymentGroupArn: DeploymentGroupArn;

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

this.application = props.application;
this.deploymentGroupName = props.deploymentGroupName;
Expand Down Expand Up @@ -100,6 +114,13 @@ export interface ServerDeploymentGroupProps {
* @default an auto-generated name will be used
*/
deploymentGroupName?: string;

/**
* The EC2/on-premise Deployment Configuration to use for this Deployment Group.
*
* @default PredefinedServerDeploymentConfiguration#OneAtATime
*/
deploymentConfiguration?: ServerDeploymentConfiguration;
}

/**
Expand All @@ -112,7 +133,7 @@ export class ServerDeploymentGroup extends ServerDeploymentGroupRef {
public readonly deploymentGroupName: DeploymentGroupName;

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

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

Expand All @@ -125,6 +146,8 @@ export class ServerDeploymentGroup extends ServerDeploymentGroupRef {
applicationName: this.application.applicationName,
deploymentGroupName: props && props.deploymentGroupName,
serviceRoleArn: this.role.roleArn,
deploymentConfigName: props && props.deploymentConfiguration &&
props.deploymentConfiguration.deploymentConfigurationName,
});

this.deploymentGroupName = resource.ref;
Expand Down
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 './application';
export * from './deployment-configuration';
export * from './deployment-group';
export * from './pipeline-action';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@
"ComputePlatform": "Server"
}
},
"CustomDeployConfig52EEBC13": {
"Type": "AWS::CodeDeploy::DeploymentConfig",
"Properties": {
"MinimumHealthyHosts": {
"Type": "HOST_COUNT",
"Value": 0
}
}
},
"CodeDeployGroupRole1D304F7A": {
"Type": "AWS::IAM::Role",
"Properties": {
Expand Down Expand Up @@ -39,6 +48,9 @@
"Arn"
]
},
"DeploymentConfigName": {
"Ref": "CustomDeployConfig52EEBC13"
},
"DeploymentGroupName": "IntegTestDeploymentGroup"
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,17 @@ const application = new codedeploy.ServerApplication(stack, 'CodeDeployApplicati
applicationName: 'IntegTestDeployApp',
});

const deploymentConfiguration = new codedeploy.CustomServerDeploymentConfiguration(stack, 'CustomDeployConfig', {
minimumHealthyHosts: {
representation: codedeploy.HostsRepresentation.NUMBER,
value: 0,
},
});

new codedeploy.ServerDeploymentGroup(stack, 'CodeDeployGroup', {
application,
deploymentGroupName: 'IntegTestDeploymentGroup',
deploymentConfiguration,
});

const bucket = new s3.Bucket(stack, 'CodeDeployPipelineIntegTest', {
Expand Down

0 comments on commit 21deb67

Please sign in to comment.