Help us understand the problem. What is going on with this article?

AnsibleでAmazon Elastic Container Registry(ECR)にDockerイメージをpushする

More than 1 year has passed since last update.

概要

AnsibleでAmazon Elastic Container Registry(ECR)にDocker ImageをPushする方法とハマリポイントを残したいと思います。

手順

下記の手順においては、実行環境にあらかじめAnsibleとDockerが導入されている前提とします

IAMポリシー作成と付与 → Dockerビルド → イメージPushの流れです

サンプルコード

以下の説明はこちらのサンプルコードをベースに説明しています
※aws/configとaws/credentialsファイルも忘れずに~

hosts

hosts
[local]
localhost ansible_connection=local

[local:vars]
region=ap-northeast-1
key_id=xxxxxxxxxxxxxx
access_key=xxxxxxxxxxxxxxx
image_name=hogehoge/fugafuga
image_version=latest

playbook

push_image.yml
---
- name: push docker image to AWS ECR Sample
  hosts: local
  tasks:
    - name: make aws directory
      file:
        dest: ~/.aws
        state: directory
        mode: u=rwx,g=,o=

    - name: copy aws config
      template:
        src: aws/config
        dest: ~/.aws/config
        mode: u=rw,g=,o=

    - name: copy aws credentials
      template:
        src: aws/credentials
        dest: ~/.aws/credentials
        mode: u=rw,g=,o=

    - name: install docker-py for build docker
      pip:
        name: docker-py
        state: present

    - name: build docker image
      docker_image: 
        path: ./
        name: "{{ image_name }}"
        tag: "{{ image_version }}"

    - name: docker login (must `--no-include-email`)
      shell: "$(aws ecr get-login --region {{ region }} --no-include-email)"
      args:
        executable: /bin/bash

    - name: install boto3
      pip:
        name: boto3
        state: present

    - name: create repository
      ecs_ecr:
        name: "{{ image_name }}"
        aws_access_key: "{{ key_id }}"
        aws_secret_key: "{{ access_key }}"
        region: "{{ region }}"
      register: ecr_repo

    - name: add tag
      docker_image:
        name: "{{ image_name }}:{{ image_version }}"
        repository: "{{ ecr_repo.repository.repositoryUri }}"
        tag: "{{ ecr_repo.repository.repositoryUri }}:{{ image_version }}"

    - name: push image to ecr
      docker_image:
        name: "{{ ecr_repo.repository.repositoryUri }}:{{ image_version }}"
        push: yes

1. IAMポリシーの作成と付与

ECRを操作するための権限(ポリシー)を作成します
以下のJSONデータをポリシー作成のJSONタブに貼り付けるか、作成画面で項目を選択してください

FireShot Capture 1 - IAM Management Console_ - https___console.aws.amazon.com_iam_.png

ひとまずすべて許可になっていますが、
必要に応じてActionResourceを絞ってください

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "ecr:*",
            "Resource": "arn:aws:ecr:*:*:repository/*"
        }
    ]
}

操作できるリポジトリ、リージョン、アカウントIDなどを制限したい場合は、
以下の"Resource": "arn:aws:ecr:ap-northeast-1:xxxxxxxx:repository/yyyyyyyyyy"という風にしてください
iam2.png

ポリシーの作成後に対象のIAMユーザに付与してください

※付与したユーザのアクセスキーとシークレットキーをサンプルコードhostskey_idaccess_keyにそれぞれ追加してください

2. AnsibleでDockerイメージのビルド

docker_imageモジュールを用いてDockerfileでイメージのビルドを行います

push_image.yml
~~ 前略 ~~

- name: build docker image
  docker_image: 
    path: ./
    name: "{{ image_name }}"
    tag: "{{ image_version }}"

3. Docker loginする(ECR経由)

--no-include-emailを入れないとunknown shorthand flag: 'e' in -eでエラーになります(ハマリポイント)
get-loginで取得されるdocker login xxxxxxに存在しないパラメータ(-e)が含まれているため

push_image.yml
~~ 前略 ~~

- name: docker login (must `--no-include-email`)
  shell: "$(aws ecr get-login --region {{ region }} --no-include-email)"

もし、ansible.cfgでexecutable=/bin/bash -lを設定している場合は、
argsで/bin/bashを追加してください(ハマリポイント)

push_image.yml
- name: docker login (must `--no-include-email`)
  shell: "$(aws ecr get-login --region {{ region }} --no-include-email)"
  args:
    executable: /bin/bash

4. ECSにリポジトリを作成

ecs_ecrモジュールはaws apiを用いるため、boto3をインストールします

push_image.yml
~~ 前略 ~~

- name: install boto3
  pip:
    name: boto3
    state: present

- name: create repository
  ecs_ecr:
    name: "{{ image_name }}"
    aws_access_key: "{{ key_id }}"
    aws_secret_key: "{{ access_key }}"
    region: "{{ region }}"
  register: ecr_repo

5. ECR用にタグ付け

ECRの「プッシュコマンドの表示」で示されているようにタグ付け(手順4)をしていきます
前述のregister(ecr_repo)に格納されているrepositoryUriを用います

push_command.png

push_image.yml
~~ 前略 ~~

- name: add tag
  docker_image:
    name: "{{ image_name }}:{{ image_version }}"
    repository: "{{ ecr_repo.repository.repositoryUri }}"
    tag: "{{ ecr_repo.repository.repositoryUri }}:{{ image_version }}"

6. イメージのpush

タグ付けしたイメージをプッシュする

push_image.yml
~~ 前略 ~~

- name: push image to ecr
  docker_image:
    name: "{{ ecr_repo.repository.repositoryUri }}:{{ image_version }}"
    push: yes
comefigo
自社クラウドサービスの開発・運用をやっています。 ここには日々のアウトプットを残したいと思います。 [Katacoda](https://www.katacoda.com/comefigo7)
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away