💨

AWS CLIでECRへログインするまでの手順

2023/10/04に公開

概要

やりたいこと

  • AWS CLIでECRへのログインやイメージのプッシュを実施したい
  • 最小権限の原則に基づき、ECRへのログインやプッシュのロールのみを持つ状態でAWS CLIから操作を行えるようにしたい(管理用のIAMユーザーをAWS CLIの認証情報として使用したくない)

流れとしては、

  • スイッチロールして、作業に必要なロールを引き受けるIAMユーザーを作成する
    • このユーザーは、ロールを引き受けるポリシーのみを持つ
  • ECR操作(ログインやプッシュ)に必要なロールやポリシーを作成する
  • (作成したユーザーで)スイッチロールしてECR操作用のロールを引き受け、AWS CLIからECR操作を行う

となります。

AWS CLIについて

前提

AWS CLIの初期設定として、使用したいIAMユーザーが持つ認証情報(アクセスキーとシークレットアクセスキー)を入力します。これによって、AWS CLIは、指定したIAMユーザーの権限を使ってAWSのリソースにアクセスできるようになります。

インストールする

HomebrewでAWS CLIをインストールします。

$ brew install awscli

$ aws --version
aws-cli/2.13.21 Python/3.11.5 Darwin/21.6.0 source/arm64 prompt/off

スイッチロール用のIAMユーザーを作成する

スイッチロールとは

スイッチロールは、名前の通りIAMロールを切り替える機能のことを指します。

AWS CLIに管理用IAMユーザーの認証情報を設定することもできますが、それは推奨されません(最小権限の原則)。必要最小限の権限を付与した状態で、AWS CLIで作業を実施するのが望ましいです。それを実現するのがスイッチロールです。

スイッチロール用のIAMユーザーを用意し、そのユーザーが作業に必要な最小限のロールを引き受け、実際の作業を実施します。

IAMユーザーを作成する

AWSコンソールのIAMからユーザーを選択し、ユーザーの作成ボタンを押します。

  • ユーザーの詳細を指定
    • ユーザー名: user-for-switch(任意)
  • その他の設定は何もせずに進みます

ユーザーを作成します。

今後、このユーザーのことはuser-for-switchと呼びます。

アクセスキーを作成する

作成したユーザー(user-for-switch)のセキュリティ認証情報タブにアクセスキーという項目があります。ここからアクセスキーを作成していきます。ここで取得するアクセスキーとシークレットアクセスキーは、後程AWS CLIの設定時に使用するものです。

  • ユースケース: コマンドラインインターフェース(CLI)

アクセスキーを作成します。

アクセスキーとシークレットアクセスキーが表示されるので、安全な場所に控えておきます。

ECRを操作するためのポリシーとロールの作成

ECR操作用のIAMポリシーを作成する

  • JSONを指定して、下記を入力します
{
	"Version": "2012-10-17",
        // ECRへのログインやプッシュに必要なアクションを指定
	"Statement": [
		{
			"Effect": "Allow",
			"Action": [
				"ecr:GetDownloadUrlForLayer",
				"ecr:BatchGetImage",
				"ecr:CompleteLayerUpload",
				"ecr:UploadLayerPart",
				"ecr:InitiateLayerUpload",
				"ecr:BatchCheckLayerAvailability",
				"ecr:PutImage"
			],
                          // アクションの対象となるECRのリポジトリを指定
			"Resource": "arn:aws:ecr:ap-northeast-1:<your-account-id>:repository/test-repos"
		},
		{
			"Effect": "Allow",
			"Action": "ecr:GetAuthorizationToken",
			"Resource": "*"
		}
	]
}

ポリシーの詳細

  • ポリシー名: ECRPushAndLoginPolicy(任意)

ポリシーを作成を押します。

ECRへのログインやイメージのプッシュに必要なアクションが指定されています。アクションについての詳細説明は割愛します。

IAMロールを作成する

続いて、今作成した"ECRPushAndLoginPolicy"をアタッチするロールを作ります。

AWSコンソールのIAMからロールを選択し、ロールを作成ボタンを押します。

  • 信頼されたエンティティを選択
    • 信頼されたエンティティタイプ: AWSアカウント
    • AWSアカウント: このアカウント
  • 許可を追加
    • 許可ポリシー: さっき作成した"ECRPushAndLoginPolicy"
  • 名前、確認、および作成
    • ロール名: ECRLoginAndPushRole(任意)

信頼されたエンティティというのは、このロールを引き受けることができるリソースのことです。今回、スイッチロールすることで、user-for-switchがこのロールを引き受けます。そのため、信頼されたエンティティにはuser-for-switchを指定します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::<your-account-id>:user/user-for-switch"
            },
            "Action": "sts:AssumeRole",
            "Condition": {}
        }
    ]
}

スイッチロールするためのポリシーをユーザーにアタッチする

