Skip to content
This repository was archived by the owner on Jul 16, 2024. It is now read-only.

Commit e118f41

Browse files
authored
chore(deploy): add click to deploy (#520)
* add CdkDeployer stack * set build status in the construct variable * package lambda code for codebuild
1 parent 042d589 commit e118f41

File tree

15 files changed

+2536
-46
lines changed

15 files changed

+2536
-46
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,5 @@ core/.github/*
3131
.idea
3232
.vscode
3333
*.iml
34+
35+
core/tmp.yaml

core/API.md

Lines changed: 1097 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/src/common/cdk-deployer-build.ts

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: MIT-0
3+
4+
// workaround to get a Lambda function with inline code and packaged into the ARA library
5+
// We need inline code to ensure it's deployable via a CloudFormation template
6+
// TODO modify the PreBundledFunction to allow for inline Lambda in addtion to asset based Lambda
7+
export const startBuild = "const respond = async function(event, context, responseStatus, responseData, physicalResourceId, noEcho) {\n return new Promise((resolve, reject) => {\n var responseBody = JSON.stringify({\n Status: responseStatus,\n Reason: \"See the details in CloudWatch Log Stream: \" + context.logGroupName + \" \" + context.logStreamName,\n PhysicalResourceId: physicalResourceId || context.logStreamName,\n StackId: event.StackId,\n RequestId: event.RequestId,\n LogicalResourceId: event.LogicalResourceId,\n NoEcho: noEcho || false,\n Data: responseData\n });\n \n console.log(\"Response body:\", responseBody);\n \n var https = require(\"https\");\n var url = require(\"url\");\n \n var parsedUrl = url.parse(event.ResponseURL);\n var options = {\n hostname: parsedUrl.hostname,\n port: 443,\n path: parsedUrl.path,\n method: \"PUT\",\n headers: {\n \"content-type\": \"\",\n \"content-length\": responseBody.length\n }\n };\n \n var request = https.request(options, function(response) {\n console.log(\"Status code: \" + response.statusCode);\n console.log(\"Status message: \" + response.statusMessage);\n resolve();\n });\n \n request.on(\"error\", function(error) {\n console.log(\"respond(..) failed executing https.request(..): \" + error);\n resolve();\n });\n \n request.write(responseBody);\n request.end();\n });\n};\n\nconst AWS = require('aws-sdk');\n\nexports.handler = async function (event, context) {\n console.log(JSON.stringify(event, null, 4));\n try {\n const projectName = event.ResourceProperties.ProjectName;\n const codebuild = new AWS.CodeBuild();\n \n console.log(`Starting new build of project ${projectName}`);\n \n const { build } = await codebuild.startBuild({\n projectName,\n // Pass CFN related parameters through the build for extraction by the\n // completion handler.\n buildspecOverride: event.RequestType === 'Delete' ? \n `\nversion: 0.2\nenv:\n variables:\n CFN_RESPONSE_URL: CFN_RESPONSE_URL_NOT_SET\n CFN_STACK_ID: CFN_STACK_ID_NOT_SET\n CFN_REQUEST_ID: CFN_REQUEST_ID_NOT_SET\n CFN_LOGICAL_RESOURCE_ID: CFN_LOGICAL_RESOURCE_ID_NOT_SET\nphases:\n pre_build:\n on-failure: ABORT\n commands:\n - cd $CODEBUILD_SRC_DIR/$CDK_APP_LOCATION\n - npm install -g aws-cdk && sudo apt-get install python3 && python -m\n ensurepip --upgrade && python -m pip install --upgrade pip && python -m\n pip install -r requirements.txt\n - \"export AWS_ACCOUNT_ID=$(echo $CODEBUILD_BUILD_ARN | cut -d: -f5)\"\n - 'echo \"AWS_ACCOUNT_ID: $AWS_ACCOUNT_ID\"'\n - cdk bootstrap aws://$AWS_ACCOUNT_ID/$AWS_REGION\n build:\n on-failure: ABORT\n commands:\n - \"export AWS_ACCOUNT_ID=$(echo $CODEBUILD_BUILD_ARN | cut -d: -f5)\"\n - 'echo \"AWS_ACCOUNT_ID: $AWS_ACCOUNT_ID\"'\n - cdk destroy --force --all --require-approval never\n `\n :\n `\nversion: 0.2\nenv:\n variables:\n CFN_RESPONSE_URL: CFN_RESPONSE_URL_NOT_SET\n CFN_STACK_ID: CFN_STACK_ID_NOT_SET\n CFN_REQUEST_ID: CFN_REQUEST_ID_NOT_SET\n CFN_LOGICAL_RESOURCE_ID: CFN_LOGICAL_RESOURCE_ID_NOT_SET\n PARAMETERS: PARAMETERS_NOT_SET\n STACKNAME: STACKNAME_NOT_SET\nphases:\n pre_build:\n on-failure: ABORT\n commands:\n - cd $CODEBUILD_SRC_DIR/$CDK_APP_LOCATION\n - npm install -g aws-cdk && sudo apt-get install python3 && python -m\n ensurepip --upgrade && python -m pip install --upgrade pip && python -m\n pip install -r requirements.txt\n - \"export AWS_ACCOUNT_ID=$(echo $CODEBUILD_BUILD_ARN | cut -d: -f5)\"\n - 'echo \"AWS_ACCOUNT_ID: $AWS_ACCOUNT_ID\"'\n - cdk bootstrap aws://$AWS_ACCOUNT_ID/$AWS_REGION\n build:\n on-failure: ABORT\n commands:\n - \"export AWS_ACCOUNT_ID=$(echo $CODEBUILD_BUILD_ARN | cut -d: -f5)\"\n - 'echo \"AWS_ACCOUNT_ID: $AWS_ACCOUNT_ID\"'\n - cdk deploy $STACKNAME $PARAMETERS --require-approval=never\n `,\n environmentVariablesOverride: [\n {\n name: 'CFN_RESPONSE_URL',\n value: event.ResponseURL\n },\n {\n name: 'CFN_STACK_ID',\n value: event.StackId\n },\n {\n name: 'CFN_REQUEST_ID',\n value: event.RequestId\n },\n {\n name: 'CFN_LOGICAL_RESOURCE_ID',\n value: event.LogicalResourceId\n },\n {\n name: 'BUILD_ROLE_ARN',\n value: event.ResourceProperties.BuildRoleArn\n }\n ]\n }).promise();\n console.log(`Build id ${build.id} started - resource completion handled by EventBridge`);\n } catch(error) {\n console.error(error);\n await respond(event, context, 'FAILED', { Error: error });\n }\n};"
8+
9+
export const reportBuild = `
10+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
11+
// SPDX-License-Identifier: MIT-0
12+
13+
const respond = async function(event, context, responseStatus, responseData, physicalResourceId, noEcho) {
14+
return new Promise((resolve, reject) => {
15+
var responseBody = JSON.stringify({
16+
Status: responseStatus,
17+
Reason: "See the details in CloudWatch Log Stream: " + context.logGroupName + " " + context.logStreamName,
18+
PhysicalResourceId: physicalResourceId || context.logStreamName,
19+
StackId: event.StackId,
20+
RequestId: event.RequestId,
21+
LogicalResourceId: event.LogicalResourceId,
22+
NoEcho: noEcho || false,
23+
Data: responseData
24+
});
25+
26+
console.log("Response body:\
27+
", responseBody);
28+
29+
var https = require("https");
30+
var url = require("url");
31+
32+
var parsedUrl = url.parse(event.ResponseURL);
33+
var options = {
34+
hostname: parsedUrl.hostname,
35+
port: 443,
36+
path: parsedUrl.path,
37+
method: "PUT",
38+
headers: {
39+
"content-type": "",
40+
"content-length": responseBody.length
41+
}
42+
};
43+
44+
var request = https.request(options, function(response) {
45+
console.log("Status code: " + response.statusCode);
46+
console.log("Status message: " + response.statusMessage);
47+
resolve();
48+
});
49+
50+
request.on("error", function(error) {
51+
console.log("respond(..) failed executing https.request(..): " + error);
52+
resolve();
53+
});
54+
55+
request.write(responseBody);
56+
request.end();
57+
});
58+
};
59+
60+
const AWS = require('aws-sdk');
61+
62+
exports.handler = async function (event, context) {
63+
console.log(JSON.stringify(event, null, 4));
64+
65+
const projectName = event['detail']['project-name'];
66+
67+
const codebuild = new AWS.CodeBuild();
68+
69+
const buildId = event['detail']['build-id'];
70+
const { builds } = await codebuild.batchGetBuilds({
71+
ids: [ buildId ]
72+
}).promise();
73+
74+
console.log(JSON.stringify(builds, null, 4));
75+
76+
const build = builds[0];
77+
// Fetch the CFN resource and response parameters from the build environment.
78+
const environment = {};
79+
build.environment.environmentVariables.forEach(e => environment[e.name] = e.value);
80+
81+
const response = {
82+
ResponseURL: environment.CFN_RESPONSE_URL,
83+
StackId: environment.CFN_STACK_ID,
84+
LogicalResourceId: environment.CFN_LOGICAL_RESOURCE_ID,
85+
RequestId: environment.CFN_REQUEST_ID
86+
};
87+
88+
if (event['detail']['build-status'] === 'SUCCEEDED') {
89+
await respond(response, context, 'SUCCESS', { BuildStatus: 'SUCCESS'}, 'build');
90+
} else {
91+
await respond(response, context, 'FAILED', { Error: 'Build failed' });
92+
}
93+
};
94+
`

0 commit comments

Comments
 (0)