Organizations環境でマルチリージョン・マルチアカウントにService Catalogのポートフォリオを共有

Organizations環境でマルチリージョン・マルチアカウントにService Catalogのポートフォリオを共有

Organizations環境でマルチリージョン・マルチアカウントにService Catalogのポートフォリオを共有してみました
2025.10.30

概要

本エントリーは下記 AWS ブログを参考に書いています。
AWS Organizations の機能や AWS CloudFormation StackSets の設定がだいぶ複雑に感じたので、分かりやすく図と補足を入れながら設定してみました。

https://aws.amazon.com/blogs/mt/simplify-sharing-your-aws-service-catalog-portfolios-in-an-aws-organizations-setup/

想定するOU構成は、Shared Service OU 内に、Service Catalog および CloudFormation StackSets の委任管理者アカウントが配置され、別のOUに複数のリージョンに跨る複数アカウントが配置されています。
委任管理者アカウントにて、Service Catalog のポートフォリオをセットアップし、各アカウント内で製品を実行できるよう共有します。

スクリーンショット 2025-10-26 23.01.29.png

AWS Blog内図転載

前提

  • AWS Organizations 環境
  • マルチアカウント
  • マルチリージョン(またはシングルリージョン)

設定の流れ

  1. 以下のサービスの AWS Organizations の信頼されたアクセスを有効
    1. AWS Service Catalog
    2. CloudFormation StackSets
  2. AWS Service Catalog と CloudFormation Stack Sets の管理者権限の委任を実行
  3. 以下のロールをサービスマネージド型 StackSets で組織内にデプロイ
    1. AWS Service Catalog の製品の起動制約に設定するロール
    2. AWS Service Catalog の製品の実行ロール
  4. セルフマネージド型 Stack Sets のロールを作成
  5. セルフマネージド型 Stack Sets で AWS Service Catalog のポートフォリオをマルチリージョン間でデプロイ
  6. 組織内に Service Catalog のポートフォリオを共有(リージョンごとに実施)
  7. サービスマネージド型 Stack Sets で AWS Service Catalog の製品の実行ロールを紐づけ、オプションタグの設定を実施

Organizations の信頼されたアクセスを有効

AWS Service Catalog の信頼されたアクセス*1 を有効化します。
これによって、AWS Service Catalog のポートフォリオを組織全体、組織単位、任意のアカウント間で簡単に共有ができるようになります。

管理アカウントで実行します。

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

CloudFormation Stack Sets の信頼されたアクセス*2 を有効化します。
サービスリンクロールを作成しサービスマネージド型でStack Setsが実行可能になります。

aws organizations enable-aws-service-access --service-principal member.org.stacksets.cloudformation.amazonaws.com

有効化の確認は以下でできます。

aws organizations list-aws-service-access-for-organization

Service Catalog と CloudFormation StackSets の管理者権限の委任を実行

<YOUR_AWS_ACCOUNT_ID> には管理者を委任するアカウントを指定します。
管理アカウントで実行します。
Service Catalog の管理者委任は CLI からのみサポートされています。

aws organizations register-delegated-administrator --account-id <YOUR_AWS_ACCOUNT_ID> --service-principal servicecatalog.amazonaws.com
aws organizations register-delegated-administrator --account-id <YOUR_AWS_ACCOUNT_ID> --service-principal member.org.stacksets.cloudformation.amazonaws.com

委任された管理者アカウントのリストは以下で確認できます。

aws organizations list-delegated-administrators

ロールをサービスマネージド型 StackSets で組織内にデプロイ

Service Catalog の製品の起動制約に設定するロールと Service Catalog の製品の実行ロールを StackSets で組織内にデプロイします。
ここで意識しておく必要があるのが、StackSets は実行する時のアクセス許可のタイプに サービスマネージド*3セルフマネージド*4 の2通りがある点です。(下記イメージ)
サービスマネージドは Organizations 機能で管理されていて利用が簡単になっていますが、ネストされた CloudFormation を実行できない制約があります。

image-1761488356900.png

ここでは StackSets をサービスマネージドで実行します。

