Afternoon Log

日々のことや、技術的な備忘録を吐き出していくつもり

CircleCI からECRへ自動push

三部作の内の第二部

あんまり覚えていないので、足りない設定とかも出てくるかも。
その時は何卒ご容赦を……。

  1. CircleCI で docker build するまで
  2. CircleCI からECRへ自動push ← イマココ
  3. CircleCI からECSへ自動デプロイ

リポジトリ用意

早速利用するリポジトリを用意していきましょう。
AWSマネジメントコンソールからECRを検索して移動します。
おっと、リージョンの選択も済ませておきましょう。
リージョンによって提供サービスの差やEC2インスタンスの価格も変わってきます。
近い方が通信速度的に良いとは思いますがユースケースから決めたら良いと思います。


遷移後、リポジトリ作成のボタンがあると思いますのでそこから作成します。
イメージタグの変更可能性は今回単純に更新していくので変更可能を選択します。
リポジトリ作成後、リポジトリ一覧にURIが表示されています。
後々リポジトリにイメージをpushする際に使用します。


CLI用アカウント用意

AWSマネジメントコンソールからIAMで検索して移動します。
Identity and Access Management の略なんですね。
ここからECRにイメージをpushするユーザーを作成します。
最初に作ったであろう自分自身のアカウントでは付与されている権限が強すぎますからね。
こういった、目的や役割に応じてアカウントを分けておくと言うのはとても大事です。

IAMユーザー作成

左サイドバーにユーザーの欄があるので、そこからユーザーの追加を行います。
大体以下の様な感じで設定していきます。
流石に僕の設定値そのままではないですが。

カラム 設定値
ユーザー名 cli
アクセスの種類 プログラムによるアクセス
グループ cli-group
(初期構築なので、作成しましょうか)

上記以外のポリシーのアタッチやタグの追加は何もせず一先ずスキップします。
これでユーザーができました。

まだこのユーザーには何の権限もありません。
なので次は権限の付与を行いますが、バイネームで権限の付与は行いません。
権限はグループに紐付けます。
権限がグループに紐付くと、ユーザーの管理運用において楽です。

グループにポリシーアタッチ

左サイドバーからグループをクリックして遷移すると、
先ほど作成したグループがあると思うのでそれをまたクリックします。
最初はユーザータブが選択されていて、
先ほど作成したユーザーが属していることが確認出来ると思います。
次にアクセス許可のタブを選択すると、
何のポリシーもアタッチされていないと思いますので
ポリシーのアタッチから付与するポリシーを選択します。
ポリシーはどういったものかというと、
適用する個々の権限をまとめ、
どのリソースにどうするか定義したものと捉えています。

今回は初めからAWSに用意されているポリシーをアタッチします。
検索枠にAmazonEC2ContainerRegistryPowerUserを入力すると該当するポリシーが出てくるので、
チェックボックス選択してポリシーのアタッチをクリックします。
これで無事にグループがECRの権限を持つことが出来ました。


CircleCIでの設定

次はCircleCIからCLIを使ってdockerイメージのpushを行います。
まずは秘密情報の設定を行います。
アカウント情報やアクセストークンなど、
知られたくない値を環境変数として設定します。
今回設定するのは以下の情報。
アクセスキーやシークレットキーは、
AWSマネジメントコンソール → IAM → ユーザー → cli(作成したユーザー) → 認証情報 から確認・生成できます。

環境変数 概要
AWS_ACCESS_KEY_ID 作成したIAMユーザーのアクセスキーID
AWS_ACCOUNT_ID アカウントID
今回では、作成したリポジトリURIの先頭
AWS_DEFAULT_REGION リポジトリを作成したリージョン
AWS_RESOURCE_NAME_PREFIX 作成したリポジトリ
AWS_SECRET_ACCESS_KEY 作成したIAMユーザーで生成したシークレットキー

これらを、
CircleCIのSetting → Projects → 連携リポジトリの設定(歯車) → Environment Variables から
Add Variable で追加していきます。
その後は、前と同様ぺたり。

.circleci/config.yml

version: 2
jobs:
  build:
    # ~~ 前回の内容なのでスキップ ~~
  push:
    docker:
      - image: circleci/node:12-stretch
    steps:
      - checkout
      - setup_remote_docker
      - attach_workspace:
          at: .
      - run:
          name: Install pip
          command: |
            curl "https://bootstrap.pypa.io/get-pip.py" -o "get-pip.py"
            sudo python get-pip.py
            sudo apt install python-dev
      - run:
          name: Load docker image
          command: docker load -i ./mu-web.tar
      - run:
          name: Install aws-cli
          command: sudo pip install awscli --upgrade
      - run:
          name: Login ECR
          command: $(aws ecr get-login --region ${AWS_DEFAULT_REGION} --no-include-email)
      - run:
          name: Tag to latest
          command: docker tag mu-web:latest ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/${AWS_RESOURCE_NAME_PREFIX}:latest
      - run:
          name: Push image to ECR
          command: docker push ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/${AWS_RESOURCE_NAME_PREFIX}:latest

workflows:
  version: 2
  pipeline:
    jobs:
      - build
      - push:
          requires:
            - build
          filters:
            branches:
              only: master

やっていることとしてはまずaws-cliをインストールしています。
そのためにpip入れたりしてみました。
python-devもインストールしないとaws-cliがインストールできないの、
地味に罠でした。
チュートリアルになかったもん!
その後作成したIAMユーザーでログインし、
latestのタグを付与して、push。
環境変数{{変数名}}で展開されます。
一部先に登録した環境変数の記述がないですが、
ログインする際に環境変数を読み取ってくれるので、
わざわざ記述する必要がないため省略しております。

また先のbuildで生成したdockerイメージを読み取っています。
そのためこのジョブを実行するために必ずbuildが必要であることをworkflowsのrequiresに書きました。

おまけで、ほいほいpushしないようにmasterブランチに限定したり。



これでECRに自動でpushできるようになったはずです。
書いたら意外と長かった。
もし設定足らずで出来てなかったら……
フィードバック貰えると助かりみ:bow: