

# Tutorial de IAM: use una plantilla de CloudFormation para crear un proveedor de identidades (IdP) de SAML
<a name="tutorial_saml-idp"></a>

Para configurar la federación de SAML en su cuenta de AWS, debe crear un proveedor de identidades (IdP) de SAML. En este tutorial, se muestra cómo usar una plantilla de CloudFormation para crear un IdP de SAML que establezca confianza entre AWS y su IdP externo.

La plantilla crea un IdP de SAML configurado con el documento de metadatos de su IdP. A continuación, los roles de IAM federados pueden hacer referencia a este IdP para permitir que los usuarios autenticados de su IdP externo accedan a los recursos de AWS.

El recurso desplegado consiste en un IdP de SAML configurado con el documento de metadatos de su IdP y la configuración de cifrado opcional.

## Requisitos previos
<a name="tutorial_saml-idp-prereqs"></a>

En este tutorial se presupone que los elementos siguientes ya existen:
+ Python 3.6 o una versión posterior instalada en su máquina local para ejecutar el comando de Python utilizado en este tutorial a fin de formatear el archivo XML de metadatos SAML de su IdP.
+ Un documento de metadatos de SAML de su IdP externo guardado como un archivo XML.

## Crear un IdP de SAML mediante CloudFormation
<a name="tutorial_saml-idp-create"></a>

Para crear el IdP de SAML, debe crear una plantilla de CloudFormation y utilizarla para crear una pila que contenga el recurso del IdP.

### Crear la plantilla
<a name="tutorial_saml-idp-file"></a>

Primero, cree la plantilla de CloudFormation.