イメージとしては以下のようになります。

AWS - Service Catalog Multi Account.png

StackSets で設定していきます。

CloudFormationテンプレート
sc-iam-setup-stackset.json
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "IAM Setup for Demo Portfolio in AWS Service Catalog (fdp-1qr5bu943)",
    "Metadata": {
      "AWS::CloudFormation::Interface": {
          "ParameterGroups": [
              {
                  "Label": {
                      "default": "IAM Role Setup Options"
                  },
                  "Parameters": [
                      "CreateLaunchConstraintRole",
                      "LaunchConstraintRoleName",
                      "CreateSCEndUserRole",
                      "SCEndUserRoleName"
                  ]
              }
          ]
      }
    },
    "Parameters": {
        "CreateSCEndUserRole": {
          "Type":"String",
          "Description":"Select yes if you want to create end user IAM role across all AWS accounts for your Service Catalog portfolios",
          "AllowedValues": ["Yes", "No"]
        },
        "SCEndUserRoleName": {
          "Type":"String",
          "Description":"The name of a role which can execute products in this portfolio (must be pre-existing in the account)"
        },
        "CreateLaunchConstraintRole": {
          "Type":"String",
          "Description":"Select yes if you want to create AWS Service Catalog launch constraint IAM role across all AWS accounts",
          "AllowedValues": ["Yes", "No"]
        },
        "LaunchConstraintRoleName": {
          "Type":"String",
          "Description":"Name of the launch constraint IAM role for the AWS Service Catalog portfolio to be created across accounts"
        }
    },
    "Conditions":{
        "CreateLaunchConstraint" : {"Fn::Equals" : [{"Ref" : "CreateLaunchConstraintRole"}, "Yes"]},
        "CreateSCEndUserRole" : {"Fn::Equals" : [{"Ref" : "CreateSCEndUserRole"}, "Yes"]}
    },
    "Resources": {     
        "LaunchConstraintRole": {
          "Type": "AWS::IAM::Role",
          "Condition": "CreateLaunchConstraint",
          "Properties": {
              "RoleName": {"Ref": "LaunchConstraintRoleName"},
              "ManagedPolicyArns": [
                "arn:aws:iam::aws:policy/AmazonEC2FullAccess",
                "arn:aws:iam::aws:policy/AmazonSSMFullAccess"
              ],
              "AssumeRolePolicyDocument": {
                  "Version": "2012-10-17",
                  "Statement": [
                      {
                          "Effect": "Allow",
                          "Principal": {
                              "Service": [
                                  "servicecatalog.amazonaws.com"
                              ]
                          },
                          "Action": [
                              "sts:AssumeRole"
                          ]
                      }
                  ]
              },
              "Path": "/",
              "Policies": [
                  {
                      "PolicyName": "root",
                      "PolicyDocument": {
                          "Version": "2012-10-17",
                          "Statement": [
                              {
                                  "Effect": "Allow",
                                  "Action": [
                                    "servicecatalog:ListServiceActionsForProvisioningArtifact",
                                    "servicecatalog:ExecuteprovisionedProductServiceAction",
                                    "iam:AddRoleToInstanceProfile",
                                    "iam:ListRolePolicies",
                                    "iam:ListPolicies",
                                    "iam:DeleteRole",
                                    "iam:GetRole",
                                    "iam:CreateInstanceProfile",
                                    "iam:PassRole",
                                    "iam:DeleteInstanceProfile",
                                    "iam:ListRoles",
                                    "iam:RemoveRoleFromInstanceProfile",
                                    "iam:CreateRole",
                                    "iam:getRolePolicy",
                                    "iam:PutRolePolicy",
                                    "iam:DetachRolePolicy",
                                    "iam:AttachRolePolicy",
                                    "iam:DeleteRolePolicy",
                                    "iam:UntagRole",
                                    "iam:TagRole",
                                    "iam:TagUser",
                                    "iam:UntagUser",
                                    "cloudformation:DescribeStackResource",
                                    "cloudformation:DescribeStackResources",
                                    "cloudformation:GetTemplate",
                                    "cloudformation:List*",
                                    "cloudformation:DescribeStackEvents",
                                    "cloudformation:DescribeStacks",
                                    "cloudformation:CreateStack",
                                    "cloudformation:DeleteStack",
                                    "cloudformation:DescribeStackEvents",
                                    "cloudformation:DescribeStacks",
                                    "cloudformation:GetTemplateSummary",
                                    "cloudformation:SetStackPolicy",
                                    "cloudformation:ValidateTemplate",
                                    "cloudformation:UpdateStack",
                                    "s3:GetObject"
                                  ],
                                  "Resource": "*"
                              }
                          ]
                      }
                  }
              ]
          }
        },
        "SCEndUserRole": {
          "Type": "AWS::IAM::Role",
          "Condition": "CreateSCEndUserRole",
          "Properties": {
              "RoleName": {"Ref": "SCEndUserRoleName"},
              "ManagedPolicyArns": [
                "arn:aws:iam::aws:policy/AWSServiceCatalogEndUserFullAccess"
              ],
              "AssumeRolePolicyDocument": {
                  "Version": "2012-10-17",
                  "Statement": [
                      {
                          "Effect": "Allow",
                          "Principal": {
                              "AWS": [
                                {"Fn::Sub": "arn:aws:iam::${AWS::AccountId}:root"}
                              ]
                          },
                          "Action": [
                              "sts:AssumeRole"
                          ]
                      }
                  ]
              },
              "Path": "/"
          }
        }
    },
    "Outputs": {
		  "LaunchConstraintRoleArn":{
          "Condition":"CreateLaunchConstraint",
          "Value": {"Fn::GetAtt":["LaunchConstraintRole","Arn"]},
          "Description": "ARN of the launch constraint role created for your AWS Service Catalog portfolio"
        },
        "SCEndUserRoleArn":{
          "Condition":"CreateSCEndUserRole",
          "Value": {"Fn::GetAtt":["SCEndUserRole","Arn"]},
          "Description": "ARN of the end user role created for your AWS Service Catalog portfolio"
        }
    }
}

