Skip to content

Commit

Permalink
feat: allow inclusion of image copy to pipeline
Browse files Browse the repository at this point in the history
  • Loading branch information
Hi-Fi committed Sep 13, 2022
1 parent fbeeee1 commit 4a720e2
Show file tree
Hide file tree
Showing 4 changed files with 981 additions and 18 deletions.
2 changes: 2 additions & 0 deletions API.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ new ECRDeployment(scope: Construct, id: string, props: ECRDeploymentProps)
* **environment** (<code>Map<string, string></code>) The environment variable to set. __*Optional*__
* **memoryLimit** (<code>number</code>) The amount of memory (in MiB) to allocate to the AWS Lambda function which replicates the files from the CDK bucket to the destination bucket. __*Default*__: 512
* **role** (<code>[aws_iam.IRole](#aws-cdk-lib-aws-iam-irole)</code>) Execution role associated with this function. __*Default*__: A role is automatically created
* **stage** (<code>[aws_codepipeline.IStage](#aws-cdk-lib-aws-codepipeline-istage)</code>) Stage to include lambda to. __*Optional*__
* **vpc** (<code>[aws_ec2.IVpc](#aws-cdk-lib-aws-ec2-ivpc)</code>) The VPC network to place the deployment lambda handler in. __*Default*__: None
* **vpcSubnets** (<code>[aws_ec2.SubnetSelection](#aws-cdk-lib-aws-ec2-subnetselection)</code>) Where in the VPC to place the deployment lambda handler. __*Default*__: the Vpc default strategy if not specified

Expand Down Expand Up @@ -150,6 +151,7 @@ Name | Type | Description
**environment**? | <code>Map<string, string></code> | The environment variable to set.<br/>__*Optional*__
**memoryLimit**? | <code>number</code> | The amount of memory (in MiB) to allocate to the AWS Lambda function which replicates the files from the CDK bucket to the destination bucket.<br/>__*Default*__: 512
**role**? | <code>[aws_iam.IRole](#aws-cdk-lib-aws-iam-irole)</code> | Execution role associated with this function.<br/>__*Default*__: A role is automatically created
**stage**? | <code>[aws_codepipeline.IStage](#aws-cdk-lib-aws-codepipeline-istage)</code> | Stage to include lambda to.<br/>__*Optional*__
**vpc**? | <code>[aws_ec2.IVpc](#aws-cdk-lib-aws-ec2-ivpc)</code> | The VPC network to place the deployment lambda handler in.<br/>__*Default*__: None
**vpcSubnets**? | <code>[aws_ec2.SubnetSelection](#aws-cdk-lib-aws-ec2-subnetselection)</code> | Where in the VPC to place the deployment lambda handler.<br/>__*Default*__: the Vpc default strategy if not specified

Expand Down
50 changes: 36 additions & 14 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import * as child_process from 'child_process';
import * as path from 'path';
import {
aws_codepipeline as codepipeline,
aws_codepipeline_actions as codepipeline_actions,
aws_ec2 as ec2,
aws_iam as iam,
aws_lambda as lambda,
Expand All @@ -14,7 +16,6 @@ import {
Token,
DockerImage,
} from 'aws-cdk-lib';
import { PolicyStatement, AddToPrincipalPolicyResult } from 'aws-cdk-lib/aws-iam';
import { Construct } from 'constructs';
import { shouldUsePrebuiltLambda } from './config';

Expand Down Expand Up @@ -77,6 +78,11 @@ export interface ECRDeploymentProps {
* The environment variable to set
*/
readonly environment?: { [key: string]: string };

/**
* Stage to include lambda to. If this is set, lambda is invoked in pipeline instead of custom resource.
*/
readonly stage?: codepipeline.IStage;
}

export interface IImageName {
Expand Down Expand Up @@ -200,7 +206,9 @@ export class ECRDeployment extends Construct {
constructor(scope: Construct, id: string, props: ECRDeploymentProps) {
super(scope, id);
const memoryLimit = props.memoryLimit ?? 512;
this.handler = new lambda.SingletonFunction(this, 'CustomResourceHandler', {
const lambdaId = props.stage ? 'ImageCopyHandler' : 'CustomResourceHandler';
const lambdaPurpose = props.stage ? 'ImageCopy' : 'Custom::CDKECRDeployment';
this.handler = new lambda.SingletonFunction(this, lambdaId, {
uuid: this.renderSingletonUuid(memoryLimit),
code: lambda.Code.fromAsset(path.join(__dirname, '../lambda'), {
bundling: {
Expand Down Expand Up @@ -254,7 +262,7 @@ export class ECRDeployment extends Construct {
runtime: lambda.Runtime.GO_1_X,
handler: 'main',
environment: props.environment,
lambdaPurpose: 'Custom::CDKECRDeployment',
lambdaPurpose,
timeout: Duration.minutes(15),
role: props.role,
memorySize: memoryLimit,
Expand Down Expand Up @@ -298,19 +306,33 @@ export class ECRDeployment extends Construct {
props.src.creds?.secretManager?.secret.grantRead(handlerRole);
props.dest.creds?.secretManager?.secret.grantRead(handlerRole);

new CustomResource(this, 'CustomResource', {
serviceToken: this.handler.functionArn,
resourceType: 'Custom::CDKBucketDeployment',
properties: {
SrcImage: props.src.uri,
SrcCreds: formatCredentials(props.src.creds),
DestImage: props.dest.uri,
DestCreds: formatCredentials(props.dest.creds),
},
});
if (props.stage) {
props.stage.addAction(
new codepipeline_actions.LambdaInvokeAction({
lambda: this.handler,
actionName: lambdaPurpose,
userParameters: {
SrcImage: props.src.uri,
SrcCreds: formatCredentials(props.src.creds),
DestImage: props.dest.uri,
DestCreds: formatCredentials(props.dest.creds),
},
}));
} else {
new CustomResource(this, 'CustomResource', {
serviceToken: this.handler.functionArn,
resourceType: lambdaPurpose,
properties: {
SrcImage: props.src.uri,
SrcCreds: formatCredentials(props.src.creds),
DestImage: props.dest.uri,
DestCreds: formatCredentials(props.dest.creds),
},
});
}
}

public addToPrincipalPolicy(statement: PolicyStatement): AddToPrincipalPolicyResult {
public addToPrincipalPolicy(statement: iam.PolicyStatement): iam.AddToPrincipalPolicyResult {
const handlerRole = this.handler.role;
if (!handlerRole) { throw new Error('lambda.SingletonFunction should have created a Role'); }

Expand Down
Loading

0 comments on commit 4a720e2

Please sign in to comment.