token-injectable-docker-builder 0.1.0 → 0.1.1
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/lib/index.d.ts +16 -0
- package/lib/index.js +140 -0
- package/package.json +1 -1
- package/test/docker_image_asset.test.d.ts +1 -0
- package/test/docker_image_asset.test.js +30 -0
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { DockerImageCode } from 'aws-cdk-lib/aws-lambda';
|
|
2
|
+
import { Construct } from 'constructs';
|
|
3
|
+
import { ContainerImage } from 'aws-cdk-lib/aws-ecs';
|
|
4
|
+
export interface TokenInjectableDockerBuilderProps {
|
|
5
|
+
path: string;
|
|
6
|
+
buildArgs?: {
|
|
7
|
+
[key: string]: string;
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export declare class TokenInjectableDockerBuilder extends Construct {
|
|
11
|
+
private readonly ecrRepository;
|
|
12
|
+
private readonly buildTriggerResource;
|
|
13
|
+
constructor(scope: Construct, id: string, props: TokenInjectableDockerBuilderProps);
|
|
14
|
+
getContainerImage(): ContainerImage;
|
|
15
|
+
getDockerImageCode(): DockerImageCode;
|
|
16
|
+
}
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TokenInjectableDockerBuilder = void 0;
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
6
|
+
const aws_codebuild_1 = require("aws-cdk-lib/aws-codebuild");
|
|
7
|
+
const aws_ecr_1 = require("aws-cdk-lib/aws-ecr");
|
|
8
|
+
const aws_iam_1 = require("aws-cdk-lib/aws-iam");
|
|
9
|
+
const aws_lambda_1 = require("aws-cdk-lib/aws-lambda");
|
|
10
|
+
const aws_s3_assets_1 = require("aws-cdk-lib/aws-s3-assets");
|
|
11
|
+
const custom_resources_1 = require("aws-cdk-lib/custom-resources");
|
|
12
|
+
const constructs_1 = require("constructs");
|
|
13
|
+
const aws_ecs_1 = require("aws-cdk-lib/aws-ecs");
|
|
14
|
+
const crypto = require("crypto");
|
|
15
|
+
const aws_lambda_2 = require("aws-cdk-lib/aws-lambda");
|
|
16
|
+
class TokenInjectableDockerBuilder extends constructs_1.Construct {
|
|
17
|
+
constructor(scope, id, props) {
|
|
18
|
+
super(scope, id);
|
|
19
|
+
const { path: sourcePath, buildArgs } = props; // Default to linux/amd64
|
|
20
|
+
// Define absolute paths for Lambda handlers
|
|
21
|
+
const onEventHandlerPath = path.resolve(__dirname, '../src/onEventHandler');
|
|
22
|
+
const isCompleteHandlerPath = path.resolve(__dirname, '../src/isCompleteHandler');
|
|
23
|
+
// Create an ECR repository
|
|
24
|
+
this.ecrRepository = new aws_ecr_1.Repository(this, 'ECRRepository');
|
|
25
|
+
// Package the source code as an asset
|
|
26
|
+
const sourceAsset = new aws_s3_assets_1.Asset(this, 'SourceAsset', {
|
|
27
|
+
path: sourcePath, // Path to the Dockerfile or source code
|
|
28
|
+
});
|
|
29
|
+
// Transform buildArgs into a string of --build-arg KEY=VALUE
|
|
30
|
+
const buildArgsString = buildArgs
|
|
31
|
+
? Object.entries(buildArgs)
|
|
32
|
+
.map(([key, value]) => `--build-arg ${key}=${value}`)
|
|
33
|
+
.join(' ')
|
|
34
|
+
: '';
|
|
35
|
+
// Pass the buildArgsString and platform as environment variables
|
|
36
|
+
const environmentVariables = {
|
|
37
|
+
ECR_REPO_URI: { value: this.ecrRepository.repositoryUri },
|
|
38
|
+
BUILD_ARGS: { value: buildArgsString },
|
|
39
|
+
};
|
|
40
|
+
// Create a CodeBuild project
|
|
41
|
+
const codeBuildProject = new aws_codebuild_1.Project(this, 'UICodeBuildProject', {
|
|
42
|
+
source: aws_codebuild_1.Source.s3({
|
|
43
|
+
bucket: sourceAsset.bucket,
|
|
44
|
+
path: sourceAsset.s3ObjectKey,
|
|
45
|
+
}),
|
|
46
|
+
environment: {
|
|
47
|
+
buildImage: aws_codebuild_1.LinuxBuildImage.STANDARD_7_0,
|
|
48
|
+
privileged: true, // Required for Docker builds
|
|
49
|
+
},
|
|
50
|
+
environmentVariables: environmentVariables,
|
|
51
|
+
buildSpec: aws_codebuild_1.BuildSpec.fromObject({
|
|
52
|
+
version: '0.2',
|
|
53
|
+
phases: {
|
|
54
|
+
pre_build: {
|
|
55
|
+
commands: [
|
|
56
|
+
'echo "Retrieving AWS Account ID..."',
|
|
57
|
+
'export ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)',
|
|
58
|
+
'echo "Logging in to Amazon ECR..."',
|
|
59
|
+
'aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com',
|
|
60
|
+
],
|
|
61
|
+
},
|
|
62
|
+
build: {
|
|
63
|
+
commands: [
|
|
64
|
+
'echo Build phase: Building the Docker image...',
|
|
65
|
+
'docker build $BUILD_ARGS -t $ECR_REPO_URI:latest $CODEBUILD_SRC_DIR',
|
|
66
|
+
],
|
|
67
|
+
},
|
|
68
|
+
post_build: {
|
|
69
|
+
commands: [
|
|
70
|
+
'echo Post-build phase: Pushing the Docker image...',
|
|
71
|
+
'docker push $ECR_REPO_URI:latest',
|
|
72
|
+
],
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
}),
|
|
76
|
+
});
|
|
77
|
+
// Grant permissions to interact with ECR
|
|
78
|
+
this.ecrRepository.grantPullPush(codeBuildProject);
|
|
79
|
+
codeBuildProject.role.addToPrincipalPolicy(new aws_iam_1.PolicyStatement({
|
|
80
|
+
actions: ['ecr:GetAuthorizationToken'],
|
|
81
|
+
resources: ['*'],
|
|
82
|
+
}));
|
|
83
|
+
// Grant permissions to CodeBuild for CloudWatch Logs
|
|
84
|
+
codeBuildProject.role.addToPrincipalPolicy(new aws_iam_1.PolicyStatement({
|
|
85
|
+
actions: ['logs:PutLogEvents', 'logs:CreateLogGroup', 'logs:CreateLogStream'],
|
|
86
|
+
resources: [`arn:aws:logs:${aws_cdk_lib_1.Stack.of(this).region}:${aws_cdk_lib_1.Stack.of(this).account}:*`],
|
|
87
|
+
}));
|
|
88
|
+
// Create Node.js Lambda function for onEvent
|
|
89
|
+
const onEventHandlerFunction = new aws_lambda_2.Function(this, 'OnEventHandlerFunction', {
|
|
90
|
+
runtime: aws_lambda_1.Runtime.NODEJS_18_X, // Use Node.js runtime
|
|
91
|
+
code: aws_lambda_1.Code.fromAsset(onEventHandlerPath), // Path to handler code
|
|
92
|
+
handler: 'index.handler', // Entry point (adjust as needed)
|
|
93
|
+
timeout: aws_cdk_lib_1.Duration.minutes(15),
|
|
94
|
+
});
|
|
95
|
+
onEventHandlerFunction.addToRolePolicy(new aws_iam_1.PolicyStatement({
|
|
96
|
+
actions: ['codebuild:StartBuild'],
|
|
97
|
+
resources: [codeBuildProject.projectArn], // Restrict to specific project
|
|
98
|
+
}));
|
|
99
|
+
// Create Node.js Lambda function for isComplete
|
|
100
|
+
const isCompleteHandlerFunction = new aws_lambda_2.Function(this, 'IsCompleteHandlerFunction', {
|
|
101
|
+
runtime: aws_lambda_1.Runtime.NODEJS_18_X,
|
|
102
|
+
code: aws_lambda_1.Code.fromAsset(isCompleteHandlerPath),
|
|
103
|
+
handler: 'index.handler',
|
|
104
|
+
timeout: aws_cdk_lib_1.Duration.minutes(15),
|
|
105
|
+
});
|
|
106
|
+
isCompleteHandlerFunction.addToRolePolicy(new aws_iam_1.PolicyStatement({
|
|
107
|
+
actions: [
|
|
108
|
+
'codebuild:BatchGetBuilds',
|
|
109
|
+
'codebuild:ListBuildsForProject',
|
|
110
|
+
'logs:GetLogEvents',
|
|
111
|
+
'logs:DescribeLogStreams',
|
|
112
|
+
'logs:DescribeLogGroups'
|
|
113
|
+
],
|
|
114
|
+
resources: ['*'],
|
|
115
|
+
}));
|
|
116
|
+
// Create a custom resource provider
|
|
117
|
+
const provider = new custom_resources_1.Provider(this, 'CustomResourceProvider', {
|
|
118
|
+
onEventHandler: onEventHandlerFunction,
|
|
119
|
+
isCompleteHandler: isCompleteHandlerFunction,
|
|
120
|
+
queryInterval: aws_cdk_lib_1.Duration.minutes(1),
|
|
121
|
+
});
|
|
122
|
+
// Define the custom resource
|
|
123
|
+
this.buildTriggerResource = new aws_cdk_lib_1.CustomResource(this, 'BuildTriggerResource', {
|
|
124
|
+
serviceToken: provider.serviceToken,
|
|
125
|
+
properties: {
|
|
126
|
+
ProjectName: codeBuildProject.projectName,
|
|
127
|
+
Trigger: crypto.randomUUID(),
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
this.buildTriggerResource.node.addDependency(codeBuildProject);
|
|
131
|
+
}
|
|
132
|
+
getContainerImage() {
|
|
133
|
+
return aws_ecs_1.ContainerImage.fromEcrRepository(this.ecrRepository, 'latest');
|
|
134
|
+
}
|
|
135
|
+
getDockerImageCode() {
|
|
136
|
+
return aws_lambda_1.DockerImageCode.fromEcr(this.ecrRepository);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
exports.TokenInjectableDockerBuilder = TokenInjectableDockerBuilder;
|
|
140
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw2QkFBNkI7QUFDN0IsNkNBQThEO0FBQzlELDZEQUF3RjtBQUN4RixpREFBaUQ7QUFDakQsaURBQXNEO0FBQ3RELHVEQUF3RTtBQUN4RSw2REFBa0Q7QUFDbEQsbUVBQXdEO0FBQ3hELDJDQUF1QztBQUN2QyxpREFBcUQ7QUFDckQsaUNBQWlDO0FBQ2pDLHVEQUFrRDtBQU9sRCxNQUFhLDRCQUE2QixTQUFRLHNCQUFTO0lBSXpELFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBd0M7UUFDaEYsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVqQixNQUFNLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsR0FBRyxLQUFLLENBQUMsQ0FBQyx5QkFBeUI7UUFFeEUsNENBQTRDO1FBQzVDLE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsdUJBQXVCLENBQUMsQ0FBQztRQUM1RSxNQUFNLHFCQUFxQixHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLDBCQUEwQixDQUFDLENBQUM7UUFFbEYsMkJBQTJCO1FBQzNCLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxvQkFBVSxDQUFDLElBQUksRUFBRSxlQUFlLENBQUMsQ0FBQztRQUUzRCxzQ0FBc0M7UUFDdEMsTUFBTSxXQUFXLEdBQUcsSUFBSSxxQkFBSyxDQUFDLElBQUksRUFBRSxhQUFhLEVBQUU7WUFDakQsSUFBSSxFQUFFLFVBQVUsRUFBRSx3Q0FBd0M7U0FDM0QsQ0FBQyxDQUFDO1FBRUgsNkRBQTZEO1FBQzdELE1BQU0sZUFBZSxHQUFHLFNBQVM7WUFDL0IsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDO2lCQUN0QixHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcs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QUNqRSxDQUFDO0lBRU0saUJBQWlCO1FBQ3RCLE9BQU8sd0JBQWMsQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQ3hFLENBQUM7SUFFTSxrQkFBa0I7UUFDdkIsT0FBTyw0QkFBZSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDckQsQ0FBQztDQUNGO0FBeEpELG9FQXdKQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgeyBEdXJhdGlvbiwgQ3VzdG9tUmVzb3VyY2UsIFN0YWNrIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHsgUHJvamVjdCwgU291cmNlLCBMaW51eEJ1aWxkSW1hZ2UsIEJ1aWxkU3BlYyB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1jb2RlYnVpbGQnO1xuaW1wb3J0IHsgUmVwb3NpdG9yeSB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1lY3InO1xuaW1wb3J0IHsgUG9saWN5U3RhdGVtZW50IH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWlhbSc7XG5pbXBvcnQgeyBDb2RlLCBEb2NrZXJJbWFnZUNvZGUsIFJ1bnRpbWUgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtbGFtYmRhJztcbmltcG9ydCB7IEFzc2V0IH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLXMzLWFzc2V0cyc7XG5pbXBvcnQgeyBQcm92aWRlciB9IGZyb20gJ2F3cy1jZGstbGliL2N1c3RvbS1yZXNvdXJjZXMnO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5pbXBvcnQgeyBDb250YWluZXJJbWFnZSB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1lY3MnO1xuaW1wb3J0ICogYXMgY3J5cHRvIGZyb20gJ2NyeXB0byc7XG5pbXBvcnQgeyBGdW5jdGlvbiB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1sYW1iZGEnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFRva2VuSW5qZWN0YWJsZURvY2tlckJ1aWxkZXJQcm9wcyB7XG4gIHBhdGg6IHN0cmluZztcbiAgYnVpbGRBcmdzPzogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfTtcbn1cblxuZXhwb3J0IGNsYXNzIFRva2VuSW5qZWN0YWJsZURvY2tlckJ1aWxkZXIgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICBwcml2YXRlIHJlYWRvbmx5IGVjclJlcG9zaXRvcnk6IFJlcG9zaXRvcnk7XG4gIHByaXZhdGUgcmVhZG9ubHkgYnVpbGRUcmlnZ2VyUmVzb3VyY2U6IEN1c3RvbVJlc291cmNlO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBUb2tlbkluamVjdGFibGVEb2NrZXJCdWlsZGVyUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgY29uc3QgeyBwYXRoOiBzb3VyY2VQYXRoLCBidWlsZEFyZ3MgfSA9IHByb3BzOyAvLyBEZWZhdWx0IHRvIGxpbnV4L2FtZDY0XG5cbiAgICAvLyBEZWZpbmUgYWJzb2x1dGUgcGF0aHMgZm9yIExhbWJkYSBoYW5kbGVyc1xuICAgIGNvbnN0IG9uRXZlbnRIYW5kbGVyUGF0aCA9IHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsICcuLi9zcmMvb25FdmVudEhhbmRsZXInKTtcbiAgICBjb25zdCBpc0NvbXBsZXRlSGFuZGxlclBhdGggPSBwYXRoLnJlc29sdmUoX19kaXJuYW1lLCAnLi4vc3JjL2lzQ29tcGxldGVIYW5kbGVyJyk7XG5cbiAgICAvLyBDcmVhdGUgYW4gRUNSIHJlcG9zaXRvcnlcbiAgICB0aGlzLmVjclJlcG9zaXRvcnkgPSBuZXcgUmVwb3NpdG9yeSh0aGlzLCAnRUNSUmVwb3NpdG9yeScpO1xuXG4gICAgLy8gUGFja2FnZSB0aGUgc291cmNlIGNvZGUgYXMgYW4gYXNzZXRcbiAgICBjb25zdCBzb3VyY2VBc3NldCA9IG5ldyBBc3NldCh0aGlzLCAnU291cmNlQXNzZXQnLCB7XG4gICAgICBwYXRoOiBzb3VyY2VQYXRoLCAvLyBQYXRoIHRvIHRoZSBEb2NrZXJmaWxlIG9yIHNvdXJjZSBjb2RlXG4gICAgfSk7XG5cbiAgICAvLyBUcmFuc2Zvcm0gYnVpbGRBcmdzIGludG8gYSBzdHJpbmcgb2YgLS1idWlsZC1hcmcgS0VZPVZBTFVFXG4gICAgY29uc3QgYnVpbGRBcmdzU3RyaW5nID0gYnVpbGRBcmdzXG4gICAgICA/IE9iamVjdC5lbnRyaWVzKGJ1aWxkQXJncylcbiAgICAgICAgICAubWFwKChba2V5LCB2YWx1ZV0pID0+IGAtLWJ1aWxkLWFyZyAke2tleX09JHt2YWx1ZX1gKVxuICAgICAgICAgIC5qb2luKCcgJylcbiAgICAgIDogJyc7XG5cbiAgICAvLyBQYXNzIHRoZSBidWlsZEFyZ3NTdHJpbmcgYW5kIHBsYXRmb3JtIGFzIGVudmlyb25tZW50IHZhcmlhYmxlc1xuICAgIGNvbnN0IGVudmlyb25tZW50VmFyaWFibGVzOiB7IFtuYW1lOiBzdHJpbmddOiB7IHZhbHVlOiBzdHJpbmcgfSB9ID0ge1xuICAgICAgRUNSX1JFUE9fVVJJOiB7IHZhbHVlOiB0aGlzLmVjclJlcG9zaXRvcnkucmVwb3NpdG9yeVVyaSB9LFxuICAgICAgQlVJTERfQVJHUzogeyB2YWx1ZTogYnVpbGRBcmdzU3RyaW5nIH0sXG4gICAgfTtcblxuICAgIC8vIENyZWF0ZSBhIENvZGVCdWlsZCBwcm9qZWN0XG4gICAgY29uc3QgY29kZUJ1aWxkUHJvamVjdCA9IG5ldyBQcm9qZWN0KHRoaXMsICdVSUNvZGVCdWlsZFByb2plY3QnLCB7XG4gICAgICBzb3VyY2U6IFNvdXJjZS5zMyh7XG4gICAgICAgIGJ1Y2tldDogc291cmNlQXNzZXQuYnVja2V0LFxuICAgICAgICBwYXRoOiBzb3VyY2VBc3NldC5zM09iamVjdEtleSxcbiAgICAgIH0pLFxuICAgICAgZW52aXJvbm1lbnQ6IHtcbiAgICAgICAgYnVpbGRJbWFnZTogTGludXhCdWlsZEltYWdlLlNUQU5EQVJEXzdfMCxcbiAgICAgICAgcHJpdmlsZWdlZDogdHJ1ZSwgLy8gUmVxdWlyZWQgZm9yIERvY2tlciBidWlsZHNcbiAgICAgIH0sXG4gICAgICBlbnZpcm9ubWVudFZhcmlhYmxlczogZW52aXJvbm1lbnRWYXJpYWJsZXMsXG4gICAgICBidWlsZFNwZWM6IEJ1aWxkU3BlYy5mcm9tT2JqZWN0KHtcbiAgICAgICAgdmVyc2lvbjogJzAuMicsXG4gICAgICAgIHBoYXNlczoge1xuICAgICAgICAgIHByZV9idWlsZDoge1xuICAgICAgICAgICAgY29tbWFuZHM6IFtcbiAgICAgICAgICAgICAgJ2VjaG8gXCJSZXRyaWV2aW5nIEFXUyBBY2NvdW50IElELi4uXCInLFxuICAgICAgICAgICAgICAnZXhwb3J0IEFDQ09VTlRfSUQ9JChhd3Mgc3RzIGdldC1jYWxsZXItaWRlbnRpdHkgLS1xdWVyeSBBY2NvdW50IC0tb3V0cHV0IHRleHQpJyxcbiAgICAgICAgICAgICAgJ2VjaG8gXCJMb2dnaW5nIGluIHRvIEFtYXpvbiBFQ1IuLi5cIicsXG4gICAgICAgICAgICAgICdhd3MgZWNyIGdldC1sb2dpbi1wYXNzd29yZCAtLXJlZ2lvbiAkQVdTX0RFRkFVTFRfUkVHSU9OIHwgZG9ja2VyIGxvZ2luIC0tdXNlcm5hbWUgQVdTIC0tcGFzc3dvcmQtc3RkaW4gJEFDQ09VTlRfSUQuZGtyLmVjci4kQVdTX0RFRkFVTFRfUkVHSU9OLmFtYXpvbmF3cy5jb20nLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGJ1aWxkOiB7XG4gICAgICAgICAgICBjb21tYW5kczogW1xuICAgICAgICAgICAgICAnZWNobyBCdWlsZCBwaGFzZTogQnVpbGRpbmcgdGhlIERvY2tlciBpbWFnZS4uLicsXG4gICAgICAgICAgICAgICdkb2NrZXIgYnVpbGQgJEJVSUxEX0FSR1MgLXQgJEVDUl9SRVBPX1VSSTpsYXRlc3QgJENPREVCVUlMRF9TUkNfRElSJyxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICBwb3N0X2J1aWxkOiB7XG4gICAgICAgICAgICBjb21tYW5kczogW1xuICAgICAgICAgICAgICAnZWNobyBQb3N0LWJ1aWxkIHBoYXNlOiBQdXNoaW5nIHRoZSBEb2NrZXIgaW1hZ2UuLi4nLFxuICAgICAgICAgICAgICAnZG9ja2VyIHB1c2ggJEVDUl9SRVBPX1VSSTpsYXRlc3QnLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSksXG4gICAgfSk7XG5cbiAgICAvLyBHcmFudCBwZXJtaXNzaW9ucyB0byBpbnRlcmFjdCB3aXRoIEVDUlxuICAgIHRoaXMuZWNyUmVwb3NpdG9yeS5ncmFudFB1bGxQdXNoKGNvZGVCdWlsZFByb2plY3QpO1xuXG4gICAgY29kZUJ1aWxkUHJvamVjdC5yb2xlIS5hZGRUb1ByaW5jaXBhbFBvbGljeShcbiAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICBhY3Rpb25zOiBbJ2VjcjpHZXRBdXRob3JpemF0aW9uVG9rZW4nXSxcbiAgICAgICAgcmVzb3VyY2VzOiBbJyonXSxcbiAgICAgIH0pXG4gICAgKTtcblxuICAgIC8vIEdyYW50IHBlcm1pc3Npb25zIHRvIENvZGVCdWlsZCBmb3IgQ2xvdWRXYXRjaCBMb2dzXG4gICAgY29kZUJ1aWxkUHJvamVjdC5yb2xlIS5hZGRUb1ByaW5jaXBhbFBvbGljeShcbiAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICBhY3Rpb25zOiBbJ2xvZ3M6UHV0TG9nRXZlbnRzJywgJ2xvZ3M6Q3JlYXRlTG9nR3JvdXAnLCAnbG9nczpDcmVhdGVMb2dTdHJlYW0nXSxcbiAgICAgICAgcmVzb3VyY2VzOiBbYGFybjphd3M6bG9nczoke1N0YWNrLm9mKHRoaXMpLnJlZ2lvbn06JHtTdGFjay5vZih0aGlzKS5hY2NvdW50fToqYF0sXG4gICAgICB9KVxuICAgICk7XG5cbiAgICAvLyBDcmVhdGUgTm9kZS5qcyBMYW1iZGEgZnVuY3Rpb24gZm9yIG9uRXZlbnRcbiAgICBjb25zdCBvbkV2ZW50SGFuZGxlckZ1bmN0aW9uID0gbmV3IEZ1bmN0aW9uKHRoaXMsICdPbkV2ZW50SGFuZGxlckZ1bmN0aW9uJywge1xuICAgICAgcnVudGltZTogUnVudGltZS5OT0RFSlNfMThfWCwgLy8gVXNlIE5vZGUuanMgcnVudGltZVxuICAgICAgY29kZTogQ29kZS5mcm9tQXNzZXQob25FdmVudEhhbmRsZXJQYXRoKSwgLy8gUGF0aCB0byBoYW5kbGVyIGNvZGVcbiAgICAgIGhhbmRsZXI6ICdpbmRleC5oYW5kbGVyJywgLy8gRW50cnkgcG9pbnQgKGFkanVzdCBhcyBuZWVkZWQpXG4gICAgICB0aW1lb3V0OiBEdXJhdGlvbi5taW51dGVzKDE1KSxcbiAgICB9KTtcblxuICAgIG9uRXZlbnRIYW5kbGVyRnVuY3Rpb24uYWRkVG9Sb2xlUG9saWN5KFxuICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgIGFjdGlvbnM6IFsnY29kZWJ1aWxkOlN0YXJ0QnVpbGQnXSxcbiAgICAgICAgcmVzb3VyY2VzOiBbY29kZUJ1aWxkUHJvamVjdC5wcm9qZWN0QXJuXSwgLy8gUmVzdHJpY3QgdG8gc3BlY2lmaWMgcHJvamVjdFxuICAgICAgfSlcbiAgICApO1xuXG4gICAgLy8gQ3JlYXRlIE5vZGUuanMgTGFtYmRhIGZ1bmN0aW9uIGZvciBpc0NvbXBsZXRlXG4gICAgY29uc3QgaXNDb21wbGV0ZUhhbmRsZXJGdW5jdGlvbiA9IG5ldyBGdW5jdGlvbih0aGlzLCAnSXNDb21wbGV0ZUhhbmRsZXJGdW5jdGlvbicsIHtcbiAgICAgIHJ1bnRpbWU6IFJ1bnRpbWUuTk9ERUpTXzE4X1gsXG4gICAgICBjb2RlOiBDb2RlLmZyb21Bc3NldChpc0NvbXBsZXRlSGFuZGxlclBhdGgpLFxuICAgICAgaGFuZGxlcjogJ2luZGV4LmhhbmRsZXInLFxuICAgICAgdGltZW91dDogRHVyYXRpb24ubWludXRlcygxNSksXG4gICAgfSk7XG5cbiAgICBpc0NvbXBsZXRlSGFuZGxlckZ1bmN0aW9uLmFkZFRvUm9sZVBvbGljeShcbiAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICBhY3Rpb25zOiBbXG4gICAgICAgICAgJ2NvZGVidWlsZDpCYXRjaEdldEJ1aWxkcycsXG4gICAgICAgICAgJ2NvZGVidWlsZDpMaXN0QnVpbGRzRm9yUHJvamVjdCcsXG4gICAgICAgICAgJ2xvZ3M6R2V0TG9nRXZlbnRzJyxcbiAgICAgICAgICAnbG9nczpEZXNjcmliZUxvZ1N0cmVhbXMnLFxuICAgICAgICAgICdsb2dzOkRlc2NyaWJlTG9nR3JvdXBzJ1xuICAgICAgICBdLFxuICAgICAgICByZXNvdXJjZXM6IFsnKiddLFxuICAgICAgfSlcbiAgICApO1xuXG4gICAgLy8gQ3JlYXRlIGEgY3VzdG9tIHJlc291cmNlIHByb3ZpZGVyXG4gICAgY29uc3QgcHJvdmlkZXIgPSBuZXcgUHJvdmlkZXIodGhpcywgJ0N1c3RvbVJlc291cmNlUHJvdmlkZXInLCB7XG4gICAgICBvbkV2ZW50SGFuZGxlcjogb25FdmVudEhhbmRsZXJGdW5jdGlvbixcbiAgICAgIGlzQ29tcGxldGVIYW5kbGVyOiBpc0NvbXBsZXRlSGFuZGxlckZ1bmN0aW9uLFxuICAgICAgcXVlcnlJbnRlcnZhbDogRHVyYXRpb24ubWludXRlcygxKSxcbiAgICB9KTtcblxuICAgIC8vIERlZmluZSB0aGUgY3VzdG9tIHJlc291cmNlXG4gICAgdGhpcy5idWlsZFRyaWdnZXJSZXNvdXJjZSA9IG5ldyBDdXN0b21SZXNvdXJjZSh0aGlzLCAnQnVpbGRUcmlnZ2VyUmVzb3VyY2UnLCB7XG4gICAgICBzZXJ2aWNlVG9rZW46IHByb3ZpZGVyLnNlcnZpY2VUb2tlbixcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgUHJvamVjdE5hbWU6IGNvZGVCdWlsZFByb2plY3QucHJvamVjdE5hbWUsXG4gICAgICAgIFRyaWdnZXI6IGNyeXB0by5yYW5kb21VVUlEKCksXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgdGhpcy5idWlsZFRyaWdnZXJSZXNvdXJjZS5ub2RlLmFkZERlcGVuZGVuY3koY29kZUJ1aWxkUHJvamVjdCk7XG4gIH1cblxuICBwdWJsaWMgZ2V0Q29udGFpbmVySW1hZ2UoKTogQ29udGFpbmVySW1hZ2Uge1xuICAgIHJldHVybiBDb250YWluZXJJbWFnZS5mcm9tRWNyUmVwb3NpdG9yeSh0aGlzLmVjclJlcG9zaXRvcnksICdsYXRlc3QnKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXREb2NrZXJJbWFnZUNvZGUoKTogRG9ja2VySW1hZ2VDb2RlIHtcbiAgICByZXR1cm4gRG9ja2VySW1hZ2VDb2RlLmZyb21FY3IodGhpcy5lY3JSZXBvc2l0b3J5KTtcbiAgfVxufVxuIl19
|
package/package.json
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const cdk = require("aws-cdk-lib");
|
|
4
|
+
const assertions_1 = require("aws-cdk-lib/assertions");
|
|
5
|
+
const index_1 = require("../lib/index");
|
|
6
|
+
test('DockerImageAsset creates required resources', () => {
|
|
7
|
+
const app = new cdk.App();
|
|
8
|
+
const stack = new cdk.Stack(app, 'TestStack');
|
|
9
|
+
new index_1.TokenInjectableDockerBuilder(stack, 'TestDockerImageAsset', {
|
|
10
|
+
path: './src/onEventHandler', // Path to Docker context
|
|
11
|
+
buildArgs: { ENV: 'test' },
|
|
12
|
+
});
|
|
13
|
+
const template = assertions_1.Template.fromStack(stack);
|
|
14
|
+
// Verify that an ECR repository is created
|
|
15
|
+
template.resourceCountIs('AWS::ECR::Repository', 1);
|
|
16
|
+
// Verify that a CodeBuild project is created with expected properties
|
|
17
|
+
template.hasResourceProperties('AWS::CodeBuild::Project', {
|
|
18
|
+
Environment: {
|
|
19
|
+
ComputeType: 'BUILD_GENERAL1_SMALL',
|
|
20
|
+
PrivilegedMode: true,
|
|
21
|
+
Image: 'aws/codebuild/standard:7.0',
|
|
22
|
+
},
|
|
23
|
+
Source: {
|
|
24
|
+
Type: 'S3',
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
// Verify the Custom Resource is created with the expected service token
|
|
28
|
+
template.resourceCountIs('AWS::CloudFormation::CustomResource', 1);
|
|
29
|
+
});
|
|
30
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG9ja2VyX2ltYWdlX2Fzc2V0LnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJkb2NrZXJfaW1hZ2VfYXNzZXQudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLG1DQUFtQztBQUNuQyx1REFBa0Q7QUFDbEQsd0NBQTREO0FBRTVELElBQUksQ0FBQyw2Q0FBNkMsRUFBRSxHQUFHLEVBQUU7SUFDdkQsTUFBTSxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7SUFDMUIsTUFBTSxLQUFLLEdBQUcsSUFBSSxHQUFHLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxXQUFXLENBQUMsQ0FBQztJQUU5QyxJQUFJLG9DQUE0QixDQUFDLEtBQUssRUFBRSxzQkFBc0IsRUFBRTtRQUM5RCxJQUFJLEVBQUUsc0JBQXNCLEVBQUUseUJBQXlCO1FBQ3ZELFNBQVMsRUFBRSxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUU7S0FDM0IsQ0FBQyxDQUFDO0lBRUgsTUFBTSxRQUFRLEdBQUcscUJBQVEsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7SUFFM0MsMkNBQTJDO0lBQzNDLFFBQVEsQ0FBQyxlQUFlLENBQUMsc0JBQXNCLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFFcEQsc0VBQXNFO0lBQ3RFLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQyx5QkFBeUIsRUFBRTtRQUN4RCxXQUFXLEVBQUU7WUFDWCxXQUFXLEVBQUUsc0JBQXNCO1lBQ25DLGNBQWMsRUFBRSxJQUFJO1lBQ3BCLEtBQUssRUFBRSw0QkFBNEI7U0FDcEM7UUFDRCxNQUFNLEVBQUU7WUFDTixJQUFJLEVBQUUsSUFBSTtTQUNYO0tBQ0YsQ0FBQyxDQUFDO0lBRUgsd0VBQXdFO0lBQ3hFLFFBQVEsQ0FBQyxlQUFlLENBQUMscUNBQXFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDckUsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBjZGsgZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHsgVGVtcGxhdGUgfSBmcm9tICdhd3MtY2RrLWxpYi9hc3NlcnRpb25zJztcbmltcG9ydCB7IFRva2VuSW5qZWN0YWJsZURvY2tlckJ1aWxkZXIgfSBmcm9tICcuLi9saWIvaW5kZXgnO1xuXG50ZXN0KCdEb2NrZXJJbWFnZUFzc2V0IGNyZWF0ZXMgcmVxdWlyZWQgcmVzb3VyY2VzJywgKCkgPT4ge1xuICBjb25zdCBhcHAgPSBuZXcgY2RrLkFwcCgpO1xuICBjb25zdCBzdGFjayA9IG5ldyBjZGsuU3RhY2soYXBwLCAnVGVzdFN0YWNrJyk7XG5cbiAgbmV3IFRva2VuSW5qZWN0YWJsZURvY2tlckJ1aWxkZXIoc3RhY2ssICdUZXN0RG9ja2VySW1hZ2VBc3NldCcsIHtcbiAgICBwYXRoOiAnLi9zcmMvb25FdmVudEhhbmRsZXInLCAvLyBQYXRoIHRvIERvY2tlciBjb250ZXh0XG4gICAgYnVpbGRBcmdzOiB7IEVOVjogJ3Rlc3QnIH0sXG4gIH0pO1xuXG4gIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcblxuICAvLyBWZXJpZnkgdGhhdCBhbiBFQ1IgcmVwb3NpdG9yeSBpcyBjcmVhdGVkXG4gIHRlbXBsYXRlLnJlc291cmNlQ291bnRJcygnQVdTOjpFQ1I6OlJlcG9zaXRvcnknLCAxKTtcblxuICAvLyBWZXJpZnkgdGhhdCBhIENvZGVCdWlsZCBwcm9qZWN0IGlzIGNyZWF0ZWQgd2l0aCBleHBlY3RlZCBwcm9wZXJ0aWVzXG4gIHRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpDb2RlQnVpbGQ6OlByb2plY3QnLCB7XG4gICAgRW52aXJvbm1lbnQ6IHtcbiAgICAgIENvbXB1dGVUeXBlOiAnQlVJTERfR0VORVJBTDFfU01BTEwnLFxuICAgICAgUHJpdmlsZWdlZE1vZGU6IHRydWUsXG4gICAgICBJbWFnZTogJ2F3cy9jb2RlYnVpbGQvc3RhbmRhcmQ6Ny4wJyxcbiAgICB9LFxuICAgIFNvdXJjZToge1xuICAgICAgVHlwZTogJ1MzJyxcbiAgICB9LFxuICB9KTtcblxuICAvLyBWZXJpZnkgdGhlIEN1c3RvbSBSZXNvdXJjZSBpcyBjcmVhdGVkIHdpdGggdGhlIGV4cGVjdGVkIHNlcnZpY2UgdG9rZW5cbiAgdGVtcGxhdGUucmVzb3VyY2VDb3VudElzKCdBV1M6OkNsb3VkRm9ybWF0aW9uOjpDdXN0b21SZXNvdXJjZScsIDEpO1xufSk7XG4iXX0=
|