マルチアカウント環境でAWS Service Catalogを利用する

記事タイトルとURLをコピーする

3月よりIE課(インターナルエデュケーション課) に異動しました山﨑です。

今回はマルチアカウント環境でAWS Service Catalog を利用する方法について整理していきます。

先に結論

気付けばめちゃくちゃ長いブログになっていたので、先に結論を書きます。

  • ユーザ目線
    • 数クリックですぐにAWSリソースをデプロイできるのでやはりラクチン
    • 製品の起動以外は権限をほぼ持っていないので、AWS初級者でも誤操作の心配がない
  • 管理者目線
    • CloudFormation にそれなりに精通している必要がある
    • 事前準備が結構大変なので、慣れが必要

おさらい

AWS Service Catalog とは

AWS Service Catalog とはAWS上で承認されたITサービス(AWSサービス)のカタログを作成、管理することができるサービスです。

AWS Service Catalog には「ポートフォリオ」「製品」「アクセス」「制約」「タグ」「TagOptions」「共有」といった構成要素があります。詳細については以下のブログをご覧ください。

blog.serverworks.co.jp

想定しているマルチアカウント環境について

アカウント構成

検証環境

  • Foundation OU配下に役割に応じて3つのOUを構成
    • 情報システム部門が管轄する「Core OU」
    • 各事業部門が利用するシステムを管理する「Workload OU」
    • 情報システム部門または各事業部門が検証目的で利用するAWSアカウントを配置する「Sandbox OU」
  • AWS Service Catalog を利用するにあたっては3つのAWSアカウントを利用
    • AWS Service Catalog の権限をManagement Account から委任し、カタログを管理する「Catalogアカウント」
    • エンドユーザーがSandboxアカウントにSSOログインするためのIDを管理する「SSOアカウント」
    • エンドユーザーが製品を起動し、各種検証を実施する「Sandboxアカウント」

現場の声(管理者)

  • 各事業部門にはSandboxアカウントを活用して検証を行い、AWSをどんどん活用していってほしい
  • 一方で、Sandboxアカウントでユーザーへ広い権限を持たせすぎると、管理外の野良リソースが増えて不要なコスト増加に繋がる懸念がある
  • AWS利用に慣れていないユーザーの場合、検証時にセキュリティリスクが生じる(例:Security Groupにおいて「0.0.0.0/0」でSSHポートを開放してしまう)懸念があるので、管理者側である程度の統制を取りたい(ガードレールを敷きたい)

現場の声(エンドユーザー)

  • SandboxアカウントでVPCやEC2を構築して検証作業をする機会が増えてきた
  • 検証作業を実施する度にVPCやEC2等のAWSリソースを一から構築するのが面倒なので省力化したい

今回はVPCの構築においてAWS Service Catalog を用いて管理者側のニーズ(統制を取りたい)とエンドユーザー側のニーズ(省力化したい)を実現してみたいと思います。

マルチアカウント環境でAWS Service Catalogを実装してみる

各種アカウントでの作業概要

Management Account

項番 作業内容 備考
1 AWS Service Catalog と IAM Identity Center について統合と委任を実施

SSOアカウント

項番 作業内容 備考
1 ユーザーおよびグループの作成
2 アクセス許可セットの作成
3 Sandboxアカウントへユーザーまたはグループとアクセス許可セットを関連付け

Sandboxアカウント

項番 作業内容 備考
1 IAMロールの作成
2 TagOptionsの有効化 Catalogアカウントでの作業完了後に実施

Catalogアカウント

項番 作業内容 備考
1 ポートフォリオの作成
2 製品の作成とポートフォリオへの関連付け
3 IAMロールの作成
4 ポートフォリオの設定(制約)
5 ポートフォリオの設定(TagOptions)
6 ポートフォリオの設定(アクセス)
7 ポートフォリオの設定(共有)

実作業(Management Account)

①AWS Service Catalog と IAM Identity Center について統合と委任を実施

Management Account で CloudShell を起動し、以下のCLIコマンドを実行します

aws organizations enable-aws-service-access --service-principal servicecatalog.amazonaws.com
aws organizations enable-aws-service-access --service-principal sso.amazonaws.com

aws organizations register-delegated-administrator --account-id <CatalogアカウントのアカウントID> --service-principal servicecatalog.amazonaws.com
aws organizations register-delegated-administrator --account-id <SSOアカウントのアカウントID> --service-principal sso.amazonaws.com

実作業(SSOアカウント)

IAM Identity Center の操作方法については本ブログのテーマから離れますので、作業ごとにご案内しているAWSドキュメントをご覧ください。

①ユーザーおよびグループの作成

今回はIAM Identity Center が提供するIDストアを利用して、ユーザーを作成します。

docs.aws.amazon.com

