使用Packer,如何远程构建Amazon ECR实例

问题描述 投票:1回答:3

我的问题:

我想将一个docker镜像保存为Amazon EC2注册表中的工件,由packer(和ansible)构建

我的局限性:构建需要由Bitbucket Pipelines触发。因此,构建步骤需要在Bitbucket管道本身或AWS EC2实例/容器中执行。

这是因为并非所有dev机器都必须具有从其本地环境构建的权限/包。我只希望这些图像是由自动CI过程构建的。

我尝试过的:

使用Packer,我能够远程构建AMI。我能够使用Packer(本地构建并远程推送到Amazon ECR)构建Docker镜像。

但是,已经在docker容器中执行构建步骤的Bitbucket Pipeline无法访问docker守护进程'docker run'。

我在Bitbucket管道中收到的错误:

+ packer build ${BITBUCKET_CLONE_DIR}/build/pipelines_builder/template.json
docker output will be in this color.
==> docker: Creating a temporary directory for sharing data...
==> docker: Pulling Docker image: hashicorp/packer
    docker: Using default tag: latest
    docker: latest: Pulling from hashicorp/packer
    docker: 88286f41530e: Pulling fs layer
    ...
    ...
    docker: 08d16a84c1fe: Pull complete
    docker: Digest: sha256:c093ddf4c346297598aaa13d3d12fe4e9d39267be51ae6e225c08af49ec67fc0
    docker: Status: Downloaded newer image for hashicorp/packer:latest
==> docker: Starting docker container...
    docker: Run command: docker run -v /root/.packer.d/tmp/packer-docker426823595:/packer-files -d -i -t hashicorp/packer /bin/bash
==> docker: Error running container: Docker exited with a non-zero exit status.
==> docker: Stderr: docker: Error response from daemon: authorization denied by plugin pipelines: Command not supported..
==> docker: See 'docker run --help'.
==> docker:
Build 'docker' errored: Error running container: Docker exited with a non-zero exit status.
Stderr: docker: Error response from daemon: authorization denied by plugin pipelines: Command not supported..
See 'docker run --help'.
==> Some builds didn't complete successfully and had errors:
--> docker: Error running container: Docker exited with a non-zero exit status.
Stderr: docker: Error response from daemon: authorization denied by plugin pipelines: Command not supported..
See 'docker run --help'.
==> Builds finished but no artifacts were created.

以下引用说明了一切(取自link):

出于安全原因,我们的共享构建基础结构目前禁止使用其他命令,例如docker run。

所以,我知道为什么会发生以下情况。这是我面临的限制。我知道我需要找到一个替代方案。

一个可能的解决方案:我现在能想到的唯一解决方案是使用安装了terraform和ansible的图像的Bitbucket Pipeline,其中包含以下内容:

  • ansible本地: terraform apply(从安装了ansible和packer的AMI中旋转实例/容器)
  • ansible-remote(对于上面提到的实例) 克隆devops repo与packer构建脚本就可以了 执行packer build命令(build命令依赖于ansible,build创建ec2容器注册表图像)
  • ansible本地 terraform毁灭

上述解决方案是否可行?还有替代品吗? Packer是否可以从ECS中远程运行的容器中运行命令和提交?

我的长期解决方案是仅使用bitbucket管道来触发AWS中的lambda函数,这将在我们的EC2 Container Registry中启动容器并在那里执行构建。更多控制,我们可以让开发人员从他们的机器触发lambda函数(具有更多定制的动态变量)。

amazon-ec2 terraform packer bitbucket-pipelines
3个回答
1
投票

我设置了一些terraform脚本,可用于从任何CI工具执行,具有一些先决条件:

  • CI工具必须具有到AWS的API访问令牌(迄今为止唯一支持的云提供商)
  • CI工具必须能够运行Terraform或dockerized Terraform容器

这将在您选择的自己的VPC中启动一个新的EC2实例并执行脚本。

对于这个堆栈溢出问题,该脚本将包含一些打包器命令来构建和推送docker镜像。 EC2实例的AMI需要安装打包器和docker。

