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ステップです。
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 | 標準出力 |
実例
$ 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の指定したレポジトリの中にプッシュしたイメージが入っているか確認します。
指定したタグでイメージが保存されていることがわかります。
以上で完了です。