image-1761489408027.png

各設定値は以下のようにします。

  • StackSet 名: 任意 (SC-test-IAM-SETUP)
  • CreateLauchConstraintRole: Yes
  • LaunchConstraintRoleName: Service Catalog 製品の起動制約のロール名 (DemoLaunchRole)
  • CreateSCENdUserRole: Yes
  • SCEndUserRoleName: Service Catalog 製品の実行のロール名(DemoEndUserRole)

image-1761489559345.png

image-1761490023976.png

CloudFormation StackSets を実行します。

スタック完了後に IAM ロールが作成されていることを確認します。

image-1761490277825.png

セルフマネージド型 Stack Sets のロールを作成

この後の手順で、ネストされた CloudFormation のスタックインスタンスをデプロイします。
サービスマネージド型 StackSets ではネストされたスタックインスタンスはサポートされていないため、セルフマネージド型でデプロイします。
セルフマネージド型のデプロイでは、実行権限を持つロールを管理側とターゲット側の全てで作成する必要があります。

管理側作成

委任管理者アカウント で実施します。
スタックの作成で、以下のテンプレートを指定します。

CloudFormationテンプレート
AWSCloudFormationStackSetAdministrationRole.yml
AWSTemplateFormatVersion: 2010-09-09
Description: Configure the AWSCloudFormationStackSetAdministrationRole to enable use of AWS CloudFormation StackSets.

Parameters:
  AdministrationRoleName:
    Type: String
    Default: AWSCloudFormationStackSetAdministrationRole
    Description: "The name of the administration role. Defaults to 'AWSCloudFormationStackSetAdministrationRole'."
  ExecutionRoleName:
    Type: String
    Default: AWSCloudFormationStackSetExecutionRole
    Description: "The name of the execution role that can assume this role. Defaults to 'AWSCloudFormationStackSetExecutionRole'."

