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.
Files changed (60) hide show
  1. package/CHANGELOG.md +378 -0
  2. package/bin/carlin +2 -0
  3. package/dist/cli.js +250 -0
  4. package/dist/config.js +10 -0
  5. package/dist/deploy/addDefaults.cloudFormation.js +138 -0
  6. package/dist/deploy/baseStack/command.js +9 -0
  7. package/dist/deploy/baseStack/config.js +30 -0
  8. package/dist/deploy/baseStack/deployBaseStack.js +61 -0
  9. package/dist/deploy/baseStack/getBaseStackResource.js +26 -0
  10. package/dist/deploy/baseStack/getBucket.template.js +44 -0
  11. package/dist/deploy/baseStack/getLambdaImageBuilder.template.js +188 -0
  12. package/dist/deploy/baseStack/getLambdaLayerBuilder.template.js +140 -0
  13. package/dist/deploy/baseStack/getVpc.template.js +169 -0
  14. package/dist/deploy/cicd/cicd.template.js +872 -0
  15. package/dist/deploy/cicd/command.js +84 -0
  16. package/dist/deploy/cicd/config.js +7 -0
  17. package/dist/deploy/cicd/deployCicd.js +114 -0
  18. package/dist/deploy/cicd/ecsTaskReportCommand.js +53 -0
  19. package/dist/deploy/cicd/getCicdStackName.js +11 -0
  20. package/dist/deploy/cicd/getTriggerPipelineObjectKey.js +12 -0
  21. package/dist/deploy/cicd/lambdas/cicdApiV1.handler.js +124 -0
  22. package/dist/deploy/cicd/lambdas/ecsTaskReport.handler.js +79 -0
  23. package/dist/deploy/cicd/lambdas/executeTasks.js +91 -0
  24. package/dist/deploy/cicd/lambdas/getProcessEnvVariable.js +10 -0
  25. package/dist/deploy/cicd/lambdas/githubWebhooksApiV1.handler.js +143 -0
  26. package/dist/deploy/cicd/lambdas/index.js +11 -0
  27. package/dist/deploy/cicd/lambdas/pipelines.handler.js +154 -0
  28. package/dist/deploy/cicd/lambdas/putApprovalResultManualTask.js +52 -0
  29. package/dist/deploy/cicd/pipelines.js +52 -0
  30. package/dist/deploy/cloudFormation.core.js +286 -0
  31. package/dist/deploy/cloudFormation.js +201 -0
  32. package/dist/deploy/command.js +211 -0
  33. package/dist/deploy/lambda.js +177 -0
  34. package/dist/deploy/lambdaLayer/command.js +51 -0
  35. package/dist/deploy/lambdaLayer/deployLambdaLayer.js +142 -0
  36. package/dist/deploy/s3.js +167 -0
  37. package/dist/deploy/stackName.js +78 -0
  38. package/dist/deploy/staticApp/command.js +101 -0
  39. package/dist/deploy/staticApp/getOriginShieldRegion.js +30 -0
  40. package/dist/deploy/staticApp/staticApp.js +206 -0
  41. package/dist/deploy/staticApp/staticApp.template.js +874 -0
  42. package/dist/deploy/utils.js +31 -0
  43. package/dist/index.js +7 -0
  44. package/dist/utils/addGroupToOptions.js +11 -0
  45. package/dist/utils/buildLambdaFiles.js +99 -0
  46. package/dist/utils/cloudFormationTemplate.js +134 -0
  47. package/dist/utils/codeBuild.js +52 -0
  48. package/dist/utils/environmentVariables.js +11 -0
  49. package/dist/utils/exec.js +24 -0
  50. package/dist/utils/formatCode.js +30 -0
  51. package/dist/utils/getAwsAccountId.js +10 -0
  52. package/dist/utils/getCurrentBranch.js +35 -0
  53. package/dist/utils/getEnvironment.js +6 -0
  54. package/dist/utils/getIamPath.js +6 -0
  55. package/dist/utils/getProjectName.js +28 -0
  56. package/dist/utils/index.js +26 -0
  57. package/dist/utils/packageJson.js +46 -0
  58. package/dist/utils/readCloudFormationTemplate.js +35 -0
  59. package/dist/utils/readObjectFile.js +50 -0
  60. 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;