使用 cloudformation 将 docker 图像推送到 ECR

Push docker image to ECR using cloudformation

我是DevOps的新手,所以如果你觉得这个问题很尴尬,请不要介意。

作为 gitci.I 的一部分,在 gitlab 中有一个 docker 文件。我打算创建一个 docker 图像并将其推送到 ECR,然后使用该图像进行批处理。

我已经使用 ECR 中的现有图像完成了批处理部分。但无法使用 cloudformation 创建 docker 图像 n 推送。

请指导我。我应该在 init.

中使用命令吗?

在此先感谢大师们

您将无法使用 CloudFormation 执行此操作,因为它不适合执行这种操作方式。

但是,您提到您正在使用 gitlab-ci。这意味着您可以轻松创建一个构建 docker 图像并将其上传到 ECR 的作业。

在我看来,创建一个 CodeBuild 项目(使用 CloudFormation、IaC FTW!)来处理 Docker 图像的构建和上传更加容易。 CodeBuild 优于 GitLab-ci 的优势在于,您将能够为 CodeBuild 工作人员提供适当的 ECR 访问权限,以便它将图像上传到存储库。

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

基线:您不能使用 cloudformation 执行此操作,cloudformation 用于创建基础架构和自动化。不过,您可以使用 codebuild 完成此操作,并且可以使用 cloudformation 创建 codebuild 项目。这个 repository 是为了一个实际的例子。

你要做的是:创建一个 cloudformation 模板来创建一个代码构建项目,并在你的代码构建中创建一个 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

这应该放在 cloudformation 的 Resources 部分,并将创建代码构建项目、ecr 存储库、代码构建服务角色和工件的 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