private CodeBuildAction CreateDockerImageBuildAction(Repository dockerRepo, Artifact_ sourceOutput) { var codeBuildAction = new CodeBuildAction(new CodeBuildActionProps { Input = sourceOutput, ActionName = "Build-app-Docker-image", Type = CodeBuildActionType.BUILD, Project = new PipelineProject(this, "CodeBuildProject", new PipelineProjectProps { ProjectName = "Unicorn-Store-app-Docker-image-build", BuildSpec = new BuildSpecHelper { PreBuildCommands = new [] { "echo Logging in to Amazon ECR...", "aws --version", "$(aws ecr get-login --region $AWS_DEFAULT_REGION --no-include-email)" }, BuildCommands = new [] { "docker build --build-arg BUILD_CONFIG=${BuildConfig}${DbEngine} -t ${DockerRepoUri}:${ImageTag} ." }, PostBuildCommands = new [] { "docker push ${DockerRepoUri}:${ImageTag}" } }.ToBuildSpec(), Environment = new BuildEnvironment { Privileged = true, BuildImage = LinuxBuildImage.UBUNTU_14_04_DOCKER_18_09_0, EnvironmentVariables = new Dictionary <string, IBuildEnvironmentVariable>() { { // Tells the Buildspec where to push images produced during the build "DockerRepoUri", new BuildEnvironmentVariable { Value = dockerRepo.RepositoryUriForTag() } }, { "DbEngine", new BuildEnvironmentVariable { Value = this.settings.DbEngine.ToString() } }, { "BuildConfig", new BuildEnvironmentVariable { Value = this.settings.BuildConfiguration } }, { "ImageTag", new BuildEnvironmentVariable { Value = this.settings.ImageTag } } }, ComputeType = this.settings.BuildInstanceSize }, Role = new Role(this, "Docker-Image-build-role", new RoleProps { // Need to explicitly grant CodeBuild service permissions to let it push Docker // images to ECR, because we do `docker push` straight from the Build stage, bypassing // Deploy stage, where it could have been done too. AssumedBy = new ServicePrincipal("codebuild.amazonaws.com"), ManagedPolicies = Helpers.FromAwsManagedPolicies("AmazonEC2ContainerRegistryPowerUser") }), Cache = Cache.Local(LocalCacheMode.SOURCE, LocalCacheMode.DOCKER_LAYER) }) }); return(codeBuildAction); }
public CiCdStack(Construct parent, string id, CiCdStackProps props) : base(parent, id, props) { var apiRepository = Amazon.CDK.AWS.CodeCommit.Repository.FromRepositoryArn(this, "Repository", props.apiRepositoryArn); var environmentVariables = new Dictionary <string, IBuildEnvironmentVariable>(); environmentVariables.Add("AWS_ACCOUNT_ID", new BuildEnvironmentVariable() { Type = BuildEnvironmentVariableType.PLAINTEXT, Value = Aws.ACCOUNT_ID }); environmentVariables.Add("AWS_DEFAULT_REGION", new BuildEnvironmentVariable() { Type = BuildEnvironmentVariableType.PLAINTEXT, Value = Aws.REGION }); var codebuildProject = new PipelineProject(this, "BuildProject", new PipelineProjectProps { Environment = new BuildEnvironment { ComputeType = ComputeType.SMALL, BuildImage = LinuxBuildImage.UBUNTU_14_04_PYTHON_3_5_2, Privileged = true, EnvironmentVariables = environmentVariables } }); var codeBuildPolicy = new PolicyStatement(); codeBuildPolicy.AddResources(apiRepository.RepositoryArn); codeBuildPolicy.AddActions( "codecommit:ListBranches", "codecommit:ListRepositories", "codecommit:BatchGetRepositories", "codecommit:GitPull" ); codebuildProject.AddToRolePolicy( codeBuildPolicy ); props.ecrRepository.GrantPullPush(codebuildProject.GrantPrincipal); var sourceOutput = new Artifact_(); var sourceAction = new Amazon.CDK.AWS.CodePipeline.Actions.CodeCommitSourceAction( new Amazon.CDK.AWS.CodePipeline.Actions.CodeCommitSourceActionProps { ActionName = "CodeCommit-Source", Branch = "master", Trigger = CodeCommitTrigger.POLL, Repository = apiRepository, Output = sourceOutput }); var buildOutput = new Artifact_(); var buildAction = new CodeBuildAction(new CodeBuildActionProps { ActionName = "Build", Input = sourceOutput, Outputs = new Artifact_[] { buildOutput }, Project = codebuildProject }); var deployAction = new EcsDeployAction(new EcsDeployActionProps { ActionName = "DeployAction", Input = buildOutput, Service = props.ecsService, }); var pipeline = new Pipeline(this, "Pipeline"); pipeline.AddStage(new StageOptions { StageName = "Source", Actions = new Action[] { sourceAction } }); pipeline.AddStage(new StageOptions { StageName = "Build", Actions = new Action[] { buildAction } }); pipeline.AddStage(new StageOptions { StageName = "Deploy", Actions = new Action[] { deployAction } }); }
private CodeBuildAction CreateAppDeploymentEnvironmentBuildAction(Artifact_ sourceOutput) { var codeBuildAction = new CodeBuildAction(new CodeBuildActionProps { Input = sourceOutput, ActionName = "Build-app-deployment-environment", Type = CodeBuildActionType.BUILD, Project = new PipelineProject(this, "DeploymentEnvCreationProject", new PipelineProjectProps { ProjectName = "Unicorn-Store-deployment-env-build", BuildSpec = new BuildSpecHelper { InstallRuntimes = new Dictionary <string, string>() { { "nodejs", "10" }, // Make sure this matches Lambda runtime version specified in CreateLambdaForRestartingEcsApp() }, PreBuildCommands = new [] { "aws --version", "npm install -g aws-cdk${CdkVersion}", "cdk --version", // Install .NET Core 3 SDK. TODO: remove this section after dotnet 3.0 runtime becomes available on AWS Linux CodeBuild images "wget -q https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb", "dpkg -i packages-microsoft-prod.deb", "apt-get update", "apt-get -y install apt-transport-https", "apt-get update", "apt-get -y install dotnet-sdk-3.0", "dotnet --info", "dotnet --version" }, BuildCommands = new [] { "echo Building CDK CI/CD project", "cd ./infra-as-code/ProdEnvInfraAsCode/src", "dotnet build ProdEnvInfraAsCode.csproj -c ${BuildConfig}${DbEngine}", "cdk diff || true", "cdk deploy --require-approval never" } }.ToBuildSpec(), Environment = new BuildEnvironment { BuildImage = LinuxBuildImage.STANDARD_2_0, ComputeType = this.settings.BuildInstanceSize, EnvironmentVariables = new Dictionary <string, IBuildEnvironmentVariable>() { { "DbEngine", new BuildEnvironmentVariable { Value = this.settings.DbEngine.ToString() } }, { "BuildConfig", new BuildEnvironmentVariable { Value = this.settings.BuildConfiguration } }, { "DockerImageRepository", new BuildEnvironmentVariable { Value = this.settings.DockerImageRepository } }, { "DotNetEnvironment", new BuildEnvironmentVariable { Value = this.settings.IsDebug ? "Development" : "Production" } }, { "EcsClusterName", new BuildEnvironmentVariable { Value = this.settings.AppEcsClusterName } }, { "CdkVersion", new BuildEnvironmentVariable { Value = this.settings.CdkInstallCommandVersion } } } }, Role = new Role(this, "App-deployment-env-creation-role", new RoleProps { // Need to explicitly grant CodeBuild service permissions to let it push Docker // images to ECR, because we do `docker push` straight from the Build stage, bypassing // Deploy stage, where it could have been done too. AssumedBy = new ServicePrincipal("codebuild.amazonaws.com"), ManagedPolicies = Helpers.FromAwsManagedPolicies( //"CloudWatchLogsFullAccess", //"AWSCodeDeployRoleForECSLimited", //"AWSCloudFormationFullAccess" "AdministratorAccess" // <= TODO: Find more fine-grained set of policies to enable CloudFormation stack creation ) }), Cache = Cache.Local(LocalCacheMode.SOURCE, LocalCacheMode.DOCKER_LAYER) }) }); return(codeBuildAction); }