

# IAM チュートリアル: CloudFormation テンプレートを使用して SAML ID プロバイダー (IdP) と SAML フェデレーション IAM ロールを作成する
<a name="tutorial_saml-idp-and-federated-role"></a>

SAML フェデレーションとその機能を理解するために、CloudFormation テンプレートを使用して SAML ID プロバイダー (IdP) と関連するフェデレーション IAM ロールを設定します。このチュートリアルでは、両方のリソースを 1 つのスタックにまとめて作成する方法を説明します。

テンプレートは、AWS リソースへのフェデレーションアクセスに使用できる SAML IdP と、SAML プロバイダーを信頼する IAM ロールを作成します。外部 IdP によって認証されたユーザーは、このロールを引き受けて AWS リソースにアクセスできます。

デプロイされたリソースは、以下で構成されます。
+ IdP のメタデータドキュメントで設定された SAML IdP。
+ SAML IdP を信頼し、認証されたユーザーが引き受けることができるフェデレーション IAM ロール。
+ 特定のアクセス許可を付与するためにロールにアタッチできる設定可能なマネージドポリシー。

## 前提条件
<a name="tutorial_saml-idp-and-federated-role-prereqs"></a>

このチュートリアルでは、以下を実行済みであることを前提としています。
+ このチュートリアルで IdP の SAML メタデータ XML ファイルをフォーマットするために使用する Python コマンドを実行するには、ローカル マシンに Python 3.6 以降がインストールされている必要があります。
+ 外部 IdP からの SAML メタデータドキュメントを XML ファイルとして保存していること。

## CloudFormation を使用して SAML IdP とロールを作成する
<a name="tutorial_saml-idp-and-federated-role-create"></a>

SAML IdP とフェデレーションロールを作成するために、CloudFormation テンプレートを作成し、それを使用して両方のリソースが含まれるスタックを作成します。

### テンプレートを作成する
<a name="tutorial_saml-idp-and-federated-role-file"></a>

まず、CloudFormation テンプレートを作成します。

