@Generated(value="jsii-pacmak/1.74.0 (build 6d08790)", date="2023-03-28T21:34:29.029Z") public class TagParameterContainerImage extends ContainerImage
ContainerImage
that uses an ECR repository for the image, but a CloudFormation Parameter for the tag of the image in that repository.
This allows providing this tag through the Parameter at deploy time, for example in a CodePipeline that pushes a new tag of the image to the repository during a build step, and then provides that new tag through the CloudFormation Parameter in the deploy step.
Example:
/** * These are the construction properties for {@link EcsAppStack}. * They extend the standard Stack properties, * but also require providing the ContainerImage that the service will use. * That Image will be provided from the Stack containing the CodePipeline. */ public class EcsAppStackProps extends StackProps { private ContainerImage image; public ContainerImage getImage() { return this.image; } public EcsAppStackProps image(ContainerImage image) { this.image = image; return this; } } /** * This is the Stack containing a simple ECS Service that uses the provided ContainerImage. */ public class EcsAppStack extends Stack { public EcsAppStack(Construct scope, String id, EcsAppStackProps props) { super(scope, id, props); TaskDefinition taskDefinition = TaskDefinition.Builder.create(this, "TaskDefinition") .compatibility(Compatibility.FARGATE) .cpu("1024") .memoryMiB("2048") .build(); taskDefinition.addContainer("AppContainer", ContainerDefinitionOptions.builder() .image(props.getImage()) .build()); FargateService.Builder.create(this, "EcsService") .taskDefinition(taskDefinition) .cluster(Cluster.Builder.create(this, "Cluster") .vpc(Vpc.Builder.create(this, "Vpc") .maxAzs(1) .build()) .build()) .build(); } } /** * This is the Stack containing the CodePipeline definition that deploys an ECS Service. */ public class PipelineStack extends Stack { public final TagParameterContainerImage tagParameterContainerImage; public PipelineStack(Construct scope, String id) { this(scope, id, null); } public PipelineStack(Construct scope, String id, StackProps props) { super(scope, id, props); /* ********** ECS part **************** */ // this is the ECR repository where the built Docker image will be pushed Repository appEcrRepo = new Repository(this, "EcsDeployRepository"); // the build that creates the Docker image, and pushes it to the ECR repo PipelineProject appCodeDockerBuild = PipelineProject.Builder.create(this, "AppCodeDockerImageBuildAndPushProject") .environment(BuildEnvironment.builder() // we need to run Docker .privileged(true) .build()) .buildSpec(BuildSpec.fromObject(Map.of( "version", "0.2", "phases", Map.of( "build", Map.of( "commands", List.of("$(aws ecr get-login --region $AWS_DEFAULT_REGION --no-include-email)", "docker build -t $REPOSITORY_URI:$CODEBUILD_RESOLVED_SOURCE_VERSION .")), "post_build", Map.of( "commands", List.of("docker push $REPOSITORY_URI:$CODEBUILD_RESOLVED_SOURCE_VERSION", "export imageTag=$CODEBUILD_RESOLVED_SOURCE_VERSION"))), "env", Map.of( // save the imageTag environment variable as a CodePipeline Variable "exported-variables", List.of("imageTag"))))) .environmentVariables(Map.of( "REPOSITORY_URI", BuildEnvironmentVariable.builder() .value(appEcrRepo.getRepositoryUri()) .build())) .build(); // needed for `docker push` appEcrRepo.grantPullPush(appCodeDockerBuild); // create the ContainerImage used for the ECS application Stack this.tagParameterContainerImage = new TagParameterContainerImage(appEcrRepo); PipelineProject cdkCodeBuild = PipelineProject.Builder.create(this, "CdkCodeBuildProject") .buildSpec(BuildSpec.fromObject(Map.of( "version", "0.2", "phases", Map.of( "install", Map.of( "commands", List.of("npm install")), "build", Map.of( "commands", List.of("npx cdk synth --verbose"))), "artifacts", Map.of( // store the entire Cloud Assembly as the output artifact "base-directory", "cdk.out", "files", "**/*")))) .build(); /* ********** Pipeline part **************** */ Artifact appCodeSourceOutput = new Artifact(); Artifact cdkCodeSourceOutput = new Artifact(); Artifact cdkCodeBuildOutput = new Artifact(); CodeBuildAction appCodeBuildAction = CodeBuildAction.Builder.create() .actionName("AppCodeDockerImageBuildAndPush") .project(appCodeDockerBuild) .input(appCodeSourceOutput) .build(); Pipeline.Builder.create(this, "CodePipelineDeployingEcsApplication") .artifactBucket(Bucket.Builder.create(this, "ArtifactBucket") .removalPolicy(RemovalPolicy.DESTROY) .build()) .stages(List.of(StageProps.builder() .stageName("Source") .actions(List.of( // this is the Action that takes the source of your application code CodeCommitSourceAction.Builder.create() .actionName("AppCodeSource") .repository(Repository.Builder.create(this, "AppCodeSourceRepository").repositoryName("AppCodeSourceRepository").build()) .output(appCodeSourceOutput) .build(), // this is the Action that takes the source of your CDK code // (which would probably include this Pipeline code as well) CodeCommitSourceAction.Builder.create() .actionName("CdkCodeSource") .repository(Repository.Builder.create(this, "CdkCodeSourceRepository").repositoryName("CdkCodeSourceRepository").build()) .output(cdkCodeSourceOutput) .build())) .build(), StageProps.builder() .stageName("Build") .actions(List.of(appCodeBuildAction, CodeBuildAction.Builder.create() .actionName("CdkCodeBuildAndSynth") .project(cdkCodeBuild) .input(cdkCodeSourceOutput) .outputs(List.of(cdkCodeBuildOutput)) .build())) .build(), StageProps.builder() .stageName("Deploy") .actions(List.of( CloudFormationCreateUpdateStackAction.Builder.create() .actionName("CFN_Deploy") .stackName("SampleEcsStackDeployedFromCodePipeline") // this name has to be the same name as used below in the CDK code for the application Stack .templatePath(cdkCodeBuildOutput.atPath("EcsStackDeployedInPipeline.template.json")) .adminPermissions(true) .parameterOverrides(Map.of( // read the tag pushed to the ECR repository from the CodePipeline Variable saved by the application build step, // and pass it as the CloudFormation Parameter for the tag this.tagParameterContainerImage.getTagParameterName(), appCodeBuildAction.variable("imageTag"))) .build())) .build())) .build(); } } App app = new App(); // the CodePipeline Stack needs to be created first PipelineStack pipelineStack = new PipelineStack(app, "aws-cdk-pipeline-ecs-separate-sources"); // we supply the image to the ECS application Stack from the CodePipeline Stack // we supply the image to the ECS application Stack from the CodePipeline Stack new EcsAppStack(app, "EcsStackDeployedInPipeline", new EcsAppStackProps() .image(pipelineStack.getTagParameterContainerImage()) );
Modifier | Constructor and Description |
---|---|
protected |
TagParameterContainerImage(software.amazon.jsii.JsiiObject.InitializationMode initializationMode) |
protected |
TagParameterContainerImage(software.amazon.jsii.JsiiObjectRef objRef) |
Modifier and Type | Method and Description |
---|---|
ContainerImageConfig |
bind(Construct scope,
ContainerDefinition containerDefinition)
Called when the image is used by a ContainerDefinition.
|
java.lang.String |
getTagParameterName()
Returns the name of the CloudFormation Parameter that represents the tag of the image in the ECR repository.
|
java.lang.String |
getTagParameterValue()
Returns the value of the CloudFormation Parameter that represents the tag of the image in the ECR repository.
|
fromAsset, fromAsset, fromDockerImageAsset, fromEcrRepository, fromEcrRepository, fromRegistry, fromRegistry, fromTarball
protected TagParameterContainerImage(software.amazon.jsii.JsiiObjectRef objRef)
protected TagParameterContainerImage(software.amazon.jsii.JsiiObject.InitializationMode initializationMode)
public ContainerImageConfig bind(Construct scope, ContainerDefinition containerDefinition)
bind
in class ContainerImage
scope
- This parameter is required.containerDefinition
- This parameter is required.public java.lang.String getTagParameterName()
public java.lang.String getTagParameterValue()