carlin 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +378 -0
- package/bin/carlin +2 -0
- package/dist/cli.js +250 -0
- package/dist/config.js +10 -0
- package/dist/deploy/addDefaults.cloudFormation.js +138 -0
- package/dist/deploy/baseStack/command.js +9 -0
- package/dist/deploy/baseStack/config.js +30 -0
- package/dist/deploy/baseStack/deployBaseStack.js +61 -0
- package/dist/deploy/baseStack/getBaseStackResource.js +26 -0
- package/dist/deploy/baseStack/getBucket.template.js +44 -0
- package/dist/deploy/baseStack/getLambdaImageBuilder.template.js +188 -0
- package/dist/deploy/baseStack/getLambdaLayerBuilder.template.js +140 -0
- package/dist/deploy/baseStack/getVpc.template.js +169 -0
- package/dist/deploy/cicd/cicd.template.js +872 -0
- package/dist/deploy/cicd/command.js +84 -0
- package/dist/deploy/cicd/config.js +7 -0
- package/dist/deploy/cicd/deployCicd.js +114 -0
- package/dist/deploy/cicd/ecsTaskReportCommand.js +53 -0
- package/dist/deploy/cicd/getCicdStackName.js +11 -0
- package/dist/deploy/cicd/getTriggerPipelineObjectKey.js +12 -0
- package/dist/deploy/cicd/lambdas/cicdApiV1.handler.js +124 -0
- package/dist/deploy/cicd/lambdas/ecsTaskReport.handler.js +79 -0
- package/dist/deploy/cicd/lambdas/executeTasks.js +91 -0
- package/dist/deploy/cicd/lambdas/getProcessEnvVariable.js +10 -0
- package/dist/deploy/cicd/lambdas/githubWebhooksApiV1.handler.js +143 -0
- package/dist/deploy/cicd/lambdas/index.js +11 -0
- package/dist/deploy/cicd/lambdas/pipelines.handler.js +154 -0
- package/dist/deploy/cicd/lambdas/putApprovalResultManualTask.js +52 -0
- package/dist/deploy/cicd/pipelines.js +52 -0
- package/dist/deploy/cloudFormation.core.js +286 -0
- package/dist/deploy/cloudFormation.js +201 -0
- package/dist/deploy/command.js +211 -0
- package/dist/deploy/lambda.js +177 -0
- package/dist/deploy/lambdaLayer/command.js +51 -0
- package/dist/deploy/lambdaLayer/deployLambdaLayer.js +142 -0
- package/dist/deploy/s3.js +167 -0
- package/dist/deploy/stackName.js +78 -0
- package/dist/deploy/staticApp/command.js +101 -0
- package/dist/deploy/staticApp/getOriginShieldRegion.js +30 -0
- package/dist/deploy/staticApp/staticApp.js +206 -0
- package/dist/deploy/staticApp/staticApp.template.js +874 -0
- package/dist/deploy/utils.js +31 -0
- package/dist/index.js +7 -0
- package/dist/utils/addGroupToOptions.js +11 -0
- package/dist/utils/buildLambdaFiles.js +99 -0
- package/dist/utils/cloudFormationTemplate.js +134 -0
- package/dist/utils/codeBuild.js +52 -0
- package/dist/utils/environmentVariables.js +11 -0
- package/dist/utils/exec.js +24 -0
- package/dist/utils/formatCode.js +30 -0
- package/dist/utils/getAwsAccountId.js +10 -0
- package/dist/utils/getCurrentBranch.js +35 -0
- package/dist/utils/getEnvironment.js +6 -0
- package/dist/utils/getIamPath.js +6 -0
- package/dist/utils/getProjectName.js +28 -0
- package/dist/utils/index.js +26 -0
- package/dist/utils/packageJson.js +46 -0
- package/dist/utils/readCloudFormationTemplate.js +35 -0
- package/dist/utils/readObjectFile.js +50 -0
- package/package.json +83 -0
package/dist/config.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CLOUDFRONT_REGION = exports.AWS_DEFAULT_REGION = exports.NAME = void 0;
|
|
4
|
+
exports.NAME = 'carlin';
|
|
5
|
+
exports.AWS_DEFAULT_REGION = 'us-east-1';
|
|
6
|
+
/**
|
|
7
|
+
* CloudFront triggers can be only in US East (N. Virginia) Region.
|
|
8
|
+
* https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-requirements-limits.html#lambda-requirements-cloudfront-triggers
|
|
9
|
+
*/
|
|
10
|
+
exports.CLOUDFRONT_REGION = 'us-east-1';
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.addDefaults = void 0;
|
|
4
|
+
const config_1 = require("../config");
|
|
5
|
+
const utils_1 = require("../utils");
|
|
6
|
+
const addDefaultsParametersAndTagsToParams = async (params) => {
|
|
7
|
+
const branchName = await utils_1.getCurrentBranch();
|
|
8
|
+
const environment = await utils_1.getEnvironment();
|
|
9
|
+
const packageName = await utils_1.getPackageName();
|
|
10
|
+
const packageVersion = await utils_1.getPackageVersion();
|
|
11
|
+
const projectName = await utils_1.getProjectName();
|
|
12
|
+
return {
|
|
13
|
+
...params,
|
|
14
|
+
Parameters: [
|
|
15
|
+
...(params.Parameters || []),
|
|
16
|
+
...(environment
|
|
17
|
+
? [{ ParameterKey: 'Environment', ParameterValue: environment }]
|
|
18
|
+
: []),
|
|
19
|
+
{ ParameterKey: 'Project', ParameterValue: projectName },
|
|
20
|
+
],
|
|
21
|
+
Tags: [
|
|
22
|
+
...(params.Tags || []),
|
|
23
|
+
{ Key: 'Branch', Value: branchName },
|
|
24
|
+
...(environment ? [{ Key: 'Environment', Value: environment }] : []),
|
|
25
|
+
{ Key: 'Package', Value: packageName },
|
|
26
|
+
{ Key: 'Project', Value: projectName },
|
|
27
|
+
{ Key: 'Version', Value: packageVersion },
|
|
28
|
+
].filter(({ Value }) => !!Value),
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
const addDefaultParametersToTemplate = async (template) => {
|
|
32
|
+
const [environment, projectName] = await Promise.all([
|
|
33
|
+
utils_1.getEnvironment(),
|
|
34
|
+
utils_1.getProjectName(),
|
|
35
|
+
]);
|
|
36
|
+
const newParameters = {
|
|
37
|
+
Project: { Default: projectName, Type: 'String' },
|
|
38
|
+
};
|
|
39
|
+
if (environment) {
|
|
40
|
+
newParameters.Environment = { Default: environment, Type: 'String' };
|
|
41
|
+
}
|
|
42
|
+
const newTemplate = {
|
|
43
|
+
...template,
|
|
44
|
+
Parameters: { ...newParameters, ...template.Parameters },
|
|
45
|
+
};
|
|
46
|
+
return newTemplate;
|
|
47
|
+
};
|
|
48
|
+
const addLogGroupToResources = (template) => {
|
|
49
|
+
const { Resources } = template;
|
|
50
|
+
const resourcesEntries = Object.entries(Resources);
|
|
51
|
+
resourcesEntries.forEach(([key, resource]) => {
|
|
52
|
+
if (['AWS::Lambda::Function', 'AWS::Serverless::Function'].includes(resource.Type)) {
|
|
53
|
+
/**
|
|
54
|
+
* Check if exist a resource on template whose LogGroupName
|
|
55
|
+
* Properties includes the Lambda logical id.
|
|
56
|
+
*/
|
|
57
|
+
const logGroup = resourcesEntries.find(([, resource2]) => {
|
|
58
|
+
var _a, _b;
|
|
59
|
+
const logGroupNameStr = JSON.stringify(((_b = (_a = resource2.Properties) === null || _a === void 0 ? void 0 : _a.LogGroupName) === null || _b === void 0 ? void 0 : _b['Fn::Join']) || '');
|
|
60
|
+
return logGroupNameStr.includes(key);
|
|
61
|
+
});
|
|
62
|
+
if (!logGroup) {
|
|
63
|
+
Resources[`${key}LogsLogGroup`] = {
|
|
64
|
+
Type: 'AWS::Logs::LogGroup',
|
|
65
|
+
DeletionPolicy: 'Delete',
|
|
66
|
+
Properties: {
|
|
67
|
+
LogGroupName: { 'Fn::Join': ['/', ['/aws/lambda', { Ref: key }]] },
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
return template;
|
|
74
|
+
};
|
|
75
|
+
const addEnvironmentsToLambdaResources = async (template) => {
|
|
76
|
+
const environment = utils_1.getEnvironment();
|
|
77
|
+
const { Resources } = template;
|
|
78
|
+
const resourcesEntries = Object.entries(Resources);
|
|
79
|
+
resourcesEntries.forEach(([, resource]) => {
|
|
80
|
+
if (resource.Type === 'AWS::Lambda::Function') {
|
|
81
|
+
const { Properties } = resource;
|
|
82
|
+
/**
|
|
83
|
+
* Lambda@Edege does not support environment variables.
|
|
84
|
+
* https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-requirements-limits.html#lambda-requirements-lambda-function-configuration
|
|
85
|
+
* Then every function that has "Lambda@Edge" in its description will not
|
|
86
|
+
* have the variables passed to Environment.Variables.
|
|
87
|
+
*/
|
|
88
|
+
if ((Properties.Description || '').includes('Lambda@Edge')) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
if (!environment) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (!Properties.Environment) {
|
|
95
|
+
Properties.Environment = {};
|
|
96
|
+
}
|
|
97
|
+
if (!Properties.Environment.Variables) {
|
|
98
|
+
Properties.Environment.Variables = {};
|
|
99
|
+
}
|
|
100
|
+
Properties.Environment.Variables.ENVIRONMENT = environment;
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
return template;
|
|
104
|
+
};
|
|
105
|
+
const addAppSyncApiOutputs = async (template) => {
|
|
106
|
+
const newTemplate = { ...template };
|
|
107
|
+
Object.entries(template.Resources).forEach(([key, resource]) => {
|
|
108
|
+
if (resource.Type === 'AWS::AppSync::GraphQLApi') {
|
|
109
|
+
newTemplate.Outputs = {
|
|
110
|
+
[key]: {
|
|
111
|
+
Description: `Automatically added by ${config_1.NAME}`,
|
|
112
|
+
Value: { 'Fn::GetAtt': [key, 'GraphQLUrl'] },
|
|
113
|
+
Export: {
|
|
114
|
+
Name: {
|
|
115
|
+
'Fn::Join': [':', [{ Ref: 'AWS::StackName' }, 'GraphQLApiUrl']],
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
...newTemplate.Outputs,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
return newTemplate;
|
|
124
|
+
};
|
|
125
|
+
const addDefaults = async ({ params, template, }) => {
|
|
126
|
+
const newTemplate = await [
|
|
127
|
+
addDefaultParametersToTemplate,
|
|
128
|
+
addLogGroupToResources,
|
|
129
|
+
addEnvironmentsToLambdaResources,
|
|
130
|
+
addAppSyncApiOutputs,
|
|
131
|
+
].reduce(async (acc, addFn) => addFn(await acc), Promise.resolve(template));
|
|
132
|
+
const response = {
|
|
133
|
+
params: await addDefaultsParametersAndTagsToParams(params),
|
|
134
|
+
template: newTemplate,
|
|
135
|
+
};
|
|
136
|
+
return response;
|
|
137
|
+
};
|
|
138
|
+
exports.addDefaults = addDefaults;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.deployBaseStackCommand = void 0;
|
|
4
|
+
const deployBaseStack_1 = require("./deployBaseStack");
|
|
5
|
+
exports.deployBaseStackCommand = {
|
|
6
|
+
command: 'base-stack',
|
|
7
|
+
describe: 'Create base resources.',
|
|
8
|
+
handler: deployBaseStack_1.deployBaseStack,
|
|
9
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BASE_STACK_VPC_PUBLIC_SUBNET_2_EXPORTED_NAME = exports.BASE_STACK_VPC_PUBLIC_SUBNET_1_EXPORTED_NAME = exports.BASE_STACK_VPC_PUBLIC_SUBNET_0_EXPORTED_NAME = exports.BASE_STACK_VPC_DEFAULT_SECURITY_GROUP_EXPORTED_NAME = exports.BASE_STACK_VPC_ID_EXPORTED_NAME = exports.BASE_STACK_LAMBDA_LAYER_BUILDER_LOGICAL_NAME = exports.BASE_STACK_LAMBDA_IMAGE_BUILDER_EXPORTED_NAME = exports.BASE_STACK_LAMBDA_IMAGE_BUILDER_LOGICAL_NAME = exports.BASE_STACK_BUCKET_NAME_EXPORTED_NAME = exports.BASE_STACK_BUCKET_LOGICAL_NAME = exports.BASE_STACK_BUCKET_TEMPLATES_FOLDER = exports.BASE_STACK_NAME = void 0;
|
|
4
|
+
const change_case_1 = require("change-case");
|
|
5
|
+
const config_1 = require("../../config");
|
|
6
|
+
const pascalCaseName = change_case_1.pascalCase(config_1.NAME);
|
|
7
|
+
exports.BASE_STACK_NAME = `${pascalCaseName}BaseStack`;
|
|
8
|
+
exports.BASE_STACK_BUCKET_TEMPLATES_FOLDER = 'cloudformation-templates';
|
|
9
|
+
/**
|
|
10
|
+
* S3 Bucket.
|
|
11
|
+
*/
|
|
12
|
+
exports.BASE_STACK_BUCKET_LOGICAL_NAME = `${pascalCaseName}Bucket`;
|
|
13
|
+
exports.BASE_STACK_BUCKET_NAME_EXPORTED_NAME = `${pascalCaseName}BucketNameExportedName`;
|
|
14
|
+
/**
|
|
15
|
+
* Lambda image builder.
|
|
16
|
+
*/
|
|
17
|
+
exports.BASE_STACK_LAMBDA_IMAGE_BUILDER_LOGICAL_NAME = `${pascalCaseName}LambdaImageBuilder`;
|
|
18
|
+
exports.BASE_STACK_LAMBDA_IMAGE_BUILDER_EXPORTED_NAME = `${pascalCaseName}LambdaImageBuilderExportedName`;
|
|
19
|
+
/**
|
|
20
|
+
* Lambda layer builder.
|
|
21
|
+
*/
|
|
22
|
+
exports.BASE_STACK_LAMBDA_LAYER_BUILDER_LOGICAL_NAME = `${pascalCaseName}LambdaLayerBuilder`;
|
|
23
|
+
/**
|
|
24
|
+
* VPC
|
|
25
|
+
*/
|
|
26
|
+
exports.BASE_STACK_VPC_ID_EXPORTED_NAME = `${pascalCaseName}VPCIDExportedName`;
|
|
27
|
+
exports.BASE_STACK_VPC_DEFAULT_SECURITY_GROUP_EXPORTED_NAME = `${pascalCaseName}DefaultSecurityGroupExportedName`;
|
|
28
|
+
exports.BASE_STACK_VPC_PUBLIC_SUBNET_0_EXPORTED_NAME = `${pascalCaseName}VPCPublicSubnet0ExportedName`;
|
|
29
|
+
exports.BASE_STACK_VPC_PUBLIC_SUBNET_1_EXPORTED_NAME = `${pascalCaseName}VPCPublicSubnet1ExportedName`;
|
|
30
|
+
exports.BASE_STACK_VPC_PUBLIC_SUBNET_2_EXPORTED_NAME = `${pascalCaseName}VPCPublicSubnet2ExportedName`;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.deployBaseStack = exports.baseStackTemplate = void 0;
|
|
7
|
+
const deepmerge_1 = __importDefault(require("deepmerge"));
|
|
8
|
+
const cloudFormation_core_1 = require("../cloudFormation.core");
|
|
9
|
+
const utils_1 = require("../utils");
|
|
10
|
+
const config_1 = require("./config");
|
|
11
|
+
const getBucket_template_1 = require("./getBucket.template");
|
|
12
|
+
const getLambdaImageBuilder_template_1 = require("./getLambdaImageBuilder.template");
|
|
13
|
+
const getLambdaLayerBuilder_template_1 = require("./getLambdaLayerBuilder.template");
|
|
14
|
+
const getVpc_template_1 = require("./getVpc.template");
|
|
15
|
+
const logPrefix = 'base-stack';
|
|
16
|
+
exports.baseStackTemplate = deepmerge_1.default.all([
|
|
17
|
+
getBucket_template_1.getBucketTemplate(),
|
|
18
|
+
getLambdaImageBuilder_template_1.getLambdaImageBuilderTemplate(),
|
|
19
|
+
getLambdaLayerBuilder_template_1.getLambdaLayerBuilderTemplate(),
|
|
20
|
+
getVpc_template_1.getVpcTemplate(),
|
|
21
|
+
]);
|
|
22
|
+
/**
|
|
23
|
+
* Base Stack is a set of auxiliary resources that will be used to help at the
|
|
24
|
+
* deployment time. The resources that will be created are listed below.
|
|
25
|
+
*
|
|
26
|
+
* - **S3 bucket**. Deployment may need an auxiliary bucket to succeed. For
|
|
27
|
+
* instance, to deploy resources that contain a
|
|
28
|
+
* [Lambda](https://carlin.ttoss.dev/docs/commands/deploy#lambda), we need a S3
|
|
29
|
+
* bucket to upload the zipped code. Or if the CloudFormation template has a
|
|
30
|
+
* size greater than [the limit](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cloudformation-limits.html),
|
|
31
|
+
* we need to upload the template to a S3 bucket in order to create/update the
|
|
32
|
+
* stack.
|
|
33
|
+
*
|
|
34
|
+
* - **Lambda Layer builder**. This resource is a CodeBuild project that is
|
|
35
|
+
* used to create Lambda Layers when [--lambda-externals](/docs/api-reference/deploy#lambda-externals)
|
|
36
|
+
* has values.
|
|
37
|
+
*
|
|
38
|
+
* - **Lambda Image builder**. This resource is a CodeBuild project that builds
|
|
39
|
+
* Docker Images if Lambda is going to use them.
|
|
40
|
+
*
|
|
41
|
+
* - **VPC**. This resource is used when some network infrastructure is
|
|
42
|
+
* required. For example, CICD needs a VPC to execute the [Fargate](https://aws.amazon.com/fargate/)
|
|
43
|
+
* operations.
|
|
44
|
+
*/
|
|
45
|
+
const deployBaseStack = async () => {
|
|
46
|
+
try {
|
|
47
|
+
const { stackName } = await utils_1.handleDeployInitialization({
|
|
48
|
+
logPrefix,
|
|
49
|
+
stackName: config_1.BASE_STACK_NAME,
|
|
50
|
+
});
|
|
51
|
+
await cloudFormation_core_1.deploy({
|
|
52
|
+
template: exports.baseStackTemplate,
|
|
53
|
+
params: { StackName: stackName },
|
|
54
|
+
terminationProtection: true,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
utils_1.handleDeployError({ error, logPrefix });
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
exports.deployBaseStack = deployBaseStack;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getBaseStackResource = exports.getBaseStackOutput = void 0;
|
|
4
|
+
const cloudFormation_core_1 = require("../cloudFormation.core");
|
|
5
|
+
const config_1 = require("./config");
|
|
6
|
+
const getBaseStackOutput = async (outputKey) => {
|
|
7
|
+
const output = await cloudFormation_core_1.getStackOutput({
|
|
8
|
+
stackName: config_1.BASE_STACK_NAME,
|
|
9
|
+
outputKey,
|
|
10
|
+
});
|
|
11
|
+
return output.OutputValue;
|
|
12
|
+
};
|
|
13
|
+
exports.getBaseStackOutput = getBaseStackOutput;
|
|
14
|
+
const resourcesKeys = {
|
|
15
|
+
BASE_STACK_BUCKET_LOGICAL_NAME: config_1.BASE_STACK_BUCKET_LOGICAL_NAME,
|
|
16
|
+
BASE_STACK_LAMBDA_IMAGE_BUILDER_LOGICAL_NAME: config_1.BASE_STACK_LAMBDA_IMAGE_BUILDER_LOGICAL_NAME,
|
|
17
|
+
BASE_STACK_LAMBDA_LAYER_BUILDER_LOGICAL_NAME: config_1.BASE_STACK_LAMBDA_LAYER_BUILDER_LOGICAL_NAME,
|
|
18
|
+
};
|
|
19
|
+
const resources = {};
|
|
20
|
+
const getBaseStackResource = async (resource) => {
|
|
21
|
+
if (!resources[resource]) {
|
|
22
|
+
resources[resource] = await exports.getBaseStackOutput(resourcesKeys[resource]);
|
|
23
|
+
}
|
|
24
|
+
return resources[resource];
|
|
25
|
+
};
|
|
26
|
+
exports.getBaseStackResource = getBaseStackResource;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getBucketTemplate = void 0;
|
|
4
|
+
const config_1 = require("./config");
|
|
5
|
+
const getBucketTemplate = () => ({
|
|
6
|
+
AWSTemplateFormatVersion: '2010-09-09',
|
|
7
|
+
Resources: {
|
|
8
|
+
[config_1.BASE_STACK_BUCKET_LOGICAL_NAME]: {
|
|
9
|
+
Type: 'AWS::S3::Bucket',
|
|
10
|
+
DeletionPolicy: 'Retain',
|
|
11
|
+
Properties: {
|
|
12
|
+
LifecycleConfiguration: {
|
|
13
|
+
Rules: [
|
|
14
|
+
{
|
|
15
|
+
ExpirationInDays: 1,
|
|
16
|
+
Prefix: config_1.BASE_STACK_BUCKET_TEMPLATES_FOLDER,
|
|
17
|
+
Status: 'Enabled',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
NoncurrentVersionExpirationInDays: 3,
|
|
21
|
+
Status: 'Enabled',
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
},
|
|
25
|
+
/**
|
|
26
|
+
* This is necessary because if we update Lambda code without change
|
|
27
|
+
* CloudFormation template, the Lambda will not be updated.
|
|
28
|
+
*/
|
|
29
|
+
VersioningConfiguration: {
|
|
30
|
+
Status: 'Enabled',
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
Outputs: {
|
|
36
|
+
[config_1.BASE_STACK_BUCKET_LOGICAL_NAME]: {
|
|
37
|
+
Value: { Ref: config_1.BASE_STACK_BUCKET_LOGICAL_NAME },
|
|
38
|
+
Export: {
|
|
39
|
+
Name: config_1.BASE_STACK_BUCKET_NAME_EXPORTED_NAME,
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
exports.getBucketTemplate = getBucketTemplate;
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getLambdaImageBuilderTemplate = void 0;
|
|
7
|
+
const js_yaml_1 = __importDefault(require("js-yaml"));
|
|
8
|
+
const utils_1 = require("../../utils");
|
|
9
|
+
const config_1 = require("./config");
|
|
10
|
+
const getLambdaImageBuilderTemplate = () => {
|
|
11
|
+
const CODE_BUILD_PROJECT_LOGS_LOGICAL_ID = 'CodeBuildProjectLogsLogGroup';
|
|
12
|
+
const CODE_BUILD_PROJECT_SERVICE_ROLE_LOGICAL_ID = 'ImageCodeBuildProjectIAMRole';
|
|
13
|
+
return {
|
|
14
|
+
AWSTemplateFormatVersion: '2010-09-09',
|
|
15
|
+
Resources: {
|
|
16
|
+
[CODE_BUILD_PROJECT_LOGS_LOGICAL_ID]: {
|
|
17
|
+
Type: 'AWS::Logs::LogGroup',
|
|
18
|
+
DeletionPolicy: 'Delete',
|
|
19
|
+
Properties: {},
|
|
20
|
+
},
|
|
21
|
+
[CODE_BUILD_PROJECT_SERVICE_ROLE_LOGICAL_ID]: {
|
|
22
|
+
Type: 'AWS::IAM::Role',
|
|
23
|
+
Properties: {
|
|
24
|
+
AssumeRolePolicyDocument: {
|
|
25
|
+
Version: '2012-10-17',
|
|
26
|
+
Statement: [
|
|
27
|
+
{
|
|
28
|
+
Effect: 'Allow',
|
|
29
|
+
Principal: {
|
|
30
|
+
Service: 'codebuild.amazonaws.com',
|
|
31
|
+
},
|
|
32
|
+
Action: 'sts:AssumeRole',
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
},
|
|
36
|
+
Path: utils_1.getIamPath(),
|
|
37
|
+
Policies: [
|
|
38
|
+
{
|
|
39
|
+
PolicyName: `${CODE_BUILD_PROJECT_SERVICE_ROLE_LOGICAL_ID}Policy`,
|
|
40
|
+
PolicyDocument: {
|
|
41
|
+
Version: '2012-10-17',
|
|
42
|
+
Statement: [
|
|
43
|
+
{
|
|
44
|
+
Effect: 'Allow',
|
|
45
|
+
Action: ['logs:CreateLogStream', 'logs:PutLogEvents'],
|
|
46
|
+
Resource: '*',
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
Effect: 'Allow',
|
|
50
|
+
Action: ['ecr:GetAuthorizationToken'],
|
|
51
|
+
Resource: '*',
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
Effect: 'Allow',
|
|
55
|
+
Action: [
|
|
56
|
+
'ecr:BatchCheckLayerAvailability',
|
|
57
|
+
'ecr:CompleteLayerUpload',
|
|
58
|
+
'ecr:InitiateLayerUpload',
|
|
59
|
+
'ecr:PutImage',
|
|
60
|
+
'ecr:UploadLayerPart',
|
|
61
|
+
],
|
|
62
|
+
Resource: '*',
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
Effect: 'Allow',
|
|
66
|
+
Action: 's3:GetObject',
|
|
67
|
+
Resource: [
|
|
68
|
+
{
|
|
69
|
+
'Fn::Sub': [
|
|
70
|
+
// eslint-disable-next-line no-template-curly-in-string
|
|
71
|
+
'arn:aws:s3:::${BucketName}/*',
|
|
72
|
+
{
|
|
73
|
+
BucketName: {
|
|
74
|
+
Ref: config_1.BASE_STACK_BUCKET_LOGICAL_NAME,
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
},
|
|
79
|
+
],
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
[config_1.BASE_STACK_LAMBDA_IMAGE_BUILDER_LOGICAL_NAME]: {
|
|
88
|
+
Type: 'AWS::CodeBuild::Project',
|
|
89
|
+
Properties: {
|
|
90
|
+
Artifacts: {
|
|
91
|
+
Type: 'NO_ARTIFACTS',
|
|
92
|
+
},
|
|
93
|
+
Cache: {
|
|
94
|
+
Location: 'LOCAL',
|
|
95
|
+
Modes: ['LOCAL_DOCKER_LAYER_CACHE'],
|
|
96
|
+
Type: 'LOCAL',
|
|
97
|
+
},
|
|
98
|
+
Description: 'Create Lambda image.',
|
|
99
|
+
Environment: {
|
|
100
|
+
ComputeType: 'BUILD_GENERAL1_SMALL',
|
|
101
|
+
EnvironmentVariables: [
|
|
102
|
+
{
|
|
103
|
+
Name: 'AWS_ACCOUNT_ID',
|
|
104
|
+
Value: { Ref: 'AWS::AccountId' },
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
Name: 'AWS_REGION',
|
|
108
|
+
Value: { Ref: 'AWS::Region' },
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
Name: 'IMAGE_TAG',
|
|
112
|
+
Value: 'latest',
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
Name: 'LAMBDA_EXTERNALS',
|
|
116
|
+
Value: '',
|
|
117
|
+
},
|
|
118
|
+
],
|
|
119
|
+
Image: 'aws/codebuild/standard:3.0',
|
|
120
|
+
ImagePullCredentialsType: 'CODEBUILD',
|
|
121
|
+
PrivilegedMode: true,
|
|
122
|
+
Type: 'LINUX_CONTAINER',
|
|
123
|
+
},
|
|
124
|
+
LogsConfig: {
|
|
125
|
+
CloudWatchLogs: {
|
|
126
|
+
Status: 'ENABLED',
|
|
127
|
+
GroupName: { Ref: CODE_BUILD_PROJECT_LOGS_LOGICAL_ID },
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
ServiceRole: {
|
|
131
|
+
'Fn::GetAtt': [CODE_BUILD_PROJECT_SERVICE_ROLE_LOGICAL_ID, 'Arn'],
|
|
132
|
+
},
|
|
133
|
+
Source: {
|
|
134
|
+
BuildSpec: js_yaml_1.default.dump({
|
|
135
|
+
version: '0.2',
|
|
136
|
+
phases: {
|
|
137
|
+
install: {
|
|
138
|
+
commands: [
|
|
139
|
+
'echo install started on `date`',
|
|
140
|
+
'npm init -y',
|
|
141
|
+
/**
|
|
142
|
+
* https://stackoverflow.com/a/51433146/8786986
|
|
143
|
+
*/
|
|
144
|
+
'npm install --save --package-lock-only --no-package-lock $LAMBDA_EXTERNALS',
|
|
145
|
+
'ls',
|
|
146
|
+
],
|
|
147
|
+
},
|
|
148
|
+
pre_build: {
|
|
149
|
+
commands: [
|
|
150
|
+
'echo pre_build started on `date`',
|
|
151
|
+
'$(aws ecr get-login --no-include-email --region $AWS_REGION)',
|
|
152
|
+
],
|
|
153
|
+
},
|
|
154
|
+
build: {
|
|
155
|
+
commands: [
|
|
156
|
+
'echo build started on `date`',
|
|
157
|
+
'echo Building the repository image...',
|
|
158
|
+
'echo "$DOCKERFILE" > Dockerfile',
|
|
159
|
+
'docker build -t $REPOSITORY_ECR_REPOSITORY:$IMAGE_TAG -f Dockerfile .',
|
|
160
|
+
'docker tag $REPOSITORY_ECR_REPOSITORY:$IMAGE_TAG $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/$REPOSITORY_ECR_REPOSITORY:$IMAGE_TAG',
|
|
161
|
+
],
|
|
162
|
+
},
|
|
163
|
+
post_build: {
|
|
164
|
+
commands: [
|
|
165
|
+
'echo post_build completed on `date`',
|
|
166
|
+
'echo Pushing the repository image...',
|
|
167
|
+
'docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com/$REPOSITORY_ECR_REPOSITORY:$IMAGE_TAG',
|
|
168
|
+
],
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
}),
|
|
172
|
+
Type: 'NO_SOURCE',
|
|
173
|
+
},
|
|
174
|
+
TimeoutInMinutes: 60,
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
Outputs: {
|
|
179
|
+
[config_1.BASE_STACK_LAMBDA_IMAGE_BUILDER_LOGICAL_NAME]: {
|
|
180
|
+
Value: { Ref: config_1.BASE_STACK_LAMBDA_IMAGE_BUILDER_LOGICAL_NAME },
|
|
181
|
+
Export: {
|
|
182
|
+
Name: config_1.BASE_STACK_LAMBDA_IMAGE_BUILDER_EXPORTED_NAME,
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
};
|
|
187
|
+
};
|
|
188
|
+
exports.getLambdaImageBuilderTemplate = getLambdaImageBuilderTemplate;
|