1. [テンプレート](#tutorial_saml-idp-and-federated-role-template) セクションで、**[JSON]** または **[YAML]** タブのコピーアイコンをクリックして、テンプレートの内容をコピーします。

1. テンプレートの内容を新しいファイルに貼り付けます。

1. ファイルをローカルに保存します。

### スタックを作成します。
<a name="tutorial_saml-idp-and-federated-role-stack"></a>

次に、保存したテンプレートを使用して CloudFormation スタックをプロビジョニングします。

1. [https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/) で CloudFormation コンソール を開きます。

1. **[スタック]** ページでは、**[スタックの作成]** メニューで **[新しいリソースを使用 (標準)]** を選択します。

1. テンプレートを指定します。

   1. **[前提条件]** で、**[既存のテンプレートを選択]** を選択します。

   1. **[テンプレートの指定]** で、**[テンプレートファイルのアップロード]** を選択します。

   1. **[ファイルを選択]** を選択し、テンプレートファイルに移動して選択します。

   1. [**次へ**] を選択します。

1. 次のスタックの詳細を指定します。

   1. スタック名を入力します。

   1. **[IdentityProviderName]** は、空のままにするとスタック名に基づいて名前を自動生成できます。または、SAML IdP のカスタム名を入力することもできます。

      例: `CompanyIdP` または `EnterpriseSSO`

   1. **[IdentityProviderSAMLMetadataDocument]** では、このフィールドに貼り付ける前に、SAML メタデータ XML ファイルを 1 行にフォーマットする必要があります。CloudFormation コンソールでコンソールパラメータを渡すときに XML コンテンツを 1 行にフォーマットする必要があるため、この処理が必要です。

      次の Python コマンドを使用して、XML ファイルを再フォーマットします。

      ```
      python3 -c "import sys, re; content=open(sys.argv[1]).read(); print(re.sub(r'>\s+<', '><', content.replace('\n', '').replace('\r', '').strip()))" saml-metadata.xml
      ```
**注記**  
IdP の SAML メタデータドキュメントは、コンソールパラメータ入力用に 1 行にフォーマットする必要があります。この Python コマンドは、改行と余分な空白を削除して、元のコンテンツと構造をすべて維持した状態で必要なフォーマットを作成します。

      Python コマンドの出力をコピーし、**[IdentityProviderSAMLMetadataDocument]** フィールドに貼り付けます。

      フォーマットされた SAML メタデータドキュメントの例 (抜粋):

      ```
      <?xml version="1.0" encoding="UTF-8"?><md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" entityID="https://portal.sso.example.com/saml/assertion/CompanyIdP"><md:IDPSSODescriptor WantAuthnRequestsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"><md:KeyDescriptor use="signing"><ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:X509Data><ds:X509Certificate>MIIDXTCCAkWgAwIBAgIJAJC1HiIAZAiIMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV...</ds:X509Certificate></ds:X509Data></ds:KeyInfo></md:KeyDescriptor><md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://portal.sso.example.com/saml/logout/CompanyIdP"/><md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</md:NameIDFormat><md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://portal.sso.example.com/saml/assertion/CompanyIdP"/></md:IDPSSODescriptor></md:EntityDescriptor>
      ```

   1. **[RoleName]** では、空のままにするとスタック名に基づいて名前を自動生成できます。または、フェデレーション IAM ロールのカスタム名を入力できます。

      例: `SAML-Developer-Access` または `SAML-ReadOnly-Role`

   1. その他のパラメータについては、デフォルト値を受け入れるか、要件に応じて独自の値を入力します。
      + **IdentityProviderAddPrivateKey** – SAML アサーションを復号するためのオプションのプライベートキー
      + **IdentityProviderAssertionEncryptionMode** – SAML アサーションの暗号化モード

        値の例: `Allowed`、`Required`、または暗号化なしの場合は空のままにする
      + **RoleSessionDuration** – 最大セッション期間 (秒) (3600～43200、デフォルトは 7200)

        例: `14400` (4 時間)
      + **RolePermissionsBoundary** – アクセス許可の境界ポリシーのオプション ARN

        例:`arn:aws:iam::123456789012:policy/DeveloperBoundary`
      + **RolePath** – IAM ロールのパス (デフォルトは /)

        例:`/saml-roles/`
      + **RoleManagedPolicy1-5** – アタッチする最大 5 つのマネージドポリシーのオプション ARN

        RoleManagedPolicy1 の例: `arn:aws:iam::aws:policy/ReadOnlyAccess`

        RoleManagedPolicy2 の例: `arn:aws:iam::123456789012:policy/CustomPolicy`

   1. [**次へ**] を選択します。

1. スタックオプションを設定します。

   1. **[スタック障害オプション]** で、**[新しく作成されたリソースをすべて削除]** を選択します。
**注記**  
このオプションを選択すると、スタックの作成に失敗した場合でも削除ポリシーで保持するように指定されているリソースに対して、課金される可能性を防ぐことができます。

   1. 他はすべて、デフォルト値を受け入れます。

   1. **[機能]** では、チェックボックスをオンにして、CloudFormation によってアカウントに IAM リソースが作成される場合があることを承認します。

   1. [**次へ**] を選択します。

1. スタックの詳細を確認して、**[送信]** を選択します。

CloudFormation によってスタックが作成されます。スタックの作成が完了すると、スタックリソースを使用する準備が整います。スタックの詳細ページの **[リソース]** タブを使用して、アカウントにプロビジョニングされたリソースを表示できます。

スタックは次の値を出力します。値は **[出力]** タブで確認できます。
+ **RoleARN**: 作成された IAM ロールの ARN (自動生成された名前を使用する場合は、`arn:aws:iam::123456789012:role/SAML-Developer-Access` または `arn:aws:iam::123456789012:role/stack-name-a1b2c3d4` など)。
+ **IdentityProviderARN**: 作成された SAML IdP の ARN (`arn:aws:iam::123456789012:saml-provider/CompanyIdP` など)。

ロールの引き受けのために適切な SAML 属性を送信するように IdP を設定する場合は、これら両方の ARN が必要です。

## SAML フェデレーションをテストする
<a name="tutorial_saml-idp-and-federated-role-using"></a>

SAML IdP とフェデレーションロールが作成されたら、フェデレーション設定をテストできます。

1. IAM コンソール ([https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/)) を開きます。

1. ナビゲーションペインで、**[ID プロバイダー]** を選択します。

   新しく作成された SAML IdP がリストに表示されるはずです。

1. IdP 名を選択すると、その詳細が表示されます。

   IdP の詳細ページで、SAML メタデータドキュメントやその他の設定の詳細を確認できます。

1. ナビゲーションペインで **Roles (ロール) ** を選択してください。

1. 新しく作成されたフェデレーションロールを見つけて選択します。

   ロールの詳細ページで、SAML IdP がこのロールを引き受けることを許可する信頼ポリシーを確認できます。

1. **[信頼関係]** タブを選択して、信頼ポリシーを確認します。

   信頼ポリシーには、SAML オーディエンス (`SAML:aud`) が `https://signin.aws.amazon.com/saml` と一致することを条件として、SAML IdP がこのロールを引き受けるように信頼されていることが示されているはずです。

## クリーンアップ: リソースを削除する
<a name="tutorial_saml-idp-and-federated-role-delete"></a>

最後のステップとして、スタックとそれに含まれるリソースを削除します。

1. CloudFormation コンソールを開きます。

1. **[スタック]** ページで、テンプレートから作成されたスタックを選択し、**[削除]** を選択してから、**[削除]** で確定します。

   CloudFormation は、スタックとそれに含まれるすべてのリソースの削除を開始します。

## CloudFormation テンプレートファイルの詳細
<a name="tutorial_saml-idp-and-federated-role-template-details"></a>

### リソース
<a name="tutorial_saml-idp-and-federated-role-template-resources"></a>

このチュートリアルで使用する CloudFormation テンプレートでは、以下のリソースがアカウントに作成されます。
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-samlprovider.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-samlprovider.html): AWS と外部 IdP の間の信頼を確立する SAML IdP。
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html): SAML IdP を介して認証されたユーザーが引き受けることができるフェデレーション IAM ロール。

