

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Tutorial IAM: Gunakan CloudFormation template untuk membuat Saml Identity Provider (iDP) dan peran IAM federasi SAMP
<a name="tutorial_saml-idp-and-federated-role"></a>

Untuk membiasakan diri dengan federasi SAMP dan kemampuannya, Anda akan menggunakan CloudFormation template untuk menyiapkan Penyedia Identitas SAMP (iDP) dan peran IAM federasi terkait. Tutorial ini menunjukkan cara membuat kedua sumber daya bersama-sama dalam satu tumpukan.

Template membuat IDP SAMP yang dapat digunakan untuk akses federasi AWS ke sumber daya, bersama dengan peran IAM yang mempercayai penyedia SAMP. Pengguna yang diautentikasi oleh iDP eksternal Anda dapat mengambil peran ini untuk AWS mengakses sumber daya.

Sumber daya yang digunakan terdiri dari yang berikut:
+ IDP SAMP dikonfigurasi dengan dokumen metadata iDP Anda.
+ Peran IAM federasi yang mempercayai SAMP iDP dan dapat diasumsikan oleh pengguna yang diautentikasi.
+ Kebijakan terkelola yang dapat dikonfigurasi yang dapat dilampirkan ke peran untuk memberikan izin tertentu.

## Prasyarat
<a name="tutorial_saml-idp-and-federated-role-prereqs"></a>

Tutorial ini mengasumsikan bahwa Anda telah melakukan hal berikut:
+ Python 3.6 atau yang lebih baru diinstal pada mesin lokal Anda untuk menjalankan perintah Python yang digunakan dalam tutorial ini untuk memformat file XHTML metadata SAMP IDP Anda.
+ Sebuah dokumen metadata SAMP dari IDP eksternal Anda disimpan sebagai file XHTML.

## Buat IDP SAMP dan peran menggunakan CloudFormation
<a name="tutorial_saml-idp-and-federated-role-create"></a>

Untuk membuat SAMP iDP dan peran federasi, Anda akan membuat template dan menggunakannya untuk CloudFormation membuat tumpukan yang berisi kedua sumber daya.

### Buattemplat
<a name="tutorial_saml-idp-and-federated-role-file"></a>

Pertama, buat CloudFormation template.