②アクセス許可セットの作成

今回はAWS Service Catalogのエンドユーザー機能へのフルアクセスを提供する「AWSServiceCatalogEndUserFullAccess」をポリシーとしてアタッチした、アクセス許可セットを作成します

docs.aws.amazon.com

③Sandboxアカウントへユーザーまたはグループとアクセス許可セットを関連付け

①②で作成したユーザーとアクセス許可セットをSandboxアカウントに割り当てます。

Sandboxアカウントへの割り当て①
Sandboxアカウントへの割り当て②

これらの作業を実施することで、エンドユーザーがIAM Identity Center 経由でSandboxアカウントにシングルサインオンでアクセスすることができるようになります。ちなみにシングルサインオンをする際に利用するアクセスポータルURLはIAM Identity Center の設定画面から確認できます。

アクセスポータルURLの確認画面
シングルサインオンの画面

実作業(Sandboxアカウント)

①IAMロールの作成

ここで作成するIAMロールは、AWS Service Catalog の製品を起動してCloudFormationをデプロイする際に許可する権限を定義したロールです。

通常、AWS Service Catalog の製品はAWSアカウントにログインしているIAMユーザー/IAMグループ/IAMロール(スイッチロールの場合)で許可されている権限の範囲内でデプロイされます。例えば、AWSアカウントにIAMユーザーの認証情報を用いてログインしているとします。この場合は製品の起動でVPCをデプロイしたければ、IAMユーザーにVPCの構築権限を付与する必要があります。

今回はエンドユーザーには極力不要な権限を与えたくないため、別途作成したIAMロールの権限をAWS Service Catalog が引き受けて製品をデプロイできるようにします。今回は「CreateEC2RoleForServiceCatalog」と命名したIAMロールを作成します。

IAMポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "cloudformation:CreateStack",
                "cloudformation:DeleteStack",
                "cloudformation:DescribeStackEvents",
                "cloudformation:DescribeStacks",
                "cloudformation:GetTemplateSummary",
                "cloudformation:SetStackPolicy",
                "cloudformation:ValidateTemplate",
                "cloudformation:UpdateStack",
                "ec2:*",
                "s3:GetObject",
                "servicecatalog:*",
                "sns:*"
            ],
            "Resource": "*"
        }
    ]
}
信頼関係
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Principal": {
                "Service": "servicecatalog.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

実作業(Catalogアカウント)

「ポートフォリオの作成」「製品の作成とポートフォリオへの関連付け」の作業手順については以下のブログで整理しているため割愛します。

AWS Service Catalog を基礎から学ぶ - サーバーワークスエンジニアブログ

今回製品として登録するCloudFormationテンプレートについては以下の通りです。VPCネットワークの各種コンポーネント(VPC/Publicサブネット/Protectedサブネット/各種ルートテーブル/IGW/NGW)を作成するテンプレートです。

AWSTemplateFormatVersion: '2010-09-09'
Description: A sample template for the service catalog

Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/24
      EnableDnsSupport: 'true'
      EnableDnsHostnames: 'true'
      Tags:
        - Key: Name
          Value: vpc-staging-env
  PublicSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.0.0/27
      AvailabilityZone: ap-northeast-1a
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: subnet-staging-env-public-a

  ProtectedSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.0.32/27
      AvailabilityZone: ap-northeast-1a
      MapPublicIpOnLaunch: false
      Tags:
        - Key: Name
          Value: subnet-staging-env-protected-a

  IGW:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: igw-staging-env
  
  VPCGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref IGW

  RouteTablePublic:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: rtb-staging-env-public

  MyRoutePublic:
    Type: AWS::EC2::Route
    DependsOn: VPCGatewayAttachment
    Properties:
      RouteTableId: !Ref RouteTablePublic
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref IGW

  SubnetRouteTableAssociationPublic:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet
      RouteTableId: !Ref RouteTablePublic

  MyEIP:
    Type: AWS::EC2::EIP

  MyNGW:
    Type: AWS::EC2::NatGateway
    Properties:
      SubnetId: !Ref PublicSubnet
      AllocationId: !GetAtt MyEIP.AllocationId
      Tags:
        - Key: Name
          Value: ngw-staging-env-a

  MyRouteTableNatA:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: rtb-staging-env-nat-a

  MyRouteNat:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref MyRouteTableNatA
      DestinationCidrBlock: 0.0.0.0/0
      NatGatewayId: !Ref MyNGW

  MySubnetRouteTableAssociationProtectedA:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref ProtectedSubnet
      RouteTableId: !Ref MyRouteTableNatA

