Как с помощью Packer создать инстанс Amazon ECR удаленно

Моя проблема:

Я хочу сохранить образ докера как артефакт в реестре Amazon EC2, созданный упаковщиком (и доступный)

Мои ограничения: сборка должна запускаться Bitbucket Pipelines. Поэтому шаги сборки необходимо выполнять либо в самом Bitbucket Pipelines, либо в экземпляре / контейнере AWS EC2.

Это связано с тем, что не все машины разработки обязательно имеют разрешения / пакеты для сборки из своей локальной среды. Я хочу, чтобы эти образы создавались только в результате автоматизированного процесса CI.

Что я пробовал:

Используя Packer, я могу создавать AMI удаленно. И я могу создавать образы Docker с помощью Packer (созданный локально и удаленно отправленный в Amazon ECR).

Однако конвейер Bitbucket, который уже выполняет шаги сборки в контейнере докера, не имеет доступа к процессу docker daemon 'docker run'.

Ошибка, которую я получаю в Bitbucket Pipelines:

+ 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.

Следующая цитата говорит обо всем (взято из ссылки ):

Другие команды, такие как docker run, в настоящее время запрещены по соображениям безопасности в нашей общей инфраструктуре сборки.

Итак, я знаю, почему происходит следующее. Это ограничение, с которым я столкнулся. Я понимаю, что мне нужно найти альтернативу.

Возможное решение. Единственное решение, которое я могу придумать на данный момент, - это конвейер Bitbucket, использующий изображение с установленными terraform и ansible, содержащее следующее:

  • ansible-local:

    • terraform apply (spins up an instance/container from AMI with ansible and packer installed)
  • ansible-remote (к указанному выше экземпляру)

    • clone devops repo with packer build script on it
    • выполнить команду сборки упаковщика (команда сборки зависит от ansible, сборка создает образ реестра контейнера ec2)
  • ансибль-местный

    • terraform destroy

Является ли вышеупомянутое решение жизнеспособным вариантом? Есть ли альтернативы? Может ли Packer не запускать команды и выполнять фиксацию из контейнера, запущенного удаленно в ECS?

Моим долгосрочным решением будет использование конвейеров битбакетов только для запуска лямбда-функций в AWS, которые будут запускать контейнеры в нашем реестре контейнеров EC2 и выполнять сборки там. Больше контроля, и мы можем заставить разработчиков запускать лямбда-функции со своих машин (с большим количеством индивидуальных динамических переменных).


person Dean Kayton    schedule 30.08.2017    source источник
comment
Я также сталкиваюсь с этой проблемой, я могу взять на себя роль локально в учетной записи, которая имеет ECR, но тогда я не могу зафиксировать изображение из-за того, что Пакер считает, что я прошел аутентификацию с моей аутентификацией без роли   -  person Joshua G. Edwards    schedule 22.03.2019
comment
Мой ответ вообще помогает @ josh-edwards?   -  person Dean Kayton    schedule 23.03.2019


Ответы (3)


Я установил несколько скриптов terraform, которые можно использовать для выполнения из любого инструмента CI, с некоторыми предварительными условиями:

  • Инструмент CI должен иметь токены доступа API к AWS (пока что единственный поддерживаемый облачный провайдер).
  • Инструмент CI должен иметь возможность запускать Terraform или докеризованный контейнер Terraform.

Это запустит новый экземпляр EC2 в вашем собственном VPC по вашему выбору и выполнит сценарий.

Для этого вопроса о переполнении стека этот сценарий будет содержать некоторые команды упаковщика для создания и отправки образа докера. Для AMI для экземпляра EC2 потребуется установить упаковщик и докер.

Дополнительную информацию можно найти по адресу: https://github.com/dnk8n/remote-provisioner.

person Dean Kayton    schedule 23.03.2019
comment
Я думаю, что у меня была другая проблема, я не использую конвейеры Bitbucket - person Joshua G. Edwards; 25.03.2019
comment
Что ж, это также можно запустить с вашего локального компьютера вместо инструмента CI. Он будет запускать экземпляр Amazon EC2 и запускать упаковщик оттуда (способом, определенным в файле сценария). - person Dean Kayton; 26.03.2019

Насколько я понимаю, ваша проблема с блокировкой заключается в том, что конвейеры битбакета (обычно называемые ими agents) не имеют достаточных разрешений для выполнения задания (terraform apply, packer build) в вашей учетной записи AWS.

Поскольку агенты конвейера Bitbucket работают в облаке Bitbucket, а не в вашей учетной записи AWS (которой вы можете назначить им роль IAM), вам следует создать учетную запись с ролью IAM (политики и разрешения перечислены ниже) назначить ее ключи API AWS (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY и вариант AWS_SESSION_TOKEN) в качестве переменных среды в вашем конвейере.

Вы можете обратиться к этому документу о том, как добавить свои учетные данные AWS в Bitbucket Pipelines.

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

При этом вы можете без проблем запускать команды упаковщика или терраформирования.

Чтобы узнать о минимальных политиках, которые необходимо назначить для запуска 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, вам не нужно запускать команду docker в конвейере bitbucket.

Таким образом, обычный конвейер с вышеуказанной средой API aws должен работать напрямую.

image: hashicorp/packer

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

Вы также можете запустить команду terraform в образе hashicorp/terraform.

person BMW    schedule 31.08.2017
comment
Я уже успешно использую упаковщик и терраформ из Bitbucket Pipelines (с разрешениями и всем настроенным). Это просто в том случае, когда в шаблоне упаковщика template.json есть построитель типа docker, где возникает проблема, потому что за кулисами Packer фактически выполняет команду docker run. Я ищу способ для Packer создать образ докера вне среды Bitbucket Pipelines (например, в экземпляре или контейнере EC2, чтобы он мог успешно выполнить команду запуска докера. Тем не менее, спасибо за ваш вклад. - person Dean Kayton; 31.08.2017

Думаю, я подошел бы к этому так:

  1. Имейте сборку Packer, которая создает «Docker build AMI», который можно запускать на EC2. По сути, это будет просто AMI с предустановленным Docker и всем остальным, что вам нужно. Эта сборка Packer может быть сохранена в другом репозитории BitBucket Git, и вы можете создать этот образ и отправить его в EC2 через другой конвейер BitBucket, чтобы любые изменения в AMI вашей сборки автоматически создавались и передавались как AMI. Как вы уже предлагали, используйте для этого AWS Builder.
  2. Используйте сценарий Terraform как часть вашего текущего проекта, который вызывается конвейером BitBucket для запуска экземпляра указанного выше AMI «Docker Build» при запуске конвейера, например terraform apply
  3. Используйте Packer Docker Builder на указанном выше экземпляре EC2 для сборки и развертывания вашего Docker. изображение в ECR (с применением ваших скриптов Ansible).
  4. Терраформируйте destroy среду после завершения сборки

При этом все в инфраструктуре хранится в виде кода, и вам будет довольно просто перемещать сборку Docker локально в конвейер BitBucket, если они предлагают поддержку для запуска docker run в любой момент.

person Rob Blake    schedule 22.09.2017
comment
Это примерно то, о чем я думал. Когда я доберусь до его реализации, я отмечу это как принятый ответ (в следующем месяце г, так) - person Dean Kayton; 26.09.2017