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);
        }
示例#2
0
        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);
        }