Outputs:
  VPCCIDR:
    Value: !GetAtt VPC.CidrBlock
  PublicCIDR:
    Value: !GetAtt PublicSubnet.CidrBlock
  PublicSubnetId:
    Description: 'The ID of the created subnet'
    Value: !Ref PublicSubnet
    Export:
      Name: PublicSubnetId
  ProtectedCIDR:
    Value: !GetAtt ProtectedSubnet.CidrBlock
  ProtectedSubnetId:
    Description: 'The ID of the created subnet'
    Value: !Ref ProtectedSubnet
    Export:
      Name: ProtectedSubnetId

③IAMロールの作成

Sandboxアカウントで作成したIAMロール「CreateEC2RoleForServiceCatalog」と同名のIAMロールを作成します。このIAMロールに対して何かポリシーをアタッチする必要はありません。ここでIAMロールを作成する理由は後述します。

④ポートフォリオの設定(制約)

ポートフォリオに対して「起動制約」を設けます。「起動制約」では指定したIAMロールに割り当てられた権限の範囲内で製品を起動させることができます。今回はメソッドとして「ロール名の入力」を選択し、Sandboxアカウントで作成したIAMロール名「CreateEC2RoleForServiceCatalog」を入力します。1つ前の手順でIAMロールを作成しましたが、Catalogアカウント上に「CreateEC2RoleForServiceCatalog」がないとエラーとなるため予め作成しておく必要があります。

⑤ポートフォリオの設定(TagOptions)

TagOptions とは、製品を起動してデプロイするAWSサービスに付与するタグのテンプレート群であり、ポートフォリオに関連付けることでタグの付与を強制することができます。

TagOptions を利用するためには予め「TagOptions ライブラリ」にタグのテンプレートを登録しておく必要があります。今回はコスト配分タグによるAWS利用料の追跡ができるよう、以下のタグをTagOptions ライブラリに追加します。

  • env: dev
  • division: business-unit1

TagOptions ライブラリ

TagOptions ライブラリにタグを追加したら、ポートフォリオの詳細画面からTagOptions タブを開いて付与するタグを関連付けます。

TagOptions でのタグの関連付け

⑥ポートフォリオの設定(アクセス)

ポートフォリオへのアクセス権をエンドユーザー付与します。IAM Identity Center を利用したシングルサインオンの場合は「AWSReservedSSO_{アクセス許可セット名}_xxxxxxxxxx」というIAMロールに対してスイッチロールすることで該当のAWSアカウントへアクセスします。そのため該当のIAMロールに対してアクセスを許可します。

アクセス権を付与
アクセスタイプとプリンシパル名の指定

これまではプリンシパル名は完全一致で指定する必要がありましたが、2023年5月31日のアップデートでワイルドカード(*)が使用できるようになったため、AWSアカウント間でのポートフォリオの共有がとても楽になりました。今回はアクセス許可セット名が「ServiceCatalogAccess」なのでプリンシパル名には「*AWSReservedSSO_ServiceCatalogAccess_*」を指定しています。

⑦ポートフォリオの設定(共有)

最後にポートフォリオをSandboxアカウントに共有することで、Sandboxアカウント上で製品を表示できるようにします。

ポートフォリオの共有タブ
共有するAWSアカウントを指定

「設定を共有」で「TagOption の共有」と「プリンシパル共有」にチェックを入れて有効化します。

設定を共有

Sandboxアカウントにてもうひと仕事

②TagOptionsの有効化

CatalogアカウントでTagOptionsを有効化してSandboxアカウントへ共有設定を行いましたが、SandboxアカウントにてTagOptionsの移行作業を実施する必要があります。

TagOptionsの移行

製品を起動してみる

ここまで色々と準備をしてきましたが、ようやく製品を起動できるところまでやってきましたので、早速起動してみます。

製品の起動画面

起動が成功し、CloudFormation テンプレートに従って各種VPCネットワークが構築されていることが確認できました!ちなみにエンドユーザーにはVPC閲覧権限を付与していないので、確認自体はAdministratorAccess権限を持った別のIAMユーザーで確認しました。

VPCのResource Map

まとめ

今回は以前から気になっていたマルチアカウント環境でのAWS Service Catalog 利用について検証してみました。

今回想定したマルチアカウント環境が検証用途だとオーバースペックだったこともありますが、作業対象のAWSアカウントが複数あり、事前準備が結構大変でした。しかし、一度準備してしまえば、エンドユーザーが必要な時に必要なAWSリソースを数クリックでデプロイできるようにため利用者目線では嬉しいサービスだと思いました。

山﨑 翔平 (Shohei Yamasaki) 記事一覧はコチラ

2019/12〜2023/2までクラウドインテグレーション部でお客様のAWS導入支援を行っていました。現在はIE(インターナルエデュケーション)課にて採用周りのお手伝いや新卒/中途オンボーディングの業務をしています。2023 Japan AWS Top Engineers/2023 Japan AWS Ambassadors