方式B(AssumeRole + ExternalId)

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 の作成(ランダム文字列)

  1. 外部ID用に英数字32文字程度のランダム文字列を作ります(例:VND-7cZ4mXq1P0...)。
  2. これを後ほどロールの信頼ポリシーに記入します。
  3. 完成後、当社へ共有してください(安全な手段で)。

1-2. VendorRepoPusher ロールの作成(コンソール操作)

  1. AWSコンソール → 右上のリージョンが ap-northeast-1 であることを確認
  2. サービス検索で「IAM」→ 左メニューの Roles(ロール)Create role
  3. 信頼するエンティティは「Another AWS account(別AWSアカウント)」を選択
    • Account ID:当社のAWSアカウントIDを入力
    • OptionsRequire external ID にチェック → 先ほどの ExternalId を入力
    • (MFAは不要です)
  4. Next を押して権限の選択へ
    • 検索ボックスに ECR と入れると標準ポリシーが並びますが、不要権限が多いため、今回はカスタムポリシーを付与します。
    • いったん Skip してロールだけ先に作成し、後でアタッチします。
  5. ロール名に VendorRepoPusher と入力 → Create role で作成

作成後:カスタムポリシーをアタッチ

  1. 同じくIAM左メニューの PoliciesCreate policy
  2. JSONタブに下記(ECR push/pull 最小権限)を貼り付け → NextPolicy nameVendorRepoPusherPolicyCreate 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-apicron-runner など対象を簡便に指定できます。必要に応じて個別のARNに絞ってもOKです。

  1. 左メニュー RolesVendorRepoPusher を開く → Attach policiesVendorRepoPusherPolicy を選択し Attach policy

これで VendorRepoPusher 完了です。


1-3. VendorEKSDeployer ロールの作成(コンソール操作)

  1. IAM → RolesCreate role
  2. Another AWS account を選択
    • Account ID:当社アカウントID
    • Require external ID:チェック → ExternalId を入力
  3. 権限は後付けするため、一旦スキップ
  4. ロール名を VendorEKSDeployer として Create role

作成後:EKS Describe 用のカスタムポリシーをアタッチ

  1. IAM → PoliciesCreate policyJSONタブに下記を貼り付け → ポリシー名 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を追加してください。

  1. RolesVendorEKSDeployerAttach policiesVendorEKSDeployerPolicy をアタッチ

2. 作成後に当社へ共有いただく情報

  • Role ARN(2つ)
    • arn:aws:iam::YOUR_ACCOUNT_ID:role/VendorRepoPusher
    • arn: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-auth ConfigMap に、今回のロールを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

その後、portal Namespace に vendor:portal:deployer に対する RoleBinding を付与すると、
当社は kubectl -n portal ... で必要な操作(デプロイ等)が可能になります。


4.(自動化したい方向け)CloudFormation 一括テンプレート

コンソール操作が不安な場合、コピペで作れるテンプレートを用意しました。

使い方

  1. コンソール → CloudFormation → Create stack → With new resources
  2. 下記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. 仕上げチェックリスト

  • VendorRepoPusherVendorEKSDeployer2ロール作成
  • 両ロールの 信頼ポリシー当社アカウントIDExternalId を設定
  • 両ロールに カスタムポリシー をアタッチ(上記JSONまたはCFn)
  • 当社へ Role ARN / ExternalId / アカウントID / リージョン / ECR URI / クラスター名 を共有
  • (任意)EKSの aws-auth を更新し、K8sの権限を付与

以上です。ここまで完了すれば、当社側で安全にAssumeRoleして、
ECRへのイメージPushEKSへのデプロイ(および/chroma/search動作確認など)の作業に着手できます。
ご不明点は画面キャプチャをいただければ、該当箇所を一緒に確認します。


Comments

コメントを残す

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