### 設定
<a name="tutorial_saml-idp-and-federated-role-configuration"></a>

テンプレートには、以下の設定可能なパラメータが含まれています。
+ **IdentityProviderName** – SAML IdP の名前 (自動生成された名前にする場合は空のままにします)
+ **IdentityProviderSAMLMetadataDocument** – IdP の SAML メタデータドキュメント (必須)。
+ **IdentityProviderAddPrivateKey** – SAML アサーションを復号するためのオプションのプライベートキー
+ **IdentityProviderAssertionEncryptionMode** – SAML アサーションの暗号化モード
+ **RoleName** – IAM ロールの名前 (自動生成された名前にする場合は空のままにします)
+ **RolePath** – IAM ロールのパス (デフォルトは /)
+ **RolePermissionsBoundary** – アクセス許可の境界ポリシーのオプション ARN
+ **RoleSessionDuration** – 最大セッション期間 (秒) (3600～43200、デフォルトは 7200)
+ **RoleManagedPolicy1-5** – アタッチする最大 5 つのマネージドポリシーのオプション ARN

## CloudFormation テンプレート
<a name="tutorial_saml-idp-and-federated-role-template"></a>

次の JSON または YAML コードを別のファイルとして保存し、このチュートリアルの CloudFormation テンプレートとして使用します。

------
#### [ JSON ]

