0. 事前にご用意いただく情報
- リージョン:
ap-northeast-1(東京) - ECRリポジトリ名:
portal-api,cron-runner(※他でもOK。portal-*で始まる名称推奨) - EKSクラスター名(既存利用または新規):例)
portal-dev - 当社AWSアカウントID:当社からお伝えします(12桁の数字)
- ExternalId:外部ID(セキュリティ用の合言葉)。英数字32桁程度のランダム文字列を作り、紙などに控えてください(例:
vnd-3Fz7K4q9...)
ExternalId は秘密情報です。作成後は当社に安全な手段でお伝えください。
1. ロール(権限の入れ物)を2つ作成します
- VendorRepoPusher:ECR(コンテナレジストリ)にpush/pullするためのロール
- VendorEKSDeployer:EKSクラスターの**情報取得(DescribeCluster)**のためのロール
※1つに統合も可能ですが、用途ごとに分ける方が分かりやすく安全です。
※両ロールとも「当社アカウント+ExternalIdを条件」にAssumeRole(引受け)できるようにします。
1-1. ExternalId の作成(ランダム文字列)
- 外部ID用に英数字32文字程度のランダム文字列を作ります(例:
VND-7cZ4mXq1P0...)。 - これを後ほどロールの信頼ポリシーに記入します。
- 完成後、当社へ共有してください(安全な手段で)。
1-2. VendorRepoPusher ロールの作成(コンソール操作)
- AWSコンソール → 右上のリージョンが ap-northeast-1 であることを確認
- サービス検索で「IAM」→ 左メニューの Roles(ロール) → Create role
- 信頼するエンティティは「Another AWS account(別AWSアカウント)」を選択
- Account ID:当社のAWSアカウントIDを入力
- Optionsの Require external ID にチェック → 先ほどの ExternalId を入力
- (MFAは不要です)
- Next を押して権限の選択へ
- 検索ボックスに
ECRと入れると標準ポリシーが並びますが、不要権限が多いため、今回はカスタムポリシーを付与します。 - いったん Skip してロールだけ先に作成し、後でアタッチします。
- 検索ボックスに
- ロール名に
VendorRepoPusherと入力 → Create role で作成
作成後:カスタムポリシーをアタッチ
- 同じくIAM左メニューの Policies → Create policy
- JSONタブに下記(ECR push/pull 最小権限)を貼り付け → Next → Policy name に
VendorRepoPusherPolicy→ Create policy
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ECRAuth",
"Effect": "Allow",
"Action": ["ecr:GetAuthorizationToken"],
"Resource": "*"
},
{
"Sid": "ECRRepositoryActions",
"Effect": "Allow",
"Action": [
"ecr:BatchCheckLayerAvailability",
"ecr:CompleteLayerUpload",
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage",
"ecr:InitiateLayerUpload",
"ecr:PutImage",
"ecr:UploadLayerPart",
"ecr:DescribeRepositories",
"ecr:ListImages"
],
"Resource": [
"arn:aws:ecr:ap-northeast-1:YOUR_ACCOUNT_ID:repository/portal-*"
]
}
]
}
YOUR_ACCOUNT_IDはお客様のAWSアカウントIDに置き換えてください。portal-*により、portal-apiやcron-runnerなど対象を簡便に指定できます。必要に応じて個別のARNに絞ってもOKです。
- 左メニュー Roles → VendorRepoPusher を開く → Attach policies →
VendorRepoPusherPolicyを選択し Attach policy
これで VendorRepoPusher 完了です。
1-3. VendorEKSDeployer ロールの作成(コンソール操作)
- IAM → Roles → Create role
- Another AWS account を選択
- Account ID:当社アカウントID
- Require external ID:チェック → ExternalId を入力
- 権限は後付けするため、一旦スキップ
- ロール名を
VendorEKSDeployerとして Create role
作成後:EKS Describe 用のカスタムポリシーをアタッチ
- IAM → Policies → Create policy → JSONタブに下記を貼り付け → ポリシー名
VendorEKSDeployerPolicy
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DescribeTargetCluster",
"Effect": "Allow",
"Action": [
"eks:DescribeCluster"
],
"Resource": "arn:aws:eks:ap-northeast-1:YOUR_ACCOUNT_ID:cluster/portal-dev"
}
]
}
portal-devは実際のEKSクラスター名に、YOUR_ACCOUNT_IDはお客様アカウントIDに置き換えてください。
クラスターが複数ある場合は、Statementを追加してください。
- Roles → VendorEKSDeployer → Attach policies →
VendorEKSDeployerPolicyをアタッチ
2. 作成後に当社へ共有いただく情報
- Role ARN(2つ)
arn:aws:iam::YOUR_ACCOUNT_ID:role/VendorRepoPusherarn:aws:iam::YOUR_ACCOUNT_ID:role/VendorEKSDeployer
- ExternalId(作成した合言葉)
- AWSアカウントID と リージョン(
ap-northeast-1) - ECRリポジトリURI(例:
YOUR_ACCOUNT_ID.dkr.ecr.ap-northeast-1.amazonaws.com/portal-api) - EKSクラスター名(例:
portal-dev)
これらを受領後、当社側で AssumeRole を使ってECRへpush/EKSへ接続確認を行います。
(Kubernetesの権限は aws-auth でマッピング後に有効になります。次章参照)
3.(参考)EKS クラスターへの権限マッピング(aws-auth)
こちらはクラスター管理者向けの作業です。
IAMの権限(DescribeCluster等)と、Kubernetesの権限(kubectlで何ができるか)は別物です。
クラスターのaws-authConfigMap に、今回のロールをK8sグループへ紐付けます。
例(vendor:portal:deployer というK8sグループへマッピング):
# kubectl edit -n kube-system configmap/aws-auth
data:
mapRoles: |
- rolearn: arn:aws:iam::YOUR_ACCOUNT_ID:role/VendorEKSDeployer
username: vendor-eks-deployer
groups:
- vendor:portal:deployer
その後、
portalNamespace にvendor:portal:deployerに対する RoleBinding を付与すると、
当社はkubectl -n portal ...で必要な操作(デプロイ等)が可能になります。
4.(自動化したい方向け)CloudFormation 一括テンプレート
コンソール操作が不安な場合、コピペで作れるテンプレートを用意しました。
使い方:
- コンソール → CloudFormation → Create stack → With new resources
- 下記YAMLを貼り付け、パラメータを入力 → 作成
AWSTemplateFormatVersion: '2010-09-09'
Description: Roles for Vendor (RepoPusher & EKSDeployer) with ExternalId trust
Parameters:
VendorAccountId:
Type: String
Description: Vendor AWS Account ID (12 digits)
ExternalId:
Type: String
Description: External ID (shared secret with vendor)
NoEcho: true
EKSClusterName:
Type: String
Description: Target EKS cluster name (e.g., portal-dev)
RepoPrefix:
Type: String
Default: portal-*
Description: ECR repository name pattern (e.g., portal-*)
Resources:
VendorRepoPusherPolicy:
Type: AWS::IAM::ManagedPolicy
Properties:
ManagedPolicyName: VendorRepoPusherPolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Sid: ECRAuth
Effect: Allow
Action: [ "ecr:GetAuthorizationToken" ]
Resource: "*"
- Sid: ECRRepositoryActions
Effect: Allow
Action:
- ecr:BatchCheckLayerAvailability
- ecr:CompleteLayerUpload
- ecr:GetDownloadUrlForLayer
- ecr:BatchGetImage
- ecr:InitiateLayerUpload
- ecr:PutImage
- ecr:UploadLayerPart
- ecr:DescribeRepositories
- ecr:ListImages
Resource:
- !Sub arn:aws:ecr:${AWS::Region}:${AWS::AccountId}:repository/${RepoPrefix}
VendorEKSDeployerPolicy:
Type: AWS::IAM::ManagedPolicy
Properties:
ManagedPolicyName: VendorEKSDeployerPolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Sid: DescribeTargetCluster
Effect: Allow
Action: [ "eks:DescribeCluster" ]
Resource:
- !Sub arn:aws:eks:${AWS::Region}:${AWS::AccountId}:cluster/${EKSClusterName}
VendorRepoPusherRole:
Type: AWS::IAM::Role
Properties:
RoleName: VendorRepoPusher
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
AWS: !Sub arn:aws:iam::${VendorAccountId}:root
Action: sts:AssumeRole
Condition:
StringEquals:
sts:ExternalId: !Ref ExternalId
ManagedPolicyArns:
- !Ref VendorRepoPusherPolicy
MaxSessionDuration: 3600
VendorEKSDeployerRole:
Type: AWS::IAM::Role
Properties:
RoleName: VendorEKSDeployer
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
AWS: !Sub arn:aws:iam::${VendorAccountId}:root
Action: sts:AssumeRole
Condition:
StringEquals:
sts:ExternalId: !Ref ExternalId
ManagedPolicyArns:
- !Ref VendorEKSDeployerPolicy
MaxSessionDuration: 3600
Outputs:
RepoPusherRoleArn:
Value: !GetAtt VendorRepoPusherRole.Arn
EKSDeployerRoleArn:
Value: !GetAtt VendorEKSDeployerRole.Arn
5. よくある質問(短く)
- Q:ECRのアクセスはこれだけで大丈夫?
A:今回の方式は**クロスアカウントではなく「お客様アカウント内のロールを当社が引き受ける」**形なので、リポジトリポリシー追加は不要です。ロールに付与した権限で push/pull できます。 - Q:ExternalId はなぜ必要?
A:なりすまし防止です。もし当社アカウントIDが漏れても、ExternalId が一致しないと AssumeRole できません。 - Q:EKSに対して kubectl で操作する権限は?
A:aws-auth でのロール→K8sグループのマッピングと、Kubernetes側のRole/RoleBindingが必要です(上記3章参照)。
6. 仕上げチェックリスト
VendorRepoPusherとVendorEKSDeployerの 2ロール作成- 両ロールの 信頼ポリシー に 当社アカウントID と ExternalId を設定
- 両ロールに カスタムポリシー をアタッチ(上記JSONまたはCFn)
- 当社へ Role ARN / ExternalId / アカウントID / リージョン / ECR URI / クラスター名 を共有
- (任意)EKSの
aws-authを更新し、K8sの権限を付与
以上です。ここまで完了すれば、当社側で安全にAssumeRoleして、
ECRへのイメージPushとEKSへのデプロイ(および/chroma/search動作確認など)の作業に着手できます。
ご不明点は画面キャプチャをいただければ、該当箇所を一緒に確認します。
コメントを残す