有关更多信息,请访问:https://github.com/dnk8n/remote-provisioner


0
投票

我对你的问题的理解是阻止你的是,bitbucket管道(通常称之为agents)没有足够的权限来完成你的AWS账户的工作(terraform applypacker build)。

由于bitbucket管道代理程序在Bitbucket云中运行,而不是在您的AWS账户(您可以在其上分配IAM角色)中运行,因此您应该创建一个具有IAM角色的帐户(下面列出的策略和权限)分配其AWS API密钥(AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYAWS_SESSION_TOKEN的选项)作为管道中的环境变量。

您可以参考此文档,了解如何将您的AWS凭证添加到Bitbucket管道

https://confluence.atlassian.com/bitbucket/deploy-to-amazon-aws-875304040.html

有了它,您可以毫无问题地运行打包程序或terraform命令。

要分配运行packer build所需的最小策略,请参阅此文档:

https://www.packer.io/docs/builders/amazon.html#using-an-iam-task-or-instance-role

{
  "Version": "2012-10-17",
  "Statement": [{
      "Effect": "Allow",
      "Action" : [
        "ec2:AttachVolume",
        "ec2:AuthorizeSecurityGroupIngress",
        "ec2:CopyImage",
        "ec2:CreateImage",
        "ec2:CreateKeypair",
        "ec2:CreateSecurityGroup",
        "ec2:CreateSnapshot",
        "ec2:CreateTags",
        "ec2:CreateVolume",
        "ec2:DeleteKeypair",
        "ec2:DeleteSecurityGroup",
        "ec2:DeleteSnapshot",
        "ec2:DeleteVolume",
        "ec2:DeregisterImage",
        "ec2:DescribeImageAttribute",
        "ec2:DescribeImages",
        "ec2:DescribeInstances",
        "ec2:DescribeRegions",
        "ec2:DescribeSecurityGroups",
        "ec2:DescribeSnapshots",
        "ec2:DescribeSubnets",
        "ec2:DescribeTags",
        "ec2:DescribeVolumes",
        "ec2:DetachVolume",
        "ec2:GetPasswordData",
        "ec2:ModifyImageAttribute",
        "ec2:ModifyInstanceAttribute",
        "ec2:ModifySnapshotAttribute",
        "ec2:RegisterImage",
        "ec2:RunInstances",
        "ec2:StopInstances",
        "ec2:TerminateInstances"
      ],
      "Resource" : "*"
  }]
}

对于terraform plan/apply,您需要分配最多权限,因为terraform可以处理几乎所有aws资源。

其次,对于您现有的需求,您只需要运行packer和terraform命令,您无需在bitbucket管道中运行docker命令。

所以正常的管道具有上面的aws API环境,它应该直接工作。

image: hashicorp/packer

pipelines:
  default:
    - step:
        script:
          - packer build <your_packer_json_file>

您也可以在图像hashicorp/terraform中运行terraform命令。


0
投票

我想我会像这样接近它:

  1. 有一个Packer构建产生一个可以在EC2上运行的“Docker build AMI”。基本上它只是一个预先安装了Docker的AMI,以及你需要的任何其他东西。这个Packer构建可以存储在另一个BitBucket Git仓库中,您可以通过另一个BitBucket管道构建并映射到EC2,以便对构建AMI的任何更改自动构建并作为AMI推送。如你所知,在这里使用AWS Builder
  2. 将Terraform脚本作为当前项目的一部分,由您的BitBucket管道调用,以便在管道启动时启动上述“Docker Build”AMI的实例,例如terraform apply
  3. 在上面的EC2实例上使用Packer Docker Builder构建并将Docker镜像推送到ECR(应用Ansible脚本)。
  4. 一旦构建完成,就将环境变成环境

这样做可以将基础架构中的所有内容保存为代码,并且如果它们支持在任何时候运行destroy,那么将Docker构建本地移动到BitBucket管道中会非常简单。

© www.soinside.com 2019 - 2024. All rights reserved.