user-for-switchはECRを操作するためのロール(ECRLoginAndPushRole)をスイッチロールする権限を持っている必要があります。その設定を行います。

ポリシーを作成する

  • JSONを指定して、下記を入力します
{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Effect": "Allow",
			"Action": "sts:AssumeRole",
			"Resource": "arn:aws:iam::<your-account-id>:role/ECRLoginAndPushRole"
		}
	]
}
  • ポリシー名: SwitchRolePolicy

上記がECRLoginAndPushRoleを引き受けるためのポリシーです。<your-account-id>は、AWSコンソールの右上で確認できます。

ポリシーをユーザーにアタッチする

今作成したSwitchRolePolicyをuser-for-switchにアタッチします。

アタッチは、ユーザーの許可タブの許可ポリシーから追加できます。SwitchRolePolicyを選択して、ポリシーを追加します。

これによって、user-for-switchはECRLoginAndPushRoleを引き受けられるようになりました。user-for-switchはこのロールにスイッチし、最小権限の原則に基づき、ECR関連の作業を実施します。

スイッチロールして作業を実施する

AWS CLIの認証設定を行う

AWS CLIの認証設定を行います。この時に使用する認証情報は、もちろんスイッチロール用のユーザーであるuser-for-switchです。

aws configureコマンドを打ち、下記の流れで認証情報と設定を入力します。

$ aws configure
AWS Access Key ID [None]:  user-for-switchのアクセスキー
AWS Secret Access Key [None]: user-for-switchのシークレットアクセスキー
Default region name [None]: ap-northeast-1
Default output format [None]:

Default output formatでは、今後のAWS CLIのデフォルトの出力形式を指定できます。json,text,table,yamlを選択できます。デフォルトはjsonです。--outputオプションを指定することで都度都度変更できますので、なんでも良いかと思います。

認証情報が設定されたことを確認します。

$ cat ~/.aws/credentials
[default]
aws_access_key_id = user-for-switchのアクセスキー
aws_secret_access_key = user-for-switchのシークレットアクセスキー

profileの追加

~/.aws/configファイルにECRLoginAndPushRole用のprofileを追加します。

profileとは、AWSサービスやリソースにアクセスするための認証情報&設定をまとめたものです。profileを設定することで、複数のAWS環境やアカウントを簡単に切り替えることができます。具体的には、aws cliコマンドに--profileオプションを付与すると、profileに設定した認証情報や設定に基づいてコマンドが実行されます。

~/.aws/configファイルを開き、以下のprofileを追加します。

[profile ECRLoginAndPushRoleProfile]
role_arn = arn:aws:iam::<your-account-id>:role/ECRLoginAndPushRole
source_profile = default

スイッチロールできるかを確認する

aws sts get-caller-identityコマンドを使って、スイッチロールが成功しているか確認します。

このコマンドは、現在AWSサービスにリクエストを誰が(何が)行っているのかを確認するものです。”誰が”にあたるものとして、IAMユーザー、IAMロール、AWSサービスなどがあります。

$ aws sts get-caller-identity --profile ECRLoginAndPushRoleProfile
{
    "UserId": "<role-id>:botocore-session-1696192666",
    "Account": "<your-account-id>",
    "Arn": "arn:aws:sts::<your-account-id>:assumed-role/ECRLoginAndPushRole/botocore-session-1696192666"
}
$ aws sts get-caller-identity                                     
{
    "UserId": "<user-id>",
    "Account": "<your-account-id>",
    "Arn": "arn:aws:iam::<your-account-id>:user/user-for-switch"
}

以後、ECRへのログインやプッシュ等の操作は、--profile ECRLoginAndPushRoleProfileを付与して行います。

ECRへログインする

下記コマンドを入力し、ECRにログインします。
※ リージョンはap-northeast-1にしていますが、必要に応じて置き換えてください。

ログインに成功しました。

$ aws ecr get-login-password --region ap-northeast-1 --profile ECRLoginAndPushRoleProfile | docker login --username AWS --password-stdin <your-account-id>.dkr.ecr.ap-northeast-1.amazonaws.com

Login Succeeded

Logging in with your password grants your terminal complete access to your account. 
For better security, log in with a limited-privilege personal access token. Learn more at https://docs.docker.com/go/access-tokens/

試しに、--profile ECRLoginAndPushRoleProfileを付与せずにログインしてみます。

期待通り、アクセスが拒否されました。

$ aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin <your-account-id>.dkr.ecr.ap-northeast-1.amazonaws.com

An error occurred (AccessDeniedException) when calling the GetAuthorizationToken operation: User: arn:aws:iam::<your-account-id>:user/user-for-switch is not authorized to perform: ecr:GetAuthorizationToken on resource: * because no identity-based policy allows the ecr:GetAuthorizationToken action
Error: Cannot perform an interactive login from a non TTY device

Discussion