```
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "[AWSDocs] IAM: tutorial_saml-idp-and-federated-role",
  "Parameters": {
    "IdentityProviderName": {
      "Type": "String",
      "Description": "Name of the SAML Identity Provider (leave empty for auto-generated name like '{StackName}-{UniqueId}')",
      "Default": "",
      "AllowedPattern": "^$|^[a-zA-Z0-9._-]+$",
      "ConstraintDescription": "Must be empty or contain only alphanumeric characters, periods, underscores, and hyphens"
    },
    "IdentityProviderSAMLMetadataDocument": {
      "Type": "String",
      "Description": "SAML metadata document from identity provider"
    },
    "IdentityProviderAddPrivateKey": {
      "Type": "String",
      "Description": "Optional private key for decrypting SAML assertions. The private key must be a .pem file that uses AES-GCM or AES-CBC encryption algorithm to decrypt SAML assertions.",
      "Default": ""
    },
    "IdentityProviderAssertionEncryptionMode": {
      "Type": "String",
      "Description": "Optional, sets encryption mode for SAML assertions",
      "Default": "",
      "AllowedValues": ["", "Allowed", "Required"]
    },
    "RoleName": {
      "Type": "String",
      "Description": "Name of the IAM Role (leave empty for auto-generated name like '{StackName}-{UniqueId}')",
      "Default": "",
      "AllowedPattern": "^$|^[\\w+=,.@-]{1,64}$",
      "ConstraintDescription": "Must be empty or 1-64 characters and can contain alphanumeric characters and +=,.@-"
    },
    "RolePath": {
      "Type": "String",
      "Description": "Path for the IAM Role",
      "AllowedPattern": "(^\\/$)|(^\\/.*\\/$)",
      "Default": "/"
    },
    "RolePermissionsBoundary": {
      "Type": "String",
      "Description": "Optional ARN of the permissions boundary policy (leave empty for none)",
      "Default": ""
    },
    "RoleSessionDuration": {
      "Description": "The maximum session duration (in seconds) that you want to set for the specified role (3600-43200)",
      "Type": "Number",
      "MinValue": 3600,
      "MaxValue": 43200,
      "Default": 7200
    },
    "RoleManagedPolicy1": {
      "Type": "String",
      "Description": "Optional managed policy ARN 1",
      "Default": ""
    },
    "RoleManagedPolicy2": {
      "Type": "String",
      "Description": "Optional managed policy ARN 2",
      "Default": ""
    },
    "RoleManagedPolicy3": {
      "Type": "String",
      "Description": "Optional managed policy ARN 3",
      "Default": ""
    },
    "RoleManagedPolicy4": {
      "Type": "String",
      "Description": "Optional managed policy ARN 4",
      "Default": ""
    },
    "RoleManagedPolicy5": {
      "Type": "String",
      "Description": "Optional managed policy ARN 5",
      "Default": ""
    }
  },
  "Conditions": {
    "HasCustomProviderName": {"Fn::Not": [{"Fn::Equals": [{"Ref": "IdentityProviderName"}, ""]}]},
    "HasCustomRoleName": {"Fn::Not": [{"Fn::Equals": [{"Ref": "RoleName"}, ""]}]},
    "HasPermissionsBoundary": {"Fn::Not": [{"Fn::Equals": [{"Ref": "RolePermissionsBoundary"}, ""]}]},
    "HasPolicy1": {"Fn::Not": [{"Fn::Equals": [{"Ref": "RoleManagedPolicy1"}, ""]}]},
    "HasPolicy2": {"Fn::Not": [{"Fn::Equals": [{"Ref": "RoleManagedPolicy2"}, ""]}]},
    "HasPolicy3": {"Fn::Not": [{"Fn::Equals": [{"Ref": "RoleManagedPolicy3"}, ""]}]},
    "HasPolicy4": {"Fn::Not": [{"Fn::Equals": [{"Ref": "RoleManagedPolicy4"}, ""]}]},
    "HasPolicy5": {"Fn::Not": [{"Fn::Equals": [{"Ref": "RoleManagedPolicy5"}, ""]}]},
    "HasPrivateKey": {"Fn::Not": [{"Fn::Equals": [{"Ref": "IdentityProviderAddPrivateKey"}, ""]}]},
    "HasAssertionEncryptionMode": {"Fn::Not": [{"Fn::Equals": [{"Ref": "IdentityProviderAssertionEncryptionMode"}, ""]}]}
  },
  "Resources": {
    "SAMLProvider": {
      "Type": "AWS::IAM::SAMLProvider",
      "Properties": {
        "Name": {"Fn::If": ["HasCustomProviderName", {"Ref": "IdentityProviderName"}, {"Ref": "AWS::NoValue"}]},
        "SamlMetadataDocument": {"Ref": "IdentityProviderSAMLMetadataDocument"},
        "AddPrivateKey": {"Fn::If": ["HasPrivateKey", {"Ref": "IdentityProviderAddPrivateKey"}, {"Ref": "AWS::NoValue"}]},
        "AssertionEncryptionMode": {"Fn::If": ["HasAssertionEncryptionMode", {"Ref": "IdentityProviderAssertionEncryptionMode"}, {"Ref": "AWS::NoValue"}]}
      }
    },
    "SAMLFederatedRole": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "RoleName": {"Fn::If": ["HasCustomRoleName", {"Ref": "RoleName"}, {"Ref": "AWS::NoValue"}]},
        "Path": {"Ref": "RolePath"},
        "Description": "SAML federated IAM role for SSO access with specified permissions",
        "MaxSessionDuration": {"Ref": "RoleSessionDuration"},
        "PermissionsBoundary": {"Fn::If": ["HasPermissionsBoundary", {"Ref": "RolePermissionsBoundary"}, {"Ref": "AWS::NoValue"}]},
        "AssumeRolePolicyDocument": {
          "Version": "2012-10-17",		 	 	 
          "Statement": [
            {
              "Effect": "Allow",
              "Principal": {
                "Federated": {"Ref": "SAMLProvider"}
              },
              "Action": [
                "sts:AssumeRole",
                "sts:SetSourceIdentity",
                "sts:TagSession"
              ],
              "Condition": {
                "StringEquals": {
                  "SAML:aud": "https://signin.aws.amazon.com/saml"
                }
              }
            }
          ]
        },
        "ManagedPolicyArns": {
          "Fn::Split": [
            ",",
            {
              "Fn::Join": [
                ",",
                [
                  {"Fn::If": ["HasPolicy1", {"Ref": "RoleManagedPolicy1"}, {"Ref": "AWS::NoValue"}]},
                  {"Fn::If": ["HasPolicy2", {"Ref": "RoleManagedPolicy2"}, {"Ref": "AWS::NoValue"}]},
                  {"Fn::If": ["HasPolicy3", {"Ref": "RoleManagedPolicy3"}, {"Ref": "AWS::NoValue"}]},
                  {"Fn::If": ["HasPolicy4", {"Ref": "RoleManagedPolicy4"}, {"Ref": "AWS::NoValue"}]},
                  {"Fn::If": ["HasPolicy5", {"Ref": "RoleManagedPolicy5"}, {"Ref": "AWS::NoValue"}]}
                ]
              ]
            }
          ]
        }
      }
    }
  },
  "Outputs": {
    "RoleARN": {
      "Description": "ARN of the created IAM Role",
      "Value": {"Fn::GetAtt": ["SAMLFederatedRole", "Arn"]},
      "Export": {
        "Name": {"Fn::Sub": "${AWS::StackName}-RoleARN"}
      }
    },
    "IdentityProviderARN": {
      "Description": "ARN of the created SAML Identity Provider",
      "Value": {"Ref": "SAMLProvider"},
      "Export": {
        "Name": {"Fn::Sub": "${AWS::StackName}-IdentityProviderARN"}
      }
    }
  }
}
```