1. En la sección [Plantilla](#tutorial_saml-idp-template), haga clic en el icono de copia de la pestaña **JSON** o **YAML** para copiar el contenido de la plantilla.

1. Pegue el contenido de la plantilla en un archivo nuevo.

1. Guarde el archivo localmente.

### Creación de la pila
<a name="tutorial_saml-idp-stack"></a>

A continuación, utilice la plantilla que creó para aprovisionar una pila de CloudFormation.

1. Abra la consola de CloudFormation en [https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/).

1. En la página **Pilas**, para **Crear pila** elija **Con nuevos recursos (estándar)**.

1. En Especificar plantilla:

   1. En **Requisito previo**, elija **Seleccionar una plantilla existente**.

   1. En **Especificar plantilla**, elija **Cargar un archivo de plantilla**.

   1. Seleccione **Elegir archivo** para navegar hasta el archivo y seleccionarlo.

   1. Elija **Siguiente**.

1. Especifique los siguientes detalles de la pila:

   1. Introduzca un nombre de pila.

   1. En el caso de **IdentityProviderName**, puede dejar este campo vacío para generar automáticamente un nombre basado en el nombre de la pila o introducir un nombre personalizado para su IdP de SAML. Los nombres personalizados deben contener únicamente caracteres alfanuméricos, puntos y guiones.

   1. En el caso de **IdentityProviderSAMLMetadataDocument**, debe formatear el archivo XML de metadatos de SAML en una sola línea antes de pegarlo en este campo. Esto es necesario porque la consola de CloudFormation requiere que el contenido XML se formatee como una sola línea cuando se pasa por los parámetros de la consola.

      Use el siguiente comando de Python para cambiar el formato del archivo 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
      ```
**nota**  
El documento de metadatos de SAML del IdP debe estar formateado en una sola línea para introducir los parámetros en la consola. El comando Python elimina los saltos de línea y los espacios en blanco adicionales para crear el formato requerido y, al mismo tiempo, mantener todo el contenido y la estructura originales.

      Copie el resultado del comando Python y péguelo en el campo **IdentityProviderSAMLMetadataDocument**.

      Ejemplo de documento de metadatos de SAML formateado (abreviado):

      ```
      <?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. Para otros parámetros, acepte los valores predeterminados o introduzca los propios en función de sus requisitos:
      + **IdentityProviderAddPrivateKey**: clave privada opcional para descifrar las aserciones de SAML
      + **IdentityProviderAssertionEncryptionMode**: opcional, establece el modo de cifrado para las aserciones de SAML (permitido, obligatorio o vacío)

   1. Elija **Siguiente**.

1. Configure las opciones la pila:

   1. En las **opciones de error de pila**, seleccione **Eliminar todos los recursos recién creados.**
**nota**  
Si elige esta opción, evita que se le facturen los recursos cuya política de eliminación especifique que se conservarán incluso si se produce un error durante la creación de la pila.

   1. Acepte todos los demás valores predeterminados.

   1. En **Capacidades**, seleccione la casilla para aceptar que CloudFormation puede crear recursos de IAM en su cuenta.

   1. Elija **Siguiente**.

1. Revise los detalles de la pila y elija **Enviar**.

CloudFormation crea el stack. Una vez completada la creación de la pila, los recursos de la pila están listos para usarse. Puede usar la pestaña **Recursos** de la página de detalles de la pila para ver los recursos que se aprovisionaron en su cuenta.

La pila generará los siguientes valores, que puede ver en la pestaña **Resultados**:
+ **ProviderARN**: el ARN del IdP de SAML creado (por ejemplo, `arn:aws:iam::123456789012:saml-provider/CompanyIdP`). Necesitará este ARN para crear funciones que confíen en este proveedor.
+ **ProviderName**: el nombre del IdP de SAML creado (por ejemplo, `CompanyIdP` si especificó un nombre personalizado o `my-saml-stack-saml-provider` si utilizó el nombre predeterminado).

Estos resultados también se exportan, lo que permite que otras pilas de CloudFormationlas importen mediante la función de `Fn::ImportValue`.

## Verificar el IdP de SAML
<a name="tutorial_saml-idp-using"></a>

Una vez creado el IdP de SAML, puede verificar su configuración y anotar su ARN para usarlo con los roles federados.

1. Abra la consola de IAM en [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/).

1. En el panel de navegación, elija **Proveedores de identidades**.

   Ahora debería poder ver el IdP de SAML recién creado en la lista.

1. Seleccione el nombre del IdP para ver sus detalles.

   En la página de detalles del IdP, puede ver el documento de metadatos de SAML y otros detalles de configuración.

1. Anote el **ARN del proveedor** que aparece en la página de detalles.

   Necesitará este ARN al crear roles de IAM federados que confíen en este IdP.

1. Revise el documento de metadatos para asegurarse de que coincida con lo que proporcionó su IdP externo.

El IdP de SAML ya está listo para usarse en roles de IAM federados. Puede crear roles que confíen en este IdP para permitir que los usuarios autenticados de su IdP externo asuman esos roles y accedan a los recursos de AWS.

## Limpieza: elimine recursos
<a name="tutorial_saml-idp-delete"></a>

Como último paso, eliminará la pila y los recursos que contiene.

1. Abra la consola de CloudFormation.

1. En la página **Pilas**, seleccione la pila creada a partir de la plantilla, seleccione **Eliminar** y, a continuación, confirme **Eliminar**.

   CloudFormation inicia la eliminación de la pila y de todos los recursos que incluye.

## Detalles de la plantilla de CloudFormation
<a name="tutorial_saml-idp-template-details"></a>

### Recursos
<a name="tutorial_saml-idp-template-resources"></a>

La plantilla de CloudFormation para este tutorial crea el siguiente recurso en su cuenta:

[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): un IdP de SAML que establece confianza entre AWS y su IdP externo.

### Configuración
<a name="tutorial_saml-idp-template-config"></a>

La plantilla incluye los siguientes parámetros configurables:
+ **IdentityProviderName**: el nombre del IdP de SAML (déjelo en blanco para que el nombre se genere automáticamente)

  Ejemplo: `CompanyIdP` o `EnterpriseSSO`
+ **IdentityProviderSAMLMetadataDocument**: el documento de metadatos de SAML de su IdP externo (formateado en una sola línea)
+ **IdentityProviderAddPrivateKey**: clave privada opcional para descifrar las aserciones de SAML
+ **IdentityProviderAssertionEncryptionMode**: opcional, establece el modo de cifrado para las aserciones de SAML

## Plantilla de CloudFormation
<a name="tutorial_saml-idp-template"></a>

Guarde el siguiente código JSON o YAML como un archivo independiente para usarlo como plantilla de CloudFormation en este tutorial.

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

```
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "[AWSDocs] IAM: tutorial_saml-idp",
  "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"]
    }
  },
  "Conditions": {
    "HasPrivateKey": {"Fn::Not": [{"Fn::Equals": [{"Ref": "IdentityProviderAddPrivateKey"}, ""]}]},
    "HasEncryptionMode": {"Fn::Not": [{"Fn::Equals": [{"Ref": "IdentityProviderAssertionEncryptionMode"}, ""]}]},
    "HasCustomName": {"Fn::Not": [{"Fn::Equals": [{"Ref": "IdentityProviderName"}, ""]}]}
  },
  "Resources": {
    "SAMLProvider": {
      "Type": "AWS::IAM::SAMLProvider",
      "Properties": {
        "Name": {"Fn::If": ["HasCustomName", {"Ref": "IdentityProviderName"}, {"Ref": "AWS::NoValue"}]},
        "SamlMetadataDocument": {"Ref": "IdentityProviderSAMLMetadataDocument"},
        "Tags": [
          {
            "Key": "Name",
            "Value": {"Fn::If": ["HasCustomName", {"Ref": "IdentityProviderName"}, {"Fn::Sub": "${AWS::StackName}-saml-provider"}]}
          }
        ],
        "AddPrivateKey": {"Fn::If": ["HasPrivateKey", {"Ref": "IdentityProviderAddPrivateKey"}, {"Ref": "AWS::NoValue"}]},
        "AssertionEncryptionMode": {"Fn::If": ["HasEncryptionMode", {"Ref": "IdentityProviderAssertionEncryptionMode"}, {"Ref": "AWS::NoValue"}]}
      }
    }
  },
  "Outputs": {
    "ProviderARN": {
      "Description": "ARN of the created SAML Identity Provider",
      "Value": {"Ref": "SAMLProvider"},
      "Export": {
        "Name": {"Fn::Sub": "${AWS::StackName}-ProviderARN"}
      }
    },
    "ProviderName": {
      "Description": "Name of the SAML Identity Provider",
      "Value": {"Fn::If": ["HasCustomName", {"Ref": "IdentityProviderName"}, {"Fn::Sub": "${AWS::StackName}-saml-provider"}]},
      "Export": {
        "Name": {"Fn::Sub": "${AWS::StackName}-ProviderName"}
      }
    }
  }
}
```

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

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

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"

Conditions:
  HasPrivateKey: !Not [!Equals [!Ref IdentityProviderAddPrivateKey, ""]]
  HasEncryptionMode: !Not [!Equals [!Ref IdentityProviderAssertionEncryptionMode, ""]]
  HasCustomName: !Not [!Equals [!Ref IdentityProviderName, ""]]

Resources:
  SAMLProvider:
    Type: 'AWS::IAM::SAMLProvider'
    Properties:
      Name: !If
        - HasCustomName
        - !Ref IdentityProviderName
        - !Ref AWS::NoValue
      SamlMetadataDocument: !Ref IdentityProviderSAMLMetadataDocument
      Tags:
        - Key: Name
          Value: !If
            - HasCustomName
            - !Ref IdentityProviderName
            - !Sub '${AWS::StackName}-saml-provider'
      AddPrivateKey: !If
        - HasPrivateKey
        - !Ref IdentityProviderAddPrivateKey
        - !Ref AWS::NoValue
      AssertionEncryptionMode: !If
        - HasEncryptionMode
        - !Ref IdentityProviderAssertionEncryptionMode
        - !Ref AWS::NoValue

Outputs:
  ProviderARN:
    Description: 'ARN of the created SAML Identity Provider'
    Value: !Ref SAMLProvider
    Export:
      Name: !Sub '${AWS::StackName}-ProviderARN'
  
  ProviderName:
    Description: 'Name of the SAML Identity Provider'
    Value: !If
      - HasCustomName
      - !Ref IdentityProviderName
      - !Sub '${AWS::StackName}-saml-provider'
    Export:
      Name: !Sub '${AWS::StackName}-ProviderName'
```

------