Organizations環境でマルチリージョン・マルチアカウントにService Catalogのポートフォリオを共有
概要
本エントリーは下記 AWS ブログを参考に書いています。
AWS Organizations の機能や AWS CloudFormation StackSets の設定がだいぶ複雑に感じたので、分かりやすく図と補足を入れながら設定してみました。
想定するOU構成は、Shared Service OU 内に、Service Catalog および CloudFormation StackSets の委任管理者アカウントが配置され、別のOUに複数のリージョンに跨る複数アカウントが配置されています。
委任管理者アカウントにて、Service Catalog のポートフォリオをセットアップし、各アカウント内で製品を実行できるよう共有します。

AWS Blog内図転載
前提
- AWS Organizations 環境
- マルチアカウント
- マルチリージョン(またはシングルリージョン)
設定の流れ
- 以下のサービスの AWS Organizations の信頼されたアクセスを有効
- AWS Service Catalog
- CloudFormation StackSets
- AWS Service Catalog と CloudFormation Stack Sets の管理者権限の委任を実行
- 以下のロールをサービスマネージド型 StackSets で組織内にデプロイ
- AWS Service Catalog の製品の起動制約に設定するロール
- AWS Service Catalog の製品の実行ロール
- セルフマネージド型 Stack Sets のロールを作成
- セルフマネージド型 Stack Sets で AWS Service Catalog のポートフォリオをマルチリージョン間でデプロイ
- 組織内に Service Catalog のポートフォリオを共有(リージョンごとに実施)
- サービスマネージド型 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 を実行できない制約があります。

ここでは StackSets をサービスマネージドで実行します。
イメージとしては以下のようになります。

StackSets で設定していきます。
CloudFormationテンプレート
{
"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"
}
}
}

各設定値は以下のようにします。
- StackSet 名: 任意 (SC-test-IAM-SETUP)
- CreateLauchConstraintRole: Yes
- LaunchConstraintRoleName: Service Catalog 製品の起動制約のロール名 (DemoLaunchRole)
- CreateSCENdUserRole: Yes
- SCEndUserRoleName: Service Catalog 製品の実行のロール名(DemoEndUserRole)


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

セルフマネージド型 Stack Sets のロールを作成
この後の手順で、ネストされた CloudFormation のスタックインスタンスをデプロイします。
サービスマネージド型 StackSets ではネストされたスタックインスタンスはサポートされていないため、セルフマネージド型でデプロイします。
セルフマネージド型のデプロイでは、実行権限を持つロールを管理側とターゲット側の全てで作成する必要があります。
管理側作成
委任管理者アカウント で実施します。
スタックの作成で、以下のテンプレートを指定します。
CloudFormationテンプレート
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}'

各設定値は以下のようにします。
- スタック名: StackSetAdministrationRole-Stack
- AdministrationRoleName: AWSCloudFormationStackSetAdministrationRole
- ExecutionRoleName: AWSCloudFormationStackSetExecutionRole
※Role 名は上記の通り正しく入力する必要があります。

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

ターゲット側作成
サービスマネージド型 StackSets を使って、組織内の他のアカウントにターゲット用のロールを作成します。
委任管理者アカウントで実施します。
StackSets を作成します。
CloudFormationテンプレート
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

各設定値は以下のようにします。
- スタック名: StackSetExecutionRole-Stack
- AdministratorAccountId: <YOUR-ACCOUNT-ID>
- ExecutionRoleName: AWSCloudFormationStackSetExecutionRole
※<YOUR-ACCOUNT-ID> は委任管理者アカウントIDを入力します。


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

セルフマネージド型 Stack Sets で AWS Service Catalog のポートフォリオをマルチリージョン間でデプロイ
次に Service Catalog のポートフォリオを作成する StackSets を作成していきます。
イメージは以下になります。

委任管理者アカウントで StackSets を作成します。
セルフサービスのアクセス許可を選択し、前の手順で作成したロールを入力します。
以下のテンプレートを開いて見てみていただけると分かるのですが、製品登録のためにスタックインスタンスをネストしています。
そのためセルフサービスのアクセス許可で CloudFormation を実行しています。
CloudFormationテンプレート
{
"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"
}
}
}

各設定は以下になります。
- 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 などに用意して作りたい製品のテンプレートを配置します。

参考ですが、製品の CloudFormation テンプレートは以下です。
デプロイするアカウントまたは組織、リージョンを指定します。

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

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

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

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

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

サービスマネージド型 Stack Sets で AWS Service Catalog の製品の実行ロールを紐づけ、オプションタグの設定を実施
最後に製品の実行ロールとオプションタグの設定を実施します。
以下のようなイメージです。

再度、委任管理者アカウントから Stack Sets でデプロイします。
CloudFormation テンプレートの下記の部分で、デプロイするリージョンと、リージョンごとのポートフォリオIDを適切な値に置き換えます。
"Mappings" : {
"RegionAndPortfolioNameToPortfolioID" : {
"ap-northeast-1": {
"SCHubPortfolioDemo": "<ADD_PORTFOLIO_ID>"
},
"ap-northeast-3" : {
"SCHubPortfolioDemo": "<ADD_PORTFOLIO_ID>"
}
}
}
CloudFormationテンプレート
{
"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" }
}
}
}
}
サービスマネージドアクセス許可 でテンプレートを指定します。

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

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

以上で、その他のOU内のアカウントおよびリージョンで製品が利用できるようになりました。
まとめ
ポートフォリオと製品を作成する StackSets のところで、セルフサービスのアクセス許可でデプロイするところがポイントかと思いました。
実際にやってみることで、マルチアカウント・マルチリージョンへの展開のポイントを確認できました。
参考
*1
*2
*3
*4