------
#### [ YAML ]

```
AWSTemplateFormatVersion: '2010-09-09'
Description: '[AWSDocs] IAM: tutorial_saml-idp-and-federated-role'

Parameters:
  IdentityProviderName:
    Type: String
    Description: Name of the SAML Identity Provider (leave empty for auto-generated name like '{StackName}-{UniqueId}')
    Default: ""
    AllowedPattern: '^$|^[a-zA-Z0-9._-]+$'
    ConstraintDescription: Must be empty or contain only alphanumeric characters, periods, underscores, and hyphens

  IdentityProviderSAMLMetadataDocument:
    Type: String
    Description: SAML metadata document from identity provider

  IdentityProviderAddPrivateKey:
    Type: String
    Description: Optional private key for decrypting SAML assertions. The private key must be a .pem file that uses AES-GCM or AES-CBC encryption algorithm to decrypt SAML assertions.
    Default: ""

  IdentityProviderAssertionEncryptionMode:
    Type: String
    Description: Optional, sets encryption mode for SAML assertions
    Default: ""
    AllowedValues:
      - ""
      - "Allowed"
      - "Required"

  RoleName:
    Type: String
    Description: Name of the IAM Role (leave empty for auto-generated name like '{StackName}-{UniqueId}')
    Default: ""
    AllowedPattern: '^$|^[\w+=,.@-]{1,64}$'
    ConstraintDescription: "Must be empty or 1-64 characters and can contain alphanumeric characters and +=,.@-"

  RolePath:
    Type: String
    Description: Path for the IAM Role
    AllowedPattern: (^\/$)|(^\/.*\/$)
    Default: "/"

  RolePermissionsBoundary:
    Type: String
    Description: Optional ARN of the permissions boundary policy (leave empty for none)
    Default: ""
    
  RoleSessionDuration:
    Description: The maximum session duration (in seconds) that you want to set for the specified role (3600-43200)
    Type: Number
    MinValue: 3600
    MaxValue: 43200
    Default: 7200

  RoleManagedPolicy1:
    Type: String
    Description: Optional managed policy ARN 1
    Default: ""
  RoleManagedPolicy2:
    Type: String
    Description: Optional managed policy ARN 2
    Default: ""
  RoleManagedPolicy3:
    Type: String
    Description: Optional managed policy ARN 3
    Default: ""
  RoleManagedPolicy4:
    Type: String
    Description: Optional managed policy ARN 4
    Default: ""
  RoleManagedPolicy5:
    Type: String
    Description: Optional managed policy ARN 5
    Default: ""

Conditions:
  HasCustomProviderName: !Not [!Equals [!Ref IdentityProviderName, ""]]
  HasCustomRoleName: !Not [!Equals [!Ref RoleName, ""]]
  HasPermissionsBoundary: !Not [!Equals [!Ref RolePermissionsBoundary, ""]]
  HasPolicy1: !Not [!Equals [!Ref RoleManagedPolicy1, ""]]
  HasPolicy2: !Not [!Equals [!Ref RoleManagedPolicy2, ""]]
  HasPolicy3: !Not [!Equals [!Ref RoleManagedPolicy3, ""]]
  HasPolicy4: !Not [!Equals [!Ref RoleManagedPolicy4, ""]]
  HasPolicy5: !Not [!Equals [!Ref RoleManagedPolicy5, ""]]
  HasPrivateKey: !Not [!Equals [!Ref IdentityProviderAddPrivateKey, ""]]
  HasAssertionEncryptionMode: !Not [!Equals [!Ref IdentityProviderAssertionEncryptionMode, ""]]

Resources:
  SAMLProvider:
    Type: AWS::IAM::SAMLProvider
    Properties:
      Name: !If
        - HasCustomProviderName
        - !Ref IdentityProviderName
        - !Ref AWS::NoValue
      SamlMetadataDocument: !Ref IdentityProviderSAMLMetadataDocument
      AddPrivateKey: !If
        - HasPrivateKey
        - !Ref IdentityProviderAddPrivateKey
        - !Ref AWS::NoValue
      AssertionEncryptionMode: !If
        - HasAssertionEncryptionMode
        - !Ref IdentityProviderAssertionEncryptionMode
        - !Ref AWS::NoValue

  SAMLFederatedRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !If
        - HasCustomRoleName
        - !Ref RoleName
        - !Ref AWS::NoValue
      Path: !Ref RolePath
      Description: "SAML federated IAM role for SSO access with specified permissions"
      MaxSessionDuration: !Ref RoleSessionDuration
      PermissionsBoundary: !If
        - HasPermissionsBoundary
        - !Ref RolePermissionsBoundary
        - !Ref AWS::NoValue
      AssumeRolePolicyDocument:
        Version: '2012-10-17		 	 	 '
        Statement:
          - Effect: Allow
            Principal:
              Federated: !Ref SAMLProvider
            Action:
              - 'sts:AssumeRole'
              - 'sts:SetSourceIdentity'
              - 'sts:TagSession'
            Condition:
              StringEquals:
                'SAML:aud': 'https://signin.aws.amazon.com/saml'
      ManagedPolicyArns: !Split
        - ','
        - !Join
          - ','
          - - !If [HasPolicy1, !Ref RoleManagedPolicy1, !Ref "AWS::NoValue"]
            - !If [HasPolicy2, !Ref RoleManagedPolicy2, !Ref "AWS::NoValue"]
            - !If [HasPolicy3, !Ref RoleManagedPolicy3, !Ref "AWS::NoValue"]
            - !If [HasPolicy4, !Ref RoleManagedPolicy4, !Ref "AWS::NoValue"]
            - !If [HasPolicy5, !Ref RoleManagedPolicy5, !Ref "AWS::NoValue"]

Outputs:
  RoleARN:
    Description: ARN of the created IAM Role
    Value: !GetAtt SAMLFederatedRole.Arn
    Export:
      Name: !Sub '${AWS::StackName}-RoleARN'

  IdentityProviderARN:
    Description: ARN of the created SAML Identity Provider
    Value: !Ref SAMLProvider
    Export:
      Name: !Sub '${AWS::StackName}-IdentityProviderARN'
```

------