使用 CloudFormation 将 Docker 映像推送到 ECR

Vik*_*ore 5 aws-cloudformation gitlab-ci docker-registry

我是 DevOps 新手。

作为 gitci 的一部分,我在 GitLab 中有一个 Docker 文件。我计划创建一个 Docker 映像并将其推送到 ECR,然后使用该映像进行批处理。

我已经使用 ECR 中的现有图像完成了批处理部分。但无法创建 Docker 映像并使用 CloudFormation 进行推送。

我应该在 init 中使用命令吗?

先谢谢各位高手了

Cai*_*mes 5

我在工作中遇到了同样的问题,并且偶然发现了这个已经提出的问题,但没有正确的答案,所以我将给出我是如何做的说明。

基线:您无法使用 cloudformation 来做到这一点,cloudformation 用于创建基础设施和自动化。不过,您可以使用 codebuild 来完成此操作,并且可以使用 cloudformation 创建 codebuild 项目。这个存储库就是一个实际的例子。

您要做的是:创建一个 cloudformation 模板,该模板创建一个 codebuild 项目,并在您的 codebuild 中创建一个 buildspec.yml (指定构建的文件),它将您的映像推送到 ECR。

codebuild 项目如下所示:

CodeBuildProject:
Type: AWS::CodeBuild::Project
Properties:
  Artifacts:
    Type: CODEPIPELINE
  Description: "Codebuild project to push flask api image to ecr"
  Environment:
    ComputeType:
      !FindInMap [CodeBuildComputeTypeMap, !Ref GithubBranch, type]
    EnvironmentVariables:
      - Name: AWS_DEFAULT_REGION
        Value: !Ref AWS::Region
      - Name: AWS_ACCOUNT_ID
        Value: !Ref "AWS::AccountId"
      - Name: AWS_ECR_REPOSITORY_URI
        Value: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/${EcrRepository}
      - Name: IMAGE_REPO_NAME
        Value: !Ref GithubRepository
      - Name: IMAGE_TAG
        Value: "latest"
    Image: "aws/codebuild/standard:5.0"
    PrivilegedMode: true
    Type: "LINUX_CONTAINER"
  ServiceRole: !GetAtt CodeBuildRole.Arn
  Source:
    Type: "CODEPIPELINE"
    BuildSpec: buildspec.yml

EcrRepository:
     Type: AWS::ECR::Repository
     Properties:
       RepositoryName: !Ref GithubRepository

CodeBuildRole:
Type: AWS::IAM::Role
Properties:
  AssumeRolePolicyDocument:
    Version: "2012-10-17"
    Statement:
      - Effect: Allow
        Principal:
          Service:
            - codebuild.amazonaws.com
        Action:
          - "sts:AssumeRole"
  Policies:
    - PolicyName: "PushImageToEcr"
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Action:
              - ecr:BatchGetImage
              - ecr:BatchCheckLayerAvailability
              - ecr:CompleteLayerUpload
              - ecr:GetDownloadUrlForLayer
              - ecr:InitiateLayerUpload
              - ecr:PutImage
              - ecr:UploadLayerPart
              - ecr:GetAuthorizationToken
            Resource: "*"
    - PolicyName: "CodeBuildLogsRole"
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Action:
              - logs:CreateLogGroup
              - logs:CreateLogStream
              - logs:PutLogEvents
            Resource:
              - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/codebuild/*"
    - PolicyName: "GetAndPutArtifacts"
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Action:
              - s3:GetObject
              - s3:PutObject
              - s3:ListBucket
            Resource:
              - !GetAtt ArtifactBucket.Arn
              - !Sub ${ArtifactBucket.Arn}/*

ArtifactBucket:
    Type: AWS::S3::Bucket
Run Code Online (Sandbox Code Playgroud)

这应该位于cloudformation 的资源部分,并将创建 codebuild 项目、ecr 存储库、codebuild 服务角色和工件的 s3 存储桶。

然后你需要一个buildspec.yml模板来推送你的图像,这看起来像这样:

version: 0.2

phases:
  pre_build:
    commands:
      - echo Logging in to Amazon ECR...
      - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
  build:
    commands:
      - echo Build started on `date`
      - echo Building the Docker image...
      - cd app/
      - docker build -t $IMAGE_REPO_NAME:$IMAGE_TAG .
      - docker tag $IMAGE_REPO_NAME:$IMAGE_TAG $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
  post_build:
    commands:
      - echo Build completed on `date`
      - echo Pushing the Docker image...
      - docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
Run Code Online (Sandbox Code Playgroud)