Skip to content

Commit

Permalink
Merge pull request #58 from alinadima/cdk-pipeline
Browse files Browse the repository at this point in the history
  • Loading branch information
nateglims committed Aug 21, 2023
2 parents 8770abe + b8bc261 commit 0b34f85
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 5 deletions.
2 changes: 1 addition & 1 deletion demos-pipeline/example/bin/poky-pipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ new BuildImagePipelineStack(app, "BuildImagePipeline", {
/**
* Set up networking to allow us to securely attach EFS to our CodeBuild instances.
*/
const vpc = new PipelineNetworkStack(app, {
const vpc = new PipelineNetworkStack(app, {
...defaultProps,
});

Expand Down
76 changes: 73 additions & 3 deletions demos-pipeline/lib/lib/demo-pipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ import * as cdk from "aws-cdk-lib";
import { Construct } from "constructs";
import * as codepipeline from "aws-cdk-lib/aws-codepipeline";
import * as codepipeline_actions from "aws-cdk-lib/aws-codepipeline-actions";
import * as events from "aws-cdk-lib/aws-events";
import * as targets from "aws-cdk-lib/aws-events-targets";
import * as lambda from "aws-cdk-lib/aws-lambda";
import * as iam from "aws-cdk-lib/aws-iam";
import * as efs from "aws-cdk-lib/aws-efs";

import {
BuildSpec,
ComputeType,
Expand All @@ -10,7 +16,7 @@ import {
PipelineProject,
} from "aws-cdk-lib/aws-codebuild";
import { IRepository } from "aws-cdk-lib/aws-ecr";
import * as efs from "aws-cdk-lib/aws-efs";

import {
ISecurityGroup,
IVpc,
Expand All @@ -20,6 +26,7 @@ import {
} from "aws-cdk-lib/aws-ec2";
import { Bucket } from "aws-cdk-lib/aws-s3";
import { SourceRepo, DistributionKind } from "./constructs/source-repo";
import { CodeCommitTrigger } from "aws-cdk-lib/aws-codepipeline-actions";

Check warning on line 29 in demos-pipeline/lib/lib/demo-pipeline.ts

View workflow job for this annotation

GitHub Actions / Run-CDK-Tests (16.x, demos-pipeline/lib)

'CodeCommitTrigger' is defined but never used

Check warning on line 29 in demos-pipeline/lib/lib/demo-pipeline.ts

View workflow job for this annotation

GitHub Actions / Run-CDK-Tests (18.x, demos-pipeline/lib)

'CodeCommitTrigger' is defined but never used

Check warning on line 29 in demos-pipeline/lib/lib/demo-pipeline.ts

View workflow job for this annotation

GitHub Actions / Run-CDK-Tests (20.x, demos-pipeline/lib)

'CodeCommitTrigger' is defined but never used

/**
* Properties to allow customizing the build.
Expand Down Expand Up @@ -70,6 +77,7 @@ export class DemoPipelineStack extends cdk.Stack {

const sourceOutput = new codepipeline.Artifact();
const sourceAction = new codepipeline_actions.CodeCommitSourceAction({
// trigger: CodeCommitTrigger.NONE,
output: sourceOutput,
actionName: "Source",
repository: sourceRepo.repo,
Expand Down Expand Up @@ -121,15 +129,62 @@ export class DemoPipelineStack extends cdk.Stack {
versioned: true,
enforceSSL: true,
});

const artifactAction = new codepipeline_actions.S3DeployAction({
actionName: "Demo-Artifact",
input: buildOutput,
bucket: artifactBucket,
});

/** Here we create the logic to check for presence of ECR image on the CodePipeline automatic triggering upon resource creation,
* and stop the execution if the image does not exist. */
const fnOnPipelineCreate = new lambda.Function(
this,
"OSImageCheckOnStart",
{
runtime: lambda.Runtime.PYTHON_3_10,
handler: "index.handler",
code: lambda.Code.fromInline(`
import boto3
import json
ecr_client = boto3.client('ecr')
codepipeline_client = boto3.client('codepipeline')
def handler(event, context):
print("Received event: " + json.dumps(event, indent=2))
response = ecr_client.describe_images(repositoryName='${props.imageRepo.repositoryName}', filter={'tagStatus': 'TAGGED'})
for i in response['imageDetails']:
if '${props.imageTag}' in i['imageTags']:
break
else:
print('OS image not found. Stopping execution.')
response = codepipeline_client.stop_pipeline_execution(
pipelineName=event['detail']['pipeline'],
pipelineExecutionId=event['detail']['execution-id'],
abandon=True,
reason='OS image not found in ECR repository. Stopping pipeline until image is present.')
`),
}
);

const pipelineCreateRule = new events.Rule(this, "OnPipelineStartRule", {
eventPattern: {
detailType: ["CodePipeline Pipeline Execution State Change"],
source: ["aws.codepipeline"],
detail: {
state: ["STARTED"],
"execution-trigger": {
"trigger-type": ["CreatePipeline"],
},
},
},
});
pipelineCreateRule.addTarget(
new targets.LambdaFunction(fnOnPipelineCreate)
);

/** Now create the actual Pipeline */
new codepipeline.Pipeline(this, "DemoPipeline", {
const pipeline = new codepipeline.Pipeline(this, "DemoPipeline", {
restartExecutionOnUpdate: true,
stages: [
{
Expand All @@ -146,6 +201,21 @@ export class DemoPipelineStack extends cdk.Stack {
},
],
});

const stopPipelinePolicy = new iam.PolicyStatement({
actions: ["codepipeline:StopPipelineExecution"],
resources: [pipeline.pipelineArn],
});

const ecrPolicy = new iam.PolicyStatement({
actions: ["ecr:DescribeImages"],
resources: [props.imageRepo.repositoryArn],
});
fnOnPipelineCreate.role?.attachInlinePolicy(
new iam.Policy(this, "CheckOSAndStop", {
statements: [stopPipelinePolicy, ecrPolicy],
})
);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion demos-pipeline/lib/lib/network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export class PipelineNetworkStack extends cdk.Stack {
public readonly vpc: ec2.IVpc;

constructor(scope: Construct, props?: cdk.StackProps) {
super(scope, 'PipelineNetwork', props);
super(scope, "PipelineNetwork", props);

// We will create a VPC with 3 Private and Public subnets for AWS
// Resources that have network interfaces (e.g. Connecting and EFS
Expand Down

0 comments on commit 0b34f85

Please sign in to comment.