他のAWSアカウントのEC2とCodeCommitのリポジトリを共有する
やりたいこと
- 自分の所属するAWSアカウント(アカウントAと呼ぶ)にあるCodeCommitのリポジトリを他のAWSアカウント(アカウントBと呼ぶ)の下にあるEC2からアクセスできるようにする
- IAMのアクセスキーやCodeCommit用のIDとパスワードの受け渡しはせずに、アクセス認可を与えたい
CodeCommitを持っているAWSアカウントAでの作業
IAMポリシーの作成
CodeCommitへのアクセスを許可するIAMポリシーを作成します(図の1)。
Resource
のAWSアカウントID部分とリポジトリ名は適宜変更してください。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "codecommit:BatchGet*", "codecommit:DescribePullRequestEvents", "codecommit:Get*", "codecommit:GitPull", "codecommit:List*" ], "Resource": "arn:aws:codecommit::123456789012:REPOSITORY-NAME" } ] }
IAMロールの作成
共有先AWSアカウントを信頼するアカウントとするIAMロールを作成します(図の2)。
先に作成したIAMポリシーをロールにアタッチします。作成したIAMロールのARN arn:aws:iam::123456789012:role/CodeCommitReadonly
をアカウントBに伝えてください。
アカウントB(リポジトリを共有される側)での作業
アカウントAからのIAMロールを引き受けられるようにするIAMロールの作成
作業1、2によりアカウントAはアカウントBを信頼しているのですが、アカウントBのEC2はアカウントAのロールを引き受けられない状態になっています。これは意図しないロールを勝手に引き受けないようにして、権限を最小にするためです。
アカウントAから提供されたロールを引き受ける(sts:AssumeRole
)ためのIAMポリシーとIAMロールを作成します(図の3)。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::123456789012:role/CodeCommitReadonly" } ] }
IAMロールのEC2へのアタッチ
EC2インスタンスにアカウントBで作成した作成したロールを設定します(図の4)。ロールの指定はEC2インスタンス作成時または、インスタンス生成後の設定のいずれでも可能です。
AWS CLIへのIAMロールの登録
AWS CLIはプロファイルを切り替えることで、複数のロールを切り替えることができます。
~/.aws/config
にCodeCommitアクセス用のプロファイル(ここではCrossAccountAccessProfile
)を作成し、アカウントAから提供されたロールを登録します(図の5)。external_id=
の行はアカウントAのIAM Roleロールで外部IDを必要とする場合のみ記載してください。
[profile CrossAccountAccessProfile] region=ap-northeast-1 role_arn=arn:aws:iam::123456789012:role/CodeCommitReadonly external_id=EXTERNAL-ID credential_source=Ec2InstanceMetadata
Gitの認証情報をAWS CLIから取得させる設定
下記コマンドを実行すれば、Gitの認証情報をAWS CLIから取得するようにできます(図の6)
git config --global credential.helper '!aws --profile CrossAccountAccessProfile codecommit credential-helper $@' git config --global credential.UseHttpPath true
リポジトリへのアクセス
ここまで来れば、アカウントBのEC2からアカウントAのCodeCommitリポジトリへアクセスすることが可能です。 認証情報は自動的に取得されます(図の7)。認証情報を要求された場合、設定に誤りがある可能性があります。
git clone https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/REPOSITORY-NAME
アカウントBでの作業を自動化するCloudFormationテンプレート
アカウントBでの作業が煩雑なので、自動化するテンプレートを作成しました。 IAMポリシーとロールの作成、EC2インスタンスの作成やGitとAWS CLIとの連携等全て自動で行えます。
AWSTemplateFormatVersion: 2010-09-09 Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: Role for cross account access Parameters: - AssumeRoleARN - AssumeRoleExternalID - Label: default: EC2 server config Parameters: - Server1AMI - Server1InstanceType - Server1SubnetID - Server1UserName - Server1KeyName ParameterLabels: AssumeRoleARN: default: ARN of external IAM role AssumeRoleExternalID: default: External ID of external IAM role Server1AMI: default: AMI ID of Server1 Server1InstanceType: default: Instance type of server 1 Server1SubnetID: default: Subnet of server 1 Server1UserName: default: Username of server 1 Server1KeyName: default: Secret key name of server 1 Parameters: AssumeRoleARN: Description: ARN of IAM role which allows to access CodeCommit repository in external AWS account. Type: String Default: arn:aws:iam::123456789012:role/CodeCommitReadonly AssumeRoleExternalID: Type: String Server1InstanceType: Type: String Default: t2.medium Server1SubnetID: Type: AWS::EC2::Subnet::Id Description: e.g. subnet-0123456789abcdef Server1UserName: Type: String Default: ec2-user Server1KeyName: Type: AWS::EC2::KeyPair::KeyName LatestAmiId: Type : 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>' Default: /aws/service/ami-amazon-linux-latest/amzn-ami-hvm-x86_64-gp2 Resources: EC2Server1: Type: AWS::EC2::Instance Properties: ImageId: !Ref LatestAmiId IamInstanceProfile: !Ref InstanceProfileAllowCodeCommit InstanceType: !Ref Server1InstanceType KeyName: !Ref Server1KeyName Tags: - Key: Name Value: Server 1 BlockDeviceMappings: - DeviceName: /dev/xvda Ebs: VolumeSize: 30 VolumeType: gp2 UserData: Fn::Base64: !Sub | #! /bin/bash yum update -y yum install -y git sudo -u ${Server1UserName} git config --global credential.helper '!aws --profile CrossAccountAccessProfile codecommit credential-helper $@' sudo -u ${Server1UserName} git config --global credential.UseHttpPath true mkdir -p ~${Server1UserName}/.aws touch ~${Server1UserName}/.aws/config chown ${Server1UserName}: ~${Server1UserName}/.aws chown ${Server1UserName}: ~${Server1UserName}/.aws/config echo "[profile CrossAccountAccessProfile]" >> ~${Server1UserName}/.aws/config echo "region=ap-northeast-1" >> ~${Server1UserName}/.aws/config echo "role_arn=${AssumeRoleARN}" >> ~${Server1UserName}/.aws/config echo "external_id=${AssumeRoleExternalID}" >> ~${Server1UserName}/.aws/config echo "credential_source=Ec2InstanceMetadata" >> ~${Server1UserName}/.aws/config InstanceProfileAllowCodeCommit: Type: AWS::IAM::InstanceProfile Properties: Roles: - !Ref IAMRoleAccessToExternalCodeCommit IAMRoleAccessToExternalCodeCommit: Type: AWS::IAM::Role Properties: RoleName: RoleAllowAccessToExternalCodeCommit AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Principal: Service: - "ec2.amazonaws.com" Action: - "sts:AssumeRole" Path: "/" IAMPolicyAccessToExternalCodeCommit: Type: AWS::IAM::Policy Properties: PolicyName : PolicyAllowAccessToExternalCodeCommit PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: sts:AssumeRole Resource: !Ref AssumeRoleARN Roles : - !Ref IAMRoleAccessToExternalCodeCommit