Resources:
  AdministrationRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Ref AdministrationRoleName
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service: cloudformation.amazonaws.com
            Action:
              - sts:AssumeRole
      Path: /
      Policies:
        - PolicyName: AssumeRole-AWSCloudFormationStackSetExecutionRole
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - sts:AssumeRole
                Resource:
                  - !Sub 'arn:*:iam::*:role/${ExecutionRoleName}'

image-1761491245677.png

各設定値は以下のようにします。

  • スタック名: StackSetAdministrationRole-Stack
  • AdministrationRoleName: AWSCloudFormationStackSetAdministrationRole
  • ExecutionRoleName: AWSCloudFormationStackSetExecutionRole

※Role 名は上記の通り正しく入力する必要があります。

image-1761491568591.png

スタックを実行します。

スタック完了後に IAM ロールが作成されていることを確認します。

image-1761491812752.png

ターゲット側作成

サービスマネージド型 StackSets を使って、組織内の他のアカウントにターゲット用のロールを作成します。

委任管理者アカウントで実施します。
StackSets を作成します。

CloudFormationテンプレート
AWSCloudFormationStackSetExecutionRole.yml
AWSTemplateFormatVersion: 2010-09-09
Description: Configure the AWSCloudFormationStackSetExecutionRole to enable use of your account as a target account in AWS CloudFormation StackSets.

Parameters:
  AdministratorAccountId:
    Type: String
    Description: AWS Account Id of the administrator account (the account in which StackSets will be created).
    MaxLength: 12
    MinLength: 12
  ExecutionRoleName:
    Type: String
    Default: AWSCloudFormationStackSetExecutionRole
    Description: "The name of the execution role. Defaults to 'AWSCloudFormationStackSetExecutionRole'."

Resources:
  ExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Ref ExecutionRoleName
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              AWS:
                - !Ref AdministratorAccountId
            Action:
              - sts:AssumeRole
      Path: /
      ManagedPolicyArns:
        - !Sub arn:${AWS::Partition}:iam::aws:policy/AdministratorAccess

image-1761492134564.png

各設定値は以下のようにします。

  • スタック名: StackSetExecutionRole-Stack
  • AdministratorAccountId: <YOUR-ACCOUNT-ID>
  • ExecutionRoleName: AWSCloudFormationStackSetExecutionRole

<YOUR-ACCOUNT-ID> は委任管理者アカウントIDを入力します。

image-1761492372514.png

image-1761490023976.png

CloudFormation StackSets を実行します。

それぞれのターゲットアカウントで IAM ロールが作成されているはずです。

image-1761492830463.png

セルフマネージド型 Stack Sets で AWS Service Catalog のポートフォリオをマルチリージョン間でデプロイ

次に Service Catalog のポートフォリオを作成する StackSets を作成していきます。

イメージは以下になります。

AWS - Service Catalog Multi Account(1).png

委任管理者アカウントで StackSets を作成します。

セルフサービスのアクセス許可を選択し、前の手順で作成したロールを入力します。

以下のテンプレートを開いて見てみていただけると分かるのですが、製品登録のためにスタックインスタンスをネストしています。
そのためセルフサービスのアクセス許可で CloudFormation を実行しています。

CloudFormationテンプレート
sc-hub-portfolio-setup-stack.json
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "AWS Service Catalog Demo Portfolio Setup for AWS Organizations Sharing.(fdp-1qr5btau9)",
    "Metadata": {
        "AWS::CloudFormation::Interface": {
            "ParameterGroups": [
                {
                    "Label": {
                        "default": "AWS SC Portfolio Information"
                    },
                    "Parameters": [
                        "PortfolioName",
                        "PortfolioProvider",
                        "PortfolioDescription"
                    ]
                },
                {
                    "Label": {
                        "default": "AWS SC Product Template Source Information"
                    },
                    "Parameters": [
                        "RepoRootURL",
                        "Product1TemplateName",
                        "Product2TemplateName"
                    ]
                },
                {
                    "Label": {
                        "default": "Launch Constraint IAM Configuration"
                    },
                    "Parameters": [
                        "LocalLaunchRoleName"
                    ]
                }
            ]
        }
    },
    "Parameters":
      {
        "PortfolioProvider": {
            "Type":"String",
            "Description":"Provider Name",
            "Default": "IT Services"
        },
       "PortfolioName": {
            "Type": "String",
            "Description": "Portfolio Name",
            "Default": "SCHubPortfolioDemo",
            "AllowedPattern" : "[a-zA-Z0-9]*",
            "ConstraintDescription" : "must contain only alphanumeric characters."
        },
        "PortfolioDescription": {
            "Type": "String",
            "Description": "Portfolio Description",
            "Default": "Service Catalog Portfolio that contains reference architecture products for Amazon Elastic Compute Cloud (EC2)."
        },
        "LocalLaunchRoleName": {
            "Type": "String",
            "Description": "Name of the launch constraint IAM role used for this portfolio (must be precreated)"
        },
        "RepoRootURL": {
            "Type": "String",
            "Description": "S3 root url for the repository containing the product templates.",
            "Default": "https://marketplace-sa-resources.s3.amazonaws.com/sc-org-sharing-blog-june20 "
        },
        "Product1TemplateName": {
            "Type": "String",
            "Description": "Filename of the AWS Service Catalog product 1 template.",
            "Default": "sc-product-ec2-linux.json"
        },
        "Product2TemplateName": {
            "Type": "String",
            "Description": "Filename of the AWS Service Catalog product 2 template.",
            "Default": "sc-product-ec2-windows.json"
        }
      },
    "Resources": 
    {
        "SCPortfolio": {
          "Type" : "AWS::ServiceCatalog::Portfolio",
          "Properties" : {
            "ProviderName": {"Ref":"PortfolioProvider"},
            "Description" : {"Ref":"PortfolioDescription"},
            "DisplayName" : {"Ref":"PortfolioName"}
          }
        },   
        "SCProduct1": {
          "Type" : "AWS::CloudFormation::Stack",
          "Properties" : {
            "Parameters" : {         
                "PortfolioProvider": {"Ref":"PortfolioProvider"},
                "LocalLaunchRoleName": {"Ref":"LocalLaunchRoleName"},
                "PortfolioId":{"Ref":"SCPortfolio"},
                "RepoRootURL":{"Ref":"RepoRootURL"}
            },
            "TemplateURL" : {"Fn::Sub": "${RepoRootURL}/${Product1TemplateName}"},
            "TimeoutInMinutes" : 5
          }
        },
        "SCProduct2": {
          "Type" : "AWS::CloudFormation::Stack",
          "Properties" : {
            "Parameters" : {         
                "PortfolioProvider": {"Ref":"PortfolioProvider"},
                "LocalLaunchRoleName": {"Ref":"LocalLaunchRoleName"},
                "PortfolioId":{"Ref":"SCPortfolio"},
                "RepoRootURL":{"Ref":"RepoRootURL"}
            },
            "TemplateURL" : {"Fn::Sub": "${RepoRootURL}/${Product2TemplateName}"},
            "TimeoutInMinutes" : 5
          }
        }
    },
    "Outputs": {
     "SCPortfolioId":{
        "Value": {"Ref":"SCPortfolio"},
        "Description":"Portfolio Id of the newly created AWS Service Catalog Portfolio"
      },
      "SCProduct1":{
        "Value": {"Fn::GetAtt":["SCProduct1","Outputs.ProductId"]},
        "Description":"Product Id of the newly created AWS Service Catalog Product 1"
      },
      "SCProduct2":{
        "Value": {"Fn::GetAtt":["SCProduct2","Outputs.ProductId"]},
        "Description":"Product Id of the newly created AWS Service Catalog Product 2"
      }
  }
}

image-1761659263607.png

