Skip to content

Instantly share code, notes, and snippets.

@jewelsjacobs
Created August 15, 2019 20:24
Show Gist options
  • Select an option

  • Save jewelsjacobs/7262100a2f45e6b68659b70edacc64cf to your computer and use it in GitHub Desktop.

Select an option

Save jewelsjacobs/7262100a2f45e6b68659b70edacc64cf to your computer and use it in GitHub Desktop.
Pipeline with Github Stage status
import cdk = require('@aws-cdk/core');
import codepipeline = require('@aws-cdk/aws-codepipeline');
import cpActions = require('@aws-cdk/aws-codepipeline-actions');
import codebuild = require('@aws-cdk/aws-codebuild');
import { AwsCustomResource } from '@aws-cdk/custom-resources';
import iam = require('@aws-cdk/aws-iam');
import ec2 = require('@aws-cdk/aws-ec2');
import { GithubStatus } from './github-status';
const capitalize = require('lodash.capitalize');
export interface PipelineStackProps extends cdk.StackProps {
serviceStack: string; // names of service stack,
config: {
nodeEnv: string;
s3Bucket: string;
appType: string;
appName: string;
githubOwner: string;
githubRepo: string;
githubBranch: string;
domain: string;
subDomain: string;
websiteIndexDocument: string;
websiteErrorDocument: string;
source: string;
removalPolicy: string;
}
}
export class PipelineStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props: PipelineStackProps) {
super(scope, id, props);
const {
nodeEnv,
s3Bucket,
githubOwner,
appName,
appType,
githubRepo,
githubBranch,
domain,
subDomain,
websiteIndexDocument,
websiteErrorDocument,
source,
removalPolicy,
} = props.config;
// creates context for account and region
ec2.Vpc.fromLookup(this, 'VPC', {
isDefault: true
});
// Put github token in Secrets Manager before CDK is deployed as a CF template
// using the AWS SDK createSecret API:
// https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/SecretsManager.html#createSecret-property
const getGithubSecret = new AwsCustomResource(this, 'CreateSecret', {
onUpdate: { // will also be called for a CREATE event
service: 'SecretsManager',
action: 'describeSecret',
parameters: {
SecretId: 'TOKENS/PIPELINE/GithubToken'
},
physicalResourceId: Date.now().toString() // Update physical id to always fetch the latest version
}
});
const gitHubSecretArn = `${getGithubSecret.getData("ARN")}` as string;
/**
* Github source
*/
const sourceOutput = new codepipeline.Artifact();
const sourceAction = new cpActions.GitHubSourceAction({
actionName: 'SourceAction',
owner: githubOwner,
repo: githubRepo,
branch: githubBranch,
oauthToken: cdk.SecretValue.secretsManager(gitHubSecretArn),
output: sourceOutput
});
/**
* Building cdn files
*/
const buildProject = new codebuild.PipelineProject(this, 'AppProject', {
environment: {
buildImage: codebuild.LinuxBuildImage.UBUNTU_14_04_NODEJS_10_14_1
},
environmentVariables: {
NODE_ENV: { value: nodeEnv }
}
});
const cdkCode = new codepipeline.Artifact();
const buildAction = new cpActions.CodeBuildAction({
actionName: 'BuildAction',
project: buildProject,
input: sourceOutput,
outputs: [cdkCode],
});
buildProject.addToRolePolicy(new iam.PolicyStatement({
resources: [ '*' ],
actions: [ '*' ]
}));
/**
* Deploying Cloudfront
*/
const deployProject = new codebuild.PipelineProject(this, 'InfrastructureProject', {
environment: {
buildImage: codebuild.LinuxBuildImage.UBUNTU_14_04_NODEJS_10_14_1
},
environmentVariables: {
ACCOUNT_FROM_CONTEXT: { value: this.account },
REGION_FROM_CONTEXT: { value: this.region },
S3_BUCKET: { value: s3Bucket },
BUCKET_REMOVAL_POLICY: { value: removalPolicy },
NODE_ENV: { value: nodeEnv },
SUBDOMAIN: { value: subDomain },
SOURCE_DIRECTORY: { value: source },
DOMAIN: { value: domain },
INDEX_PAGE: { value: websiteIndexDocument },
ERROR_PAGE: { value: websiteErrorDocument },
SERVICE_STACK: { value: props.serviceStack },
ACM_CERT_REF: {
value: `/${capitalize(nodeEnv)}/${appName}/${appType}/certificateArn`,
type: codebuild.BuildEnvironmentVariableType.PARAMETER_STORE
},
}
});
const deployAction = new cpActions.CodeBuildAction({
actionName: 'deployAction',
project: deployProject,
input: cdkCode
});
deployProject.addToRolePolicy(new iam.PolicyStatement({
resources: [ '*' ],
actions: [ '*' ]
}));
/**
* Pipeline
*/
const pipeline = new codepipeline.Pipeline(this, 'Pipeline', {
restartExecutionOnUpdate: true
});
pipeline.addStage({
stageName: 'Source',
actions: [sourceAction],
});
const buildStage = pipeline.addStage({
stageName: 'Build',
actions: [buildAction],
});
new GithubStatus(this, 'GithubStatusBuild', {
stage: buildStage,
gitHubSecretArn
})
pipeline.addStage({
stageName: 'Deploy',
actions: [deployAction],
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment