简体   繁体   中英

AWS CodePipeline GitHub Source Action and ECS Deploy Action

I have a Github repo with source code for an API. I want to deploy this API in AWS ECS. I also want to create an AWS CodePipeline such that, every time I deploy into my Github API repo, the CodePipeline fetches the new commit, builds an ECR image, and deploys my ECS service using the new ECR image. I am using aws-cdk-lib for my infrastructure.

The pipeline is modeled as follows:

GitHubSourceStage --> EcrCodeBuildStage --> EcsDeploymentStage

 export class MyEcsPipelineConstruct extends Construct {

    constructor(scope: Construct, id: string, props: MyApiEcsServiceProps) {
        super(scope, id, props);

        const pipeline = new codepipeline.Pipeline(this, 'PipelineId', {
            pipelineName: 'PipelineName',
            crossAccountKeys: false,
            stages: [
                {
                    stageName: 'GitHubSourceStage',
                    actions: [ new GitHubSourceAction({...}) ],  // Gets Github Source Code
                },
                {
                    stageName: 'EcrCodeBuildStage',
                    actions: [new CodeBuildAction({...})],   // Builds and pushes ECR image
                },
                {
                    stageName: 'EcsDeploymentStage',
                    actions: [ new EcsDeployAction({...}) ],
                },
            ],
        });
    }
}

I managed to meet the above requirements. The problem that I have is a chicken and egg problem.

The ECR repository is empty upon initial creation of my infrastructure, it doesn't have any images. It will only get an image after the pipeline runs EcrCodeBuildStage stage for the first time.

When I initially deploy this stack, the deployment gets stuck. This is because the deployment tries to create the ECS service by pulling an empty ECR repo. This is how the stack looks:

export class MyApiEcsStack extends Stack {
    readonly vpc: Vpc;
    readonly ecsCluster: Cluster;
    readonly ecrRepository: Repository;
    readonly fargateService: ApplicationLoadBalancedFargateService;
    readonly fargateTaskDefinition: FargateTaskDefinition;

    constructor(scope: App, id: string, props: MyApiEcsServiceProps) {
        super(scope, id, props);

        this.vpc = new ec2.Vpc(...);

        this.ecsCluster = new ecs.Cluster(...);

        this.ecrRepository = new ecr.Repository(...);

        this.fargateTaskDefinition = new ecs.FargateTaskDefinition(...);

        this.fargateService = new ApplicationLoadBalancedFargateService(...);

        new MyEcsPipelineConstruct(...);
    }
}

Here is my plan to cheat the chicken and egg problem.

  1. Create an ECR repository before running the CDK script.
  2. Build the Docker image for the service locally and push it to the repository.
  3. Import the existing repository in the CDK script instead of creating a new one. When deploying the ECS service, the repository would contain the first image.

As a side note, I want to mention that the same problem happens with an AWS CodeCommit repository. Should one create the repository in the CDK script or import an existing repository and only set necessary permissions in the script?

The problem happens once when we start a new project. Though, we have to do this for every project.

I stick to the following plan when I start working on a new project.

  1. Create a GitHub repository for the project and write a readme file with a short explanation, including a building plan.
  2. Write a minimum working version with Docker build files and Docker Composer setup to run the application locally.
  3. Create an ECR repository and push the application images to the repository. Then, other developers can run the application locally without building it. Or even integrate it with their applications by using the image from the ECR repository in their docker-compose setup.
  4. Setup the application environment in the cloud and write and test the CDK deployment scripts.

Sometimes I join the project in the last stage and set up the cloud environment for the application done by other people. For example, they might have some dockerized applications integrated with other applications. My task would be to develop deployment for the application garden.

Please let me know if you see any issues with the plan.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM