DockerでAWSのECRへのログインを省略するコマンド(エイリアス)の作成方法を実例で解説|ECRにイメージをプッシュする方法(バージョンv1とv2対応)

aws-prograshi(プロぐらし)-kv AWS
記事内に広告が含まれていることがあります。

AWSのECRにコマンドラインからログインするには以下のような長ったらしいコマンドを入力する必要があります。

$ aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 111111111111.dkr.ecr.ap-northeast-1.amazonaws.com

しかも、AWSのECRにログインするにはAWS CLIのバージョンが1(v1)かそれ以上(v2など)かでログイン方法が異なります。

ここでは、AWS CLIのv1とv2以上に対応したECRへのログインを、たった一つのコマンド「aws-login」で実行できるようにし、

更に、AWSへのログインとECRへのイメージのプッシュを「push-image」のたった1つのコマンドで実行できるようにする方法についてまとめています。


作業の流れ

作業流れは大きく以下の2ステップです。

作業手順
  1. AWS ECRへのログインのエイリアス「aws-login」を作成する。
  2. AWSにログインし、ECRにイメージをプッシュする「img-push」を作成する。


AWS ECRへのログインコマンドのエイリアスの作成

概要

初めに、AWSのECRにログインする処理を作成します。

AWSのECRへのログインは、aws-cliのawsコマンドで行います。

ただしAWS CLIのバージョンがv1の場合は、AWSに直接ログインする必要がありますが、バージョン2からはdocker経由でログインする必要があります。

このコマンドを実行する人がどちらのAWS CLIのバージョンを使っているかがわからないため、どちらの環境にも合わせられるよう、条件分岐を使って記述します。


コード全体像

作成するコードは以下となります。ここでは、エイリアスをまとめたシェルファイル「aliases.sh」を作成し、その中に記述していきます。

function login-aws() {
  version=$(echo $(aws --version 2>&1) | sed -e 's/aws-cli\/\([0-9]\{1,\}\).*/\1/')
  if [[ $version -eq 1 ]]; then
    $(aws ecr get-login --no-include-email --region ap-northeast-1)
  elif [[ $version -ge 2 ]]; then
    aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 111111111111.dkr.ecr.ap-northeast-1.amazonaws.com
  else
    echo "Error: could not detect aws command version."
    return 1
  fi
}

以下でそれぞれのコードの内容を解説しています。

aws-cliのバージョン情報を取得

最初の処理でaws-cliのバージョン情報を取得しています。

version=$(echo $(aws --version 2>&1)

aws --version
awsはaws-cliのコマンドです。

「–version」オプションでAWS CLIのバージョン情報を取得します。


2>&1
エラーがあった場合も標準出力に表示するための記述です。

記号内容
2標準エラー出力
>リダイレクト(上書き)
&ファイル指定子
1標準出力
point

リダイレクト(>)の後には通常ファイル名がきます(例 2>test.txt)。

標準出力や標準エラー出力(ファイルディスクリプタ)を指定する場合には「ファイルではない」ということを意味する「&」をつける必要があります。


実例

$ echo $(aws --version 2>&1)
aws-cli/2.0.44 Python/3.7.4 Darwin/19.6.0 exe/x86_64


aws-cliのメジャーバージョン情報のみ取得する

上記の処理で取得できるのは、aws-cliのフルの情報です。

ですが、AWSへのログインをAWS CLIのバージョンによって切り分けるために必要な情報は「aws-cliのメジャーバージョン情報のみ」です。

このため、メジャーバージョンのみを取得する処理を書きます。

例えば、「aws –version」コマンドで出力された、aws-cliのバージョンが「aws-cli/2.0.44 Python/3.7.4 Darwin/19.6.0 exe/x86_64
」なら、バージョン情報の2.0.44の冒頭の2のみ取得するということです。

sed -e 's/aws-cli\/\([0-9]\{1,\}\).*/\1/'

受け取ったデータに対し、sコマンドで置換を行っています。

aws-cli/([0-9]{1,}).*
aws/cliの後に数字が1文字以上繰り返し、その後に任意の文字が1つ以上続くパターンを検出しています。

\1
処理の中の一つ目のカッコ( )の中身を抽出する記述です。冒頭のバージョン0~99 (3桁以上もOK) を抜き出します。

sedコマンドとは何か?

指定のファイルや前から渡されたデータに対してコマンドを実行する。
置換、抽出、削除ができる。

sed [オプション] コマンド [ファイルパス]

-eオプション: expression
この後ろの引数が式になる。式が一つの場合は省略できる。

・置換する
置換する場合はsコマンドを使う

sed 's/(置換前の文字パターン)/(置換後の文字パターン)/'


実例

$ echo $(aws --version 2>&1)
aws-cli/2.0.44 Python/3.7.4 Darwin/19.6.0 exe/x86_64

$ echo $(aws --version 2>&1) | sed -e 's/aws-cli\/\([0-9]\{1,\}\).*/\1/'
2


ver1の時のログイン処理

検出したaws-cliのバージョン情報が、ver1だった場合のログイン処理を記述します。

  if [[ $version -eq 1 ]]; then
    $(aws ecr get-login --no-include-email --region ap-northeast-1)

・条件分岐
if [[ 条件式 ]]; then 処理

-ep: イコール。取得したバージョン情報が1なら以下の、ecrのget-loginコマンドを実行します。

$ aws ecr get-login --no-include-email --region ap-northeast-1


ver2以上のログイン処理

検出したaws-cliのバージョン情報が、ver2以上だった場合のログイン処理を記述します。v2以上ではdockerからログインできます。

elif [[ "$version" -ge 2 ]]; then
    aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 111111111111.dkr.ecr.ap-northeast-1.amazonaws.com

-ge: 以上。(Greater than or Equal)

ver1と異なり、ecrのログインパスワードを取得して、dockerからAWSにログインします。

$ aws ecr get-login-password --region ap-northeast-1

実行すると以下のようになります。

$ aws ecr get-login-password --region ap-northeast-1
1xM1A1aEpJdjlVeGw3VT~~~~~~~

この処理で表示されたログインパスワードを、「|」で次の処理に渡します。

$ docker login --username AWS --password-stdin 111111111111.dkr.ecr.ap-northeast-1.amazonaws.com


バージョン情報が取得できなかった場合の処理

バージョン情報が取得できなかった場合の処理(AWS CLIがインストールされていない場合)も記述しておきます。

  else
    echo "Error: could not detect aws command version."
    return 1

バージョン情報が取得できなかった場合は、エラーメッセージ「Error: could not detect aws command version.」を表示して、終了ステータス1(強制終了)で処理を終わります。


以上でAWSのECRにログインするコマンドは完成です。関数名の「login-aws」を実行すれば、実行環境のAWS CLIのバージョンに合わせてログインすることができます。


AWSにログインし、ECRにイメージをプッシュするエイリアスの作成

続いて、AWSのECRログイン後に、指定したレポジトリにイメージをプッシュ処理を記述します。

コードの全体像

コードの全体像は以下のようになります。

alias push-image="login-aws && \
  docker tag image:latest 111111111111.dkr.ecr.ap-northeast-1.amazonaws.com/repository-name:latest && \
  docker push 111111111111.dkr.ecr.ap-northeast-1.amazonaws.com/reposirory-name:latest"

それぞれの処理を以下で解説しています。


エイリアスの作成

以下のようにすることで、指定した処理を、指定したエイリアス名で登録し、エイリアス名のみで処理を実行することができるようになります。

alias エイリアス名=処理

ここでは、「push-image」という名前をつけています。

alias push-image=処理


AWS ECRにログインする

先ほど作成したAWSへのログインコマンドを実行し、AWSのECRにログインします。

login-aws


&& \

AWSへのログインコマンドの後ろに「&&」と「\(バックスラッシュ)」を付けています。

「&&」の後ろに、次に実行するコマンドを記述することができます。

「\(バックスラッシュ)」は改行です。


dockerイメージ名を変更する

ECRにイメージをプッシュするためには、Dockeイメージ名の名前を、ECRのエンドポイントとレポジトリ名をと合わせる必要があります。(※ECRはイメージ名でどのレポジトリのものかを判断するため)

  docker tag image:latest 111111111111.dkr.ecr.ap-northeast-1.amazonaws.com/repository-name:latest


docker tagの使い方

イメージ名を変更するには「docker tag」コマンドを使います。

$ docker tag <元のイメージ名> <変更後のイメージ名>

上記のようにすることで、指定したイメージの名前を変更することができます。

タグも指定する場合は「イメージ名:タグ名」のように「:」をつけてタグ名を記載します。


ECRのエンドポイント名(レポジトリ名)

ECRのエンドポイント(レポジトリのありか)は以下のように記述します。

[awsレジストリのid].dkr.ecr.[awsのリージョン].amazonaws.com


処理の内容

docker tagコマンドにより以下のようにイメージ名が変更となります。

変更前のイメージ名

image:latest

イメージ名は「image」、タグ名は「latest」です。

イメージ名とタグ名はDockerでビルドしたときに指定している名前にしてください。

 ↓ 変更後

111111111111.dkr.ecr.ap-northeast-1.amazonaws.com/repository-name:latest

イメージ名がECRのエンドポイントの名前に置き換わります。タグ(latest)はそのままです。


イメージをプッシュする

最後に、作成したイメージを「docker push」コマンドで、ECRのレジストリにプッシュする処理を記述します。

docker push 111111111111.dkr.ecr.ap-northeast-1.amazonaws.com/repository-name:latest"


ECRの中のdocker push

AWSのECRにログインしている状態で「docker push」を行った場合、イメージ名からどのECRのどのレポジトリかを判断して、イメージをプッシュします。

docker push [ホスト名]/[レポジトリ名]:タグ名

レポジトリが深い階層にある場合は、/でディレクトリ構造を指定します。


コマンドの全体像と実行方法

コマンドの全体像

上記の2つの処理を組み合わせると「aliases.sh」ファイルの中身は以下のようになります。

alias push-image="login-aws && \
  docker tag image:latest 111111111111.dkr.ecr.ap-northeast-1.amazonaws.com/repository-name:latest && \
  docker push 111111111111.dkr.ecr.ap-northeast-1.amazonaws.com/reposirory-name:latest"


function login-aws() {
  version=$(echo $(aws --version 2>&1) | sed -e 's/aws-cli\/\([0-9]\{1,\}\).*/\1/')
  if [[ $version -eq 1 ]]; then
    $(aws ecr get-login --no-include-email --region ap-northeast-1)
  elif [[ $version -ge 2 ]]; then
    aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 111111111111.dkr.ecr.ap-northeast-1.amazonaws.com
  else
    echo "Error: could not detect aws command version."
    return 1
  fi
}


シェルファイルのリロード

シェルファイルを変更した場合は、コマンド実行前にファイルをリロードする必要があります。

リロードは「source」コマンドを使ってファイルパスを指定します。

$ source <リロードするファイルパス>

実例

$ source aliases.sh

これで、シェルファイルの内容が読み込まれ、「aws-login」と「push-image」のコマンドが使えるようになります。


コマンドの実行

作成した「push-image」コマンドを実行します。

$ push-image
Login Succeeded
The push refers to repository [111111111111.dkr.ecr.ap-northeast-1.amazonaws.com/repository-name]
e14d7e1febc9: Preparing 
df3dbc632729: Preparing 
ad171ae561d6: Preparing 

(省略)

ddcd8d2fcf7e: Layer already exists 
87c8a1d8f54f: Layer already exists 
latest: digest: sha256:8************************c size: 10326

イメージのpushが完了しました。


ECRでイメージを確認

最後に、ECRの指定したレポジトリの中にプッシュしたイメージが入っているか確認します。

指定したタグでイメージが保存されていることがわかります。

以上で完了です。

タイトルとURLをコピーしました