各設定は以下になります。

  • StackSet 名: 任意 (SC-test-HUB-SETUP)
  • PortfolioName: Service Catalog のポートフォリオ名 (SCHubPortfolioDemo)
  • PortfolioProvider: Service Catalog の所有者
  • PortfolioDescription: Service Catalog の説明
  • RepoRootURL: Service Catalog 製品のテンプレートが配置されているレポジトリ (https://marketplace-sa-resources.s3.amazonaws.com/sc-org-sharing-blog-june20)
  • Product1TemplateName: レポジトリ内のテンプレートファイル (sc-product-ec2-linux.json)
  • Product2TemplateName: レポジトリ内のテンプレートファイル (sc-product-ec2-windows.json)
  • LocalLaunchRoleName: 作成済みの Service Catalog 製品の起動制約のロール名 (DemoLaunchRole)

RepoRootURL には、AWSブログの参考URLを入力しています。
サンプルのテンプレートを使った Service Catalog 製品が登録されますが、実際にはテンプレートを S3 などに用意して作りたい製品のテンプレートを配置します。

image-1761785725004.png

参考ですが、製品の CloudFormation テンプレートは以下です。

Product1TemplateName

Product2TemplateName

デプロイするアカウントまたは組織、リージョンを指定します。

image-1761785806653.png

委任管理者アカウントにて、ポートフォリオが登録されていますね。

image-1761786762597.png

組織内に Service Catalog のポートフォリオを共有(リージョンごとに実施)

ここでの作業は、委任管理者アカウントで作成したポートフォリオをその他のOUのアカウントに共有します。
リージョンごとの作業になります。

AWS - Service Catalog Multi Account(3).png

Service Catalog で ポートフォリオを選択し、共有します。

image-1761826129208.png

AWS Organization組織ノード を選択し、組織単位で共有します。

image-1761826477789.png

共有先のアカウントでポートフォリオが共有されていますね。

image-1761827493086.png

サービスマネージド型 Stack Sets で AWS Service Catalog の製品の実行ロールを紐づけ、オプションタグの設定を実施

最後に製品の実行ロールとオプションタグの設定を実施します。
以下のようなイメージです。

AWS - Service Catalog Multi Account(4).png

再度、委任管理者アカウントから Stack Sets でデプロイします。

CloudFormation テンプレートの下記の部分で、デプロイするリージョンと、リージョンごとのポートフォリオIDを適切な値に置き換えます。

"Mappings" : {
  "RegionAndPortfolioNameToPortfolioID" : {
    "ap-northeast-1": {
      "SCHubPortfolioDemo": "<ADD_PORTFOLIO_ID>"
    },
    "ap-northeast-3" : {
      "SCHubPortfolioDemo": "<ADD_PORTFOLIO_ID>"  
    }
  }
}
CloudFormationテンプレート
sc-iam-and-tag-assignment-stackset.json
{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "IAM and TagOption assignment for Demo Portfolio in AWS Service Catalog (fdp-1qr5btaug)",
    "Metadata": {
      "AWS::CloudFormation::Interface": {
          "ParameterGroups": [
              {
                  "Label": {
                      "default": "AWS SC Portfolio Information"
                  },
                  "Parameters": [
                      "PortfolioName"
                  ]
              },
              {
                  "Label": {
                      "default": "AWS SC End User Information"
                  },
                  "Parameters": [
                      "LinkEndUserRole",
                      "SCEndUserRoleName"
                  ]
              },
              {
                  "Label": {
                      "default": "(OPTIONAL) Sample TagOption Setup Options"
                  },
                  "Parameters": [
                      "AddTagOptions"
                    ]
              }
          ]
      }
    },
    "Mappings" : {
      "RegionAndPortfolioNameToPortfolioID" : {
        "ap-northeast-1": {
          "SCHubPortfolioDemo": "<ADD_PORTFOLIO_ID>"
        },
        "ap-northeast-3" : {
          "SCHubPortfolioDemo": "<ADD_PORTFOLIO_ID>"
        }
      }
      },
    "Parameters": {
        "PortfolioName": {
          "Type":"String",
          "Description":"Portfolio Name of the AWS Service Catalog portfolio that is shared to AWS Organizations or AWS Accounts",
          "Default": "SCHubPortfolioDemo"
      },
        "SCEndUserRoleName": {
            "Type":"String",
            "Description":"The name of a role which can execute products in this portfolio (must be pre-existing in all the accounts). Leave blank if no assignment required."
        },
        "LinkEndUserRole": {
          "Type":"String",
          "Description":"Determines if an end user role is to be added to your portfolio",
          "AllowedValues": ["Yes", "No"]
        },
        "AddTagOptions": {
          "Type":"String",
          "Description":"Determines if tagOptions are to be added to your portfolio",
          "AllowedValues": ["Yes", "No"]
        }
      },
    "Conditions":{
        "AddTagOptions" : {"Fn::Equals" : [{"Ref" : "AddTagOptions"}, "Yes"]},
        "LinkEndUserRole" : {"Fn::Equals" : [{"Ref" : "LinkEndUserRole"}, "Yes"]}
          },
    "Resources": {
        "LinkSCEndUserRole":{
          "Type" : "AWS::ServiceCatalog::PortfolioPrincipalAssociation",
          "Condition":"LinkEndUserRole",
          "Properties" : {
            "PrincipalARN" : {"Fn::Sub": "arn:aws:iam::${AWS::AccountId}:role/${SCEndUserRoleName}"},
            "PortfolioId" : { "Fn::FindInMap" : [ "RegionAndPortfolioNameToPortfolioID", { "Ref" : "AWS::Region" }, { "Ref" : "PortfolioName" } ]},
            "PrincipalType" : "IAM"
          }
        },
        "productEnvironmentProd" : {
          "Type" : "AWS::ServiceCatalog::TagOption",
          "Condition": "AddTagOptions",
          "Properties" : {
            "Active" : true,
            "Value" : "PROD",
            "Key" : "serviceEnvironment"
          }
        },
        "productEnvironmentProdassoc":{
            "Type" : "AWS::ServiceCatalog::TagOptionAssociation",
            "Condition": "AddTagOptions",
            "Properties" : {
              "ResourceId" : { "Fn::FindInMap" : [ "RegionAndPortfolioNameToPortfolioID", { "Ref" : "AWS::Region" }, { "Ref" : "PortfolioName" } ]},
              "TagOptionId" : { "Ref" : "productEnvironmentProd" }
            }
        },
        "productEnvironmentQA" : {
          "Type" : "AWS::ServiceCatalog::TagOption",
          "Condition": "AddTagOptions",
          "Properties" : {
            "Active" : true,
            "Value" : "QA",
            "Key" : "serviceEnvironment"
          }
        },
        "productEnvironmentQAassoc":{
          "Type" : "AWS::ServiceCatalog::TagOptionAssociation",
          "Condition": "AddTagOptions",
          "Properties" : {
            "ResourceId" : { "Fn::FindInMap" : [ "RegionAndPortfolioNameToPortfolioID", { "Ref" : "AWS::Region" }, { "Ref" : "PortfolioName" } ]},
            "TagOptionId" : { "Ref" : "productEnvironmentQA" }
          }
        },
        "productEnvironmentDev" : {
          "Type" : "AWS::ServiceCatalog::TagOption",
          "Condition": "AddTagOptions",
          "Properties" : {
            "Active" : true,
            "Value" : "DEV",
            "Key" : "serviceEnvironment"
          }
        },
        "productEnvironmentDevassoc":{
          "Type" : "AWS::ServiceCatalog::TagOptionAssociation",
          "Condition": "AddTagOptions",
          "Properties" : {
            "ResourceId" : { "Fn::FindInMap" : [ "RegionAndPortfolioNameToPortfolioID", { "Ref" : "AWS::Region" }, { "Ref" : "PortfolioName" } ]},
            "TagOptionId" : { "Ref" : "productEnvironmentDev" }
          }
        },
        "ChargeBackDataInsights" : {
          "Type" : "AWS::ServiceCatalog::TagOption",
          "Condition": "AddTagOptions",
          "Properties" : {
            "Active" : true,
            "Value" : "DATA-INSIGHTS",
            "Key" : "Chargeback"
          }
        },
        "ChargeBackDataInsightsassoc":{
          "Type" : "AWS::ServiceCatalog::TagOptionAssociation",
          "Condition": "AddTagOptions",
          "Properties" : {
            "ResourceId" : { "Fn::FindInMap" : [ "RegionAndPortfolioNameToPortfolioID", { "Ref" : "AWS::Region" }, { "Ref" : "PortfolioName" } ]},
            "TagOptionId" : { "Ref" : "ChargeBackDataInsights" }
          }
        },
        "ChargeBackMK" : {
          "Type" : "AWS::ServiceCatalog::TagOption",
          "Condition": "AddTagOptions",
          "Properties" : {
            "Active" : true,
            "Value" : "MARKETING",
            "Key" : "Chargeback"
          }
        },
        "ChargeBackMKassoc":{
          "Type" : "AWS::ServiceCatalog::TagOptionAssociation",
          "Condition": "AddTagOptions",
          "Properties" : {
            "ResourceId" : { "Fn::FindInMap" : [ "RegionAndPortfolioNameToPortfolioID", { "Ref" : "AWS::Region" }, { "Ref" : "PortfolioName" } ]},
            "TagOptionId" : { "Ref" : "ChargeBackMK" }
          }
        },
        "ChargeBackSC" : {
            "Type" : "AWS::ServiceCatalog::TagOption",
            "Condition": "AddTagOptions",
            "Properties" : {
              "Active" : true,
              "Value" : "SUPPLYCHAIN",
              "Key" : "Chargeback"
            }
        },
        "ChargeBackSCassoc":{
          "Type" : "AWS::ServiceCatalog::TagOptionAssociation",
          "Condition": "AddTagOptions",
          "Properties" : {
            "ResourceId" : { "Fn::FindInMap" : [ "RegionAndPortfolioNameToPortfolioID", { "Ref" : "AWS::Region" }, { "Ref" : "PortfolioName" } ]},
            "TagOptionId" : { "Ref" : "ChargeBackSC" }
          }
        },
        "ChargeBackAccounting" : {
          "Type" : "AWS::ServiceCatalog::TagOption",
          "Condition": "AddTagOptions",
          "Properties" : {
            "Active" : true,
            "Value" : "ACCOUNTING",
            "Key" : "Chargeback"
          }
        },
        "ChargeBackAccountingassoc":{
          "Type" : "AWS::ServiceCatalog::TagOptionAssociation",
          "Condition": "AddTagOptions",
          "Properties" : {
            "ResourceId" : { "Fn::FindInMap" : [ "RegionAndPortfolioNameToPortfolioID", { "Ref" : "AWS::Region" }, { "Ref" : "PortfolioName" } ]},
            "TagOptionId" : { "Ref" : "ChargeBackAccounting" }
          }
        }        
      } 
}

サービスマネージドアクセス許可 でテンプレートを指定します。

image-1761829248048.png

各設定は以下になります。

  • StackSet 名: 任意 (SC-test-ASSIGNMENT)
  • PortfolioName: Service Catalog のポートフォリオ名 (SCHubPortfolioDemo)
  • LinkEndUserRole: Yes
  • SCEndUserRole: 各アカウントに作成した製品の実行ロール名 (DemoEndUserRole)
  • AddTagOptions: タグオプションをつけるかどうか (Yes/No)

image-1761829863889.png

デプロイ先の組織、リージョンを指定して StackSets を作成します。

image-1761830855523.png

以上で、その他のOU内のアカウントおよびリージョンで製品が利用できるようになりました。

まとめ

ポートフォリオと製品を作成する StackSets のところで、セルフサービスのアクセス許可でデプロイするところがポイントかと思いました。
実際にやってみることで、マルチアカウント・マルチリージョンへの展開のポイントを確認できました。

参考

*1
https://docs.aws.amazon.com/ja_jp/organizations/latest/userguide/services-that-can-integrate-servicecatalog.html

*2
https://docs.aws.amazon.com/ja_jp/organizations/latest/userguide/services-that-can-integrate-cloudformation.html

*3
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/stacksets-orgs-associate-stackset-with-org.html

*4
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/stacksets-getting-started-create-self-managed.html

この記事をシェアする

FacebookHatena blogX

関連記事