1. Di [Templat](#tutorial_saml-idp-and-federated-role-template) bagian ini, klik ikon salin pada tab **JSON** atau **YAMAL** untuk menyalin konten templat.

1. Tempelkan konten template ke file baru.

1. Simpan file secara lokal.

### Buat tumpukan
<a name="tutorial_saml-idp-and-federated-role-stack"></a>

Selanjutnya, gunakan template yang telah Anda simpan untuk menyediakan CloudFormation tumpukan.

1. Buka CloudFormation konsol di [https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/).

1. Pada halaman **Stacks**, dari menu **Create stack**, pilih **dengan sumber daya baru (standar)**.

1. Tentukan template:

   1. Di bawah **Prasyarat**, pilih **Pilih templat yang ada**.

   1. Di bawah **Tentukan templat**, pilih **Unggah file templat**.

   1. Pilih **Pilih file**, navigasikan ke file template, dan pilih.

   1. Pilih **Berikutnya**.

1. Tentukan detail tumpukan berikut:

   1. Masukkan nama tumpukan.

   1. Untuk **IdentityProviderName**, Anda dapat membiarkan ini kosong untuk menghasilkan nama secara otomatis berdasarkan nama tumpukan, atau memasukkan nama khusus untuk IDP SAMP Anda.

      Contoh: `CompanyIdP` atau `EnterpriseSSO`

   1. Untuk **IdentityProviderSAMLMetadataDokumen**, Anda perlu memformat file XMLSAM metadata Anda sebagai satu baris sebelum menempelkannya ke bidang ini. Hal ini diperlukan karena CloudFormation konsol memerlukan konten XHTML untuk diformat sebagai satu baris ketika melewati parameter konsol.

      Gunakan perintah Python berikut untuk memformat ulang file XMLmu:

      ```
      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
      ```
**catatan**  
Dokumen metadata SAMP iDP harus diformat sebagai satu baris untuk input parameter konsol. Perintah Python menghapus jeda baris dan spasi tambahan untuk membuat format yang diperlukan sambil mempertahankan semua konten dan struktur asli.

      Salin output dari perintah Python dan tempelkan ke bidang **IdentityProviderSAMLMetadataDokumen**.

      Contoh dokumen metadata SAMP yang diformat (disingkat):

      ```
      <?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. Untuk **RoleName**, Anda dapat membiarkan ini kosong untuk menghasilkan nama secara otomatis berdasarkan nama tumpukan, atau memasukkan nama khusus untuk peran IAM federasi.

      Contoh: `SAML-Developer-Access` atau `SAML-ReadOnly-Role`

   1. Untuk parameter lain, terima nilai default atau masukkan sendiri berdasarkan kebutuhan Anda:
      + **IdentityProviderAddPrivateKey**- Kunci pribadi opsional untuk mendekripsi pernyataan SAMP
      + **IdentityProviderAssertionEncryptionMode**- Mode enkripsi untuk pernyataan SAMP

        Contoh nilai:`Allowed`,`Required`, atau biarkan kosong tanpa enkripsi
      + **RoleSessionDuration**- Durasi sesi maksimum dalam hitungan detik (3600-43200, default 7200)

        Contoh: `14400` (4 jam)
      + **RolePermissionsBoundary**- ARN opsional dari kebijakan batas izin

        Contoh: `arn:aws:iam::123456789012:policy/DeveloperBoundary`
      + **RolePath**- Jalur untuk peran IAM (default adalah/)

        Contoh: `/saml-roles/`
      + **RoleManagedPolicy1-5** - Opsional ARNs hingga 5 kebijakan terkelola untuk dilampirkan

        Contoh untuk RoleManagedPolicy 1: `arn:aws:iam::aws:policy/ReadOnlyAccess`

        Contoh untuk RoleManagedPolicy 2: `arn:aws:iam::123456789012:policy/CustomPolicy`

   1. Pilih **Berikutnya**.

1. Konfigurasikan opsi tumpukan:

   1. Di bawah **Opsi kegagalan tumpukan**, pilih **Hapus semua sumber daya yang baru dibuat**.
**catatan**  
Memilih opsi ini mencegah Anda dari kemungkinan ditagih untuk sumber daya yang kebijakan penghapusan menentukan mereka dipertahankan bahkan jika pembuatan tumpukan gagal.

   1. Terima semua nilai default lainnya.

   1. Di bawah **Kemampuan**, centang kotak untuk mengetahui bahwa CloudFormation mungkin membuat sumber daya IAM di akun Anda.

   1. Pilih **Berikutnya**.

1. Tinjau detail tumpukan dan pilih **Kirim**.

CloudFormation menciptakan tumpukan. Setelah pembuatan tumpukan selesai, sumber daya tumpukan siap digunakan. Anda dapat menggunakan tab **Sumber Daya** di halaman detail tumpukan untuk melihat sumber daya yang disediakan di akun Anda.

Tumpukan akan menampilkan nilai-nilai berikut, yang dapat Anda lihat di tab **Output**:
+ **roLearn**: ARN dari peran IAM yang dibuat (misalnya, `arn:aws:iam::123456789012:role/SAML-Developer-Access` atau `arn:aws:iam::123456789012:role/stack-name-a1b2c3d4` jika menggunakan nama yang dibuat secara otomatis).
+ **IdentityProviderARN: ARN** dari SAMP iDP yang dibuat (misalnya,). `arn:aws:iam::123456789012:saml-provider/CompanyIdP`

Anda akan memerlukan keduanya ARNs saat mengonfigurasi IDP Anda untuk mengirim atribut SAMP yang sesuai untuk asumsi peran.

## Uji federasi SAMP
<a name="tutorial_saml-idp-and-federated-role-using"></a>

Setelah IDP SAMP dan peran federasi telah dibuat, Anda dapat menguji pengaturan federasi.

1. Buka konsol IAM di [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/).

1. Pada panel navigasi, silakan pilih **Penyedia identitas**.

   Anda akan melihat SAMP IDP yang baru dibuat dalam daftar.

1. Pilih nama iDP untuk melihat detailnya.

   Pada halaman detail iDP, Anda dapat melihat dokumen metadata SAMP dan detail konfigurasi lainnya.

1. Di panel navigasi, pilih **Peran**.

1. Temukan dan pilih peran federasi Anda yang baru dibuat.

   Pada halaman detail peran, Anda dapat melihat kebijakan kepercayaan yang memungkinkan IDP SAMP untuk mengambil peran ini.

1. Pilih tab **Hubungan kepercayaan** untuk meninjau kebijakan kepercayaan.

   Kebijakan kepercayaan harus menunjukkan bahwa IDP SAMP dipercaya untuk mengambil peran ini dengan syarat bahwa audiens `SAML:aud` SAMP () cocok. `https://signin.aws.amazon.com/saml`

## Bersihkan: hapus sumber daya
<a name="tutorial_saml-idp-and-federated-role-delete"></a>

Sebagai langkah terakhir, Anda akan menghapus tumpukan dan sumber daya yang dikandungnya.

1. Buka CloudFormation konsol.

1. Pada halaman **Stacks**, pilih tumpukan yang dibuat dari templat, lalu pilih **Hapus**, lalu konfirmasikan **Hapus**.

   CloudFormation memulai penghapusan tumpukan dan semua sumber daya yang disertakan.

## CloudFormation rincian template
<a name="tutorial_saml-idp-and-federated-role-template-details"></a>

### Sumber daya
<a name="tutorial_saml-idp-and-federated-role-template-resources"></a>

 CloudFormation Template untuk tutorial ini akan membuat sumber daya berikut di akun Anda:
+ [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): IDP SAMP yang membangun kepercayaan AWS antara dan IDP eksternal Anda.
+ [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): Peran IAM federasi yang dapat diasumsikan oleh pengguna yang diautentikasi melalui SAMP iDP.

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

Template mencakup parameter yang dapat dikonfigurasi berikut:
+ **IdentityProviderName**- Nama SAMP iDP (biarkan kosong untuk nama yang dibuat secara otomatis)
+ **IdentityProviderSAMLMetadataDocument - Dokumen** metadata SAMP dari IDP Anda (wajib)
+ **IdentityProviderAddPrivateKey**- Kunci pribadi opsional untuk mendekripsi pernyataan SAMP
+ **IdentityProviderAssertionEncryptionMode**- Mode enkripsi untuk pernyataan SAMP
+ **RoleName**- Nama Peran IAM (biarkan kosong untuk nama yang dihasilkan secara otomatis)
+ **RolePath**- Jalur untuk peran IAM (default/)
+ **RolePermissionsBoundary**- ARN opsional kebijakan batas izin
+ **RoleSessionDuration**- Durasi sesi maksimum dalam hitungan detik (3600-43200, default 7200)
+ **RoleManagedPolicy1-5** - Opsional ARNs hingga 5 kebijakan terkelola untuk dilampirkan

## CloudFormation template
<a name="tutorial_saml-idp-and-federated-role-template"></a>

Simpan kode JSON atau YAMAL berikut sebagai file terpisah untuk digunakan sebagai CloudFormation template untuk tutorial ini.

------
#### [ 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'
```

------