AWS

IAMロールを使用したCodeCommitリポジトリへのクロスアカウントアクセスについて

こんにちは、かっこいいデスク環境に憧れるディーネットの山田です。(そろそろ自分の中で完成形になりつつあります)

さて、今回は異なるAWSアカウント上にあるCodeCommitから、EC2へクローンする際にIAMユーザーと紐付けたSSHキーを使っていましたが、AWSらしい使い方ができないか調べていたところ、クロスアカウントアクセスを用いることで可能だったので紹介します。

CodeDeployを使った高度なものではなく、 git clone を使ってソースをクローンし手動でデプロイする際に使いました。
ニーズが少ないかもしれませんが、ご了承ください。

目的

FTP、SCP、SFTPなどのファイル転送プロトコルを介さず、開発したソースコードをEC2上にデプロイしたい。
ソースを管理しているリポジトリとEC2が稼働しているAWSアカウントは異なるが、せっかくAWSを利用しているのでAWSらしい使い方をしたい。

構成図

イメージいただきやすいよう、簡単にですが構成図を作成しました。
RoleAとRoleBを連携させて、一時的にアカウントBのRoleA権限を使ってアカウントBのCodeCommitからクローンする形となります。

作業内容

アカウントB側でIAMポリシーを作成する

自身のもつ、CodeCommitにアクセスさせるポリシーを定義します。
以下の例では、読み取り系をすべて許可している形になります。
Resource で対象となるリポジトリを制限できます。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "codecommit:GetTree",
                "codecommit:ListPullRequests",
                "codecommit:GetBlob",
                "codecommit:GetReferences",
                "codecommit:GetPullRequestApprovalStates",
                "codecommit:DescribeMergeConflicts",
                "codecommit:ListTagsForResource",
                "codecommit:BatchDescribeMergeConflicts",
                "codecommit:GetCommentsForComparedCommit",
                "codecommit:GetCommentReactions",
                "codecommit:GetCommit",
                "codecommit:GetComment",
                "codecommit:GetCommitHistory",
                "codecommit:GetCommitsFromMergeBase",
                "codecommit:BatchGetCommits",
                "codecommit:DescribePullRequestEvents",
                "codecommit:GetPullRequest",
                "codecommit:ListAssociatedApprovalRuleTemplatesForRepository",
                "codecommit:ListBranches",
                "codecommit:GetPullRequestOverrideState",
                "codecommit:GetRepositoryTriggers",
                "codecommit:GitPull",
                "codecommit:BatchGetRepositories",
                "codecommit:GetCommentsForPullRequest",
                "codecommit:GetObjectIdentifier",
                "codecommit:CancelUploadArchive",
                "codecommit:GetFolder",
                "codecommit:BatchGetPullRequests",
                "codecommit:GetFile",
                "codecommit:GetUploadArchiveStatus",
                "codecommit:EvaluatePullRequestApprovalRules",
                "codecommit:GetDifferences",
                "codecommit:GetRepository",
                "codecommit:GetBranch",
                "codecommit:GetMergeConflicts",
                "codecommit:GetMergeCommit",
                "codecommit:GetMergeOptions"
            ],
            "Resource": "arn:aws:codecommit:{リージョン名}:{アカウントBのアカウント番号}:{リポジトリ名}"
        }
    ]
}

アカウントB側でIAMロールを作成する

以下の画像で示しておりますように、

  • アカウントAは 別のAWSアカウント ですので、信頼されたエンティティには 別のAWSアカウント を選択
  • アカウントIDは、アカウントAのものを入力
  • オプションで、 外部IDが必要 を選択し、内容には 別のAWSアカウント で(アカウントAの)他の利用者がわからないものを入力
  • アクセス権限には、先ほど作成したポリシーを適用
    を設定します。
    外部IDが必要 に関しては、必須ではありませんがこちらを設定していない場合は、 別のAWSアカウント からRole名さえわかれば利用できてしまう可能性がありますので、ご注意ください。


アカウントB側で作成したIAMロールのARNを確認する

IAMロール作成画面のウィザードを一通り進めていただいて、登録されると ロールARN を確認することができます。
ロールARN を確認してください。

アカウントA側でIAMポリシーを作成する

アカウントB側で作成したIAMロールを引き受けるポリシーを定義します。
Resource で対象となるARNを指定します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "{アカウントB側で作成したIAMロールのARN}"
        }
    ]
}

アカウントA側でEC2に割り当てるIAMロールを作成する

以下の画像で示しておりますように、

  • 割り当てる先は EC2 ですので、信頼されたエンティティには AWSサービス を選択
  • ユースケースは、 EC2 に割り当てますので、 EC2 を選択
  • アクセス権限には、先ほど作成したポリシーを適用
    を設定します。

対象のEC2インスタンスにIAMロールを割り当てる

IAMロールを割り当てたいEC2インスタンスを選択して 「アクション」をクリックする

アクションメニューから「セキュリティ」→「IAMロールを変更」の順にクリックする

対象とするEC2インスタンスが正しいことを確認して先ほど作成したIAMロールを選択する

AWS CLIへIAMロールを登録する

※ 事前にAWS CLIのインストールをお願いします。AWS CLI のインストール

Gitの認証情報をAWS CLIから取得させる設定を行う

$ aws configure --profile {好きなプロファイル名}
AWS Access Key ID [None]: {空Enter}
AWS Secret Access Key [None]: {空Enter}
Default region name [None]: {使用するリージョン}
Default output format [None]: json
$ aws configure set --profile {好きなプロファイル名} external_id {外部ID}
$ aws configure set --profile {好きなプロファイル名} credential_source Ec2InstanceMetadata
$ aws configure set --profile {好きなプロファイル名} role_arn {アカウントB側で作成したIAMロールのARN}

設定後はこんな設定が書かれました

$ cat .aws/config
[profile {好きなプロファイル名}]
output = json
region = {使用するリージョン}
external_id = {外部ID}
credential_source = Ec2InstanceMetadata
role_arn = {アカウントB側で作成したIAMロールのARN}

Gitコマンドの設定を行う

$ git config --global credential.helper '!aws --profile {好きなプロファイル名} codecommit credential-helper $@'
$ git config --global credential.UseHttpPath true

設定後はこんな設定が書かれました

$ cat .gitconfig 
[credential]
        helper = !aws --profile {好きなプロファイル名} codecommit credential-helper $@
        UseHttpPath = true

リポジトリからクローンする

$ git clone "{cloneするURL(https://)}"
Cloning into '{リポジトリ名}'...
remote: Counting objects: 18494, done.
Receiving objects: 100% (18494/18494), 20.28 MiB | 2.45 MiB/s, done.
Resolving deltas: 100% (7334/7334), done.

まとめ

  • IAMユーザーに紐付けたSSHキーを使っていましたが、どの環境のどのユーザーを設定しているか管理が面倒だったので、管理が楽になりました。
  • デプロイのためだけに、SSHの秘密鍵をたくさん管理していましたが、不要になった。
  • IAMロールを割り当てたEC2(特定のAWSアカウント内に存在する必要がある)からでないと対象のリポジトリへアクセスできないので、セキュリティ面が向上しました。

参考にさせていただいた記事

AWS CLI 認証情報ヘルパーを使用した、Linux、macOS、または UNIX 上の AWS CodeCommit リポジトリへの HTTPS 接続のセットアップ手順
リポジトリへのクロスアカウントアクセス: AccountB のリポジトリユーザーのアクション
他のAWSアカウントのEC2とCodeCommitのリポジトリを共有する
AWS CodePipelineで別アカウントのCodeCommitを利用する

返信を残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA