概要
AWS Codebuildでno basic auth credentials
というエラーに遭遇しました。
本記事ではその原因と解決方法を記載します。
エラー内容
AWS Codebuildで使うbuildspec.yml
において、以下の内容でビルドしました。
version: 0.2
phases:
pre_build:
commands:
- echo Logging in to Amazon ECR...
- aws --version
- aws ecr get-login-password --region ap-northeast-1
build:
commands:
- echo Build started on `date`
- echo Logging in to Docker Hub...
- docker login -u $USER_DOCKER -p $DOCKER_KEY
- echo Building the Docker image...
- docker build -t $REPOSITORY_URI:latest .
## 以後省略
すると、以下のエラーがCodebuildのログに表示され、失敗しました。
no basic auth credentials
原因と解決方法
同じような現象の記事を見つけました。
Can't push image to Amazon ECR - fails with "no basic auth credentials"
そちらに記載してあるとおり、
- $(aws ecr get-login --no-include-email --region $AWS_DEFAULT_REGION)
というように表記を変えたところ、このエラーがなくなり、ビルドに成功しました。
なぜこれで解決できるようになったかというと、、、
最初の方法では、
・ECRに対するDocker認証トークンを取得
・その出力を直接標準出力に表示(=出力がDockerに提供されていない)
ということが行われています。
修正後の方法では、
・AWS CLIコマンドにより、サブシェル内でECRの認証情報を取得し、その結果を実行中のシェルに埋め込む
・Docker Hubへのログインに必要なECRの認証情報が提供され、Dockerはそのトークンを使用して正常にDocker Hubにログイン
ということが行われています。
つまり、$(...)
を使用することで、コマンドの実行結果を変数に格納し、後でその変数を別のコマンドに渡す(パイプする)ことができるということです。認証情報を受け渡すには一般的な方法らしいです。
aws ecr get-login
コマンドについて
aws ecr get-login
コマンドは、Amazon ECRにログインするための認証情報を取得するコマンドです。このコマンドを実行すると、Dockerクライアントに必要な認証情報を含むdocker login
コマンドが出力されます。
このdocker login
コマンドを実行することで、Docker Hubにログインするための認証情報が提供される、という流れなのです。
しかし、DockerクライアントがDocker Hubに対して適切な認証情報を持っていないと、no basic auth credentials
というエラーが発生する、というわけです。
WARNING! Using --password via the CLI is insecure.
について
上記の方法だと、Dockerがセキュリティの警告を表示する可能性があります。この警告は、Docker CLIがパスワードをコマンドライン引数として直接受け取る(=パスワードを平文で渡す)ことはセキュリティ上のリスクであるためです。
以下のようにビルドログに表示されていました。
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
メッセージにある通り、docker login
コマンドには--password-stdin
オプションを使用することが推奨されています。これにより、パスワードは標準入力から受け取られ、セキュリティ的なリスクが軽減されます。
- aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
これにより、パスワードはコマンドライン引数ではなく、標準入力から提供されるため、セキュリティが向上すると言えるでしょう。
同様に、ビルド時のログインコマンドも以下のようにするとよりセキュアです。
- echo $DOCKER_KEY | docker login -u $USER_DOCKER --password-stdin
--password-stdinオプション
の詳細
Docker Hubなどのコンテナレジストリに対して安全に認証情報(通常はパスワード)を提供するためのDockerコマンドのオプションです。
docker login
コマンドでは、ユーザー名とパスワードをコマンドライン引数として指定します。しかし、パスワードがコマンドラインに平文で表示され、シェルの履歴やプロセスリストに含まれるとセキュリティ的によろしくないです。
ということで、このオプションが導入されたんですね。
基本的な使い方は以下になります。
echo $PASSWORD | docker login -u $USERNAME --password-stdin
echoコマンド
を使用してパスワード($PASSWORD
)を標準出力に送り、docker login
コマンドがそれを標準入力から読み取ります。これにより、パスワードがセキュアに扱われ、認証情報がコマンドラインに表示されることがなくなります。