

# Recursos personalizados y respaldados por Amazon SNS
<a name="template-custom-resources-sns"></a>

En el siguiente tema se muestra cómo configurar un recurso personalizado con un token de servicio que especifica el tema de Amazon SNS al que CloudFormation envía las solicitudes. También aprenderá la secuencia de eventos y mensajes enviados y recibidos como resultado de la creación, las actualizaciones y la eliminación de pilas de recursos personalizados.

Con los recursos personalizados y Amazon SNS, puede habilitar escenarios como añadir nuevos recursos a una pila e inyectar datos dinámicos a una pila. Por ejemplo, al crear una pila, CloudFormation puede enviar una solicitud `Create` a un tema supervisado por una aplicación que se ejecute en una instancia de Amazon EC2. La notificación de Amazon SNS activa la aplicación para llevar a cabo tareas de aprovisionamiento adicionales, como recuperar un grupo de IP elásticas de direcciones IP. Después de este proceso, la aplicación envía una respuesta (y los datos de salida) que le notifica a CloudFormation que puede seguir con la operación de la pila.

Cuando se especifica un tema de Amazon SNS como destino de un recurso personalizado, CloudFormation envía mensajes al tema de SNS especificado durante las operaciones de pila que involucran el recurso personalizado. Para procesar estos mensajes y realizar las acciones necesarias, debe tener un punto de conexión compatible suscrito al tema de SNS.

Para obtener una introducción a los recursos personalizados y a su funcionamiento, consulte [Cómo funcionan los recursos personalizados](template-custom-resources.md#how-custom-resources-work). Para obtener más información sobre Amazon SNS y su funcionamiento, consulte la [Guía para desarrolladores de Amazon Simple Notification Service](https://docs.aws.amazon.com/sns/latest/dg/).

## Uso de Amazon SNS para crear recursos personalizados
<a name="walkthrough-custom-resources-sns-adding-nonaws-resource"></a>

**Topics**
+ [Paso 1: Creación de una pila](#crpg-walkthrough-stack-creation)
+ [Paso 2: Actualizaciones de pila](#crpg-walkthrough-stack-updates)
+ [Paso 3: Eliminación de pila](#crpg-walkthrough-stack-deletion)

### Paso 1: Creación de una pila
<a name="crpg-walkthrough-stack-creation"></a>

1. <a name="crpg-walkthrough-stack-creation-customer-template"></a>El desarrollador de plantillas crea una pila de CloudFormation que contiene un recurso personalizado. 

   En el siguiente ejemplo de plantilla, usamos el nombre de tipo de recurso personalizado `Custom::SeleniumTester` para el recurso personalizado con ID lógico `MySeleniumTest`. Los nombres del tipo de recurso personalizado deben ser alfanuméricos y pueden tener una longitud máxima de 60 caracteres. 

   El tipo de recurso personalizado se declara con un token de servicio, propiedades específicas de proveedores opcionales y atributos [Fn::GetAtt](resources-section-structure.md#resource-properties-getatt) opcionales que define el proveedor de recursos personalizados. Se pueden usar estas propiedades y atributos para pasar a la información del template developer a custom resource provider y viceversa. El token de servicio especifica un tema de Amazon SNS que el proveedor de recursos ha configurado.

   ```
   {
      "AWSTemplateFormatVersion" : "2010-09-09",
      "Resources" : {
         "MySeleniumTest" : {
            "Type": "Custom::SeleniumTester",
            "Version" : "1.0",
            "Properties" : {
               "ServiceToken": "arn:aws:sns:us-west-2:123456789012:CRTest",
               "seleniumTester" : "SeleniumTest()",
               "endpoints" : [ "http://mysite.com", "http://myecommercesite.com/", "http://search.mysite.com" ],
               "frequencyOfTestsPerHour" : [ "3", "2", "4" ]
            }
         }
      },
      "Outputs" : {
         "topItem" : {
            "Value" : { "Fn::GetAtt" : ["MySeleniumTest", "resultsPage"] }
         },
         "numRespondents" : {
            "Value" : { "Fn::GetAtt" : ["MySeleniumTest", "lastUpdate"] }
         }
      }
   }
   ```
**nota**  
Los nombres y los valores de los datos a los que se accede con `Fn::GetAtt` los devuelve el proveedor de recursos personalizados durante la respuesta del proveedor a CloudFormation. Si custom resource provider es de terceros, template developer debe obtener los nombres de estos valores de devolución desde custom resource provider.

1. <a name="crpg-walkthrough-stack-creation-provider-request"></a>CloudFormation envía una notificación de Amazon SNS al proveedor de recursos con un `"RequestType" : "Create"` que contiene información sobre la pila, las propiedades de recursos personalizados de la plantilla de pila y una URL de S3 para la respuesta.

   El tema de SNS que se usa para enviar la notificación está incrustado en la plantilla en la propiedad `ServiceToken`. Para evitar el uso de un valor codificado, un desarrollador de plantillas puede usar un parámetro de plantilla para que el valor se ingrese en el momento en que se lanza la pila.

   El siguiente ejemplo muestra una solicitud de recurso `Create` personalizado que incluye un nombre de tipo de recurso personalizado, `Custom::SeleniumTester`, creado con un `LogicalResourceId` de `MySeleniumTester`:

   ```
   {
      "RequestType" : "Create",
      "RequestId" : "unique-request-id",
      "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/5b918d10-cd98-11ea-90d5-0a9cd3354c10",
      "ResponseURL" : "http://pre-signed-S3-url-for-response",
      "ResourceType" : "Custom::SeleniumTester",
      "LogicalResourceId" : "MySeleniumTester",
      "ResourceProperties" : {
         "seleniumTester" : "SeleniumTest()",
         "endpoints" : [ "http://mysite.com", "http://myecommercesite.com/", "http://search.mysite.com" ],
         "frequencyOfTestsPerHour" : [ "3", "2", "4" ]
      }
   }
   ```

   Para obtener información detallada sobre el objeto de solicitud de las solicitudes `Create`, consulte el tema [Referencia de solicitud y respuesta](crpg-ref.md).

1. <a name="crpg-walkthrough-stack-creation-provider-response"></a>El custom resource provider procesa los datos enviados por el template developer y determina si la solicitud `Create` se realizó correctamente. El proveedor de recursos usa luego la URL de S3 que CloudFormation ha enviado para remitir una respuesta `SUCCESS` o `FAILED`.

   En función del tipo de respuesta, CloudFormation esperará diferentes campos de respuesta. Para obtener información sobre los campos de respuesta de un tipo de solicitud concreto, consulte la documentación correspondiente a ese tipo de solicitud en la sección [Referencia de solicitud y respuesta](crpg-ref.md).

   En respuesta a una solicitud de creación o actualización, el proveedor de recursos personalizados puede devolver los elementos de datos en el campo `Data` de la respuesta. Estos son pares de nombre/valor y los *nombres* corresponden a los atributos `Fn::GetAtt` que se utilizan con el recurso personalizado de la plantilla de pila. Los *valores* son los datos que se devuelven cuando el desarrollador de la plantilla llama a `Fn::GetAtt` por el recurso con el nombre de atributo.

   El siguiente es un ejemplo de respuesta de recursos personalizados:

   ```
   {
      "Status" : "SUCCESS",
      "RequestId" : "unique-request-id",
      "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/5b918d10-cd98-11ea-90d5-0a9cd3354c10",
      "LogicalResourceId" : "MySeleniumTester",
      "PhysicalResourceId" : "Tester1",
      "Data" : {
         "resultsPage" : "http://www.myexampledomain/test-results/guid",
         "lastUpdate" : "2012-11-14T03:30Z"
      }
   }
   ```

   Para obtener información detallada sobre el objeto de respuesta de las solicitudes `Create`, consulte el tema [Referencia de solicitud y respuesta](crpg-ref.md).

   Los campos `StackId`, `RequestId` y `LogicalResourceId` deben copiarse textualmente de la solicitud.

1. <a name="crpg-walkthrough-stack-creation-stack-status"></a> CloudFormation declara el estado de pila como `CREATE_COMPLETE` o `CREATE_FAILED`. Si la pila se creó correctamente, el desarrollador de plantillas puede utilizar los valores de salida del recurso personalizado que se creó, accediendo a ellos con [Fn::GetAtt](resources-section-structure.md#resource-properties-getatt).

   Por ejemplo, la plantilla de recursos personalizados empleados para ilustrar usó `Fn::GetAtt` para copiar salidas de recursos en las salidas de pila:

   ```
   "Outputs" : {
      "topItem" : {
         "Value" : { "Fn::GetAtt" : ["MySeleniumTest", "resultsPage"] }
      },
      "numRespondents" : {
         "Value" : { "Fn::GetAtt" : ["MySeleniumTest", "lastUpdate"] }
      }
   }
   ```

### Paso 2: Actualizaciones de pila
<a name="crpg-walkthrough-stack-updates"></a>

Para actualizar una pila existente, debe enviar una plantilla que especifique las actualizaciones de las propiedades de recursos de la pila, tal y como se muestra en el ejemplo siguiente. CloudFormation actualiza únicamente los recursos que tengan los cambios especificados en la plantilla. Para obtener más información, consulte [Comprensión de los comportamientos de actualización de los recursos de la pila](using-cfn-updating-stacks-update-behaviors.md).

Puede actualizar los recursos personalizados que requieren una sustitución del recurso físico subyacente. Al actualizar un recurso personalizado en una plantilla de CloudFormation, CloudFormation envía una solicitud de actualización a dicho recurso personalizado. Si un recurso personalizado requiere una sustitución, el nuevo recurso personalizado debe enviar una respuesta con el nuevo ID físico. Cuando CloudFormation recibe la respuesta, compara el `PhysicalResourceId` entre los recursos personalizados antiguos y nuevos. Si son diferentes, CloudFormation reconoce la actualización como sustitución y envía una solicitud de eliminación al antiguo recurso, tal y como se muestra en [Paso 3: Eliminación de pila](#crpg-walkthrough-stack-deletion).

**nota**  
Si no realizó cambios en el recurso personalizado, CloudFormation no le enviará solicitudes durante la actualización de una pila.

1. <a name="crpg-walkthrough-stack-updates-customer-template"></a>template developer inicia una actualización de la pila que contiene un recurso personalizado. Durante una actualización, template developer puede especificar nuevas propiedades en la plantilla de pila.

   El siguiente es un ejemplo de `Update` para la plantilla de pila que usa un tipo de recurso personalizado:

   ```
   {
      "AWSTemplateFormatVersion" : "2010-09-09",
      "Resources" : {
         "MySeleniumTest" : {
            "Type": "Custom::SeleniumTester",
            "Version" : "1.0",
            "Properties" : {
               "ServiceToken": "arn:aws:sns:us-west-2:123456789012:CRTest",
               "seleniumTester" : "SeleniumTest()",
               "endpoints" : [ "http://mysite.com", "http://myecommercesite.com/", "http://search.mysite.com",
                  "http://mynewsite.com" ],
               "frequencyOfTestsPerHour" : [ "3", "2", "4", "3" ]
            }
         }
      },
      "Outputs" : {
         "topItem" : {
            "Value" : { "Fn::GetAtt" : ["MySeleniumTest", "resultsPage"] }
         },
         "numRespondents" : {
            "Value" : { "Fn::GetAtt" : ["MySeleniumTest", "lastUpdate"] }
         }
      }
   }
   ```

1. <a name="crpg-walkthrough-stack-updates-provider-request"></a>CloudFormation envía una notificación de Amazon SNS al proveedor de recursos con un `"RequestType" : "Update"` que contiene información similar a la llamada `Create`, salvo que el campo `OldResourceProperties` contiene las propiedades del antiguo recurso y ResourceProperties contiene las del recurso actualizado (si existe).

   El siguiente es un ejemplo de una solicitud de `Update`:

   ```
   {
      "RequestType" : "Update",
      "RequestId" : "unique-request-id",
      "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/5b918d10-cd98-11ea-90d5-0a9cd3354c10",
      "ResponseURL" : "http://pre-signed-S3-url-for-response",
      "ResourceType" : "Custom::SeleniumTester",
      "LogicalResourceId" : "MySeleniumTester",
      "PhysicalResourceId" : "Tester1",
      "ResourceProperties" : {
         "seleniumTester" : "SeleniumTest()",
         "endpoints" : [ "http://mysite.com", "http://myecommercesite.com/", "http://search.mysite.com",
            "http://mynewsite.com" ],
         "frequencyOfTestsPerHour" : [ "3", "2", "4", "3" ]
      },
      "OldResourceProperties" : {
         "seleniumTester" : "SeleniumTest()",
         "endpoints" : [ "http://mysite.com", "http://myecommercesite.com/", "http://search.mysite.com" ],
         "frequencyOfTestsPerHour" : [ "3", "2", "4" ]
      }
   }
   ```

   Para obtener información detallada sobre el objeto de solicitud de las solicitudes `Update`, consulte el tema [Referencia de solicitud y respuesta](crpg-ref.md).

1. <a name="crpg-walkthrough-stack-updates-provider-response"></a>El proveedor de recursos personalizados procesa los datos que CloudFormation envía. El recurso personalizado realiza la actualización y envía una respuesta `SUCCESS` o `FAILED` a la URL de S3. CloudFormation compara entonces los valores de `PhysicalResourceIDs` de los recursos personalizados antiguos y nuevos. Si son diferentes, CloudFormation reconoce que la actualización requiere una sustitución y envía una solicitud de eliminación al antiguo recurso. El siguiente ejemplo demuestra la respuesta de custom resource provider a una solicitud de `Update`.

   ```
   {
      "Status" : "SUCCESS",
      "RequestId" : "unique-request-id",
      "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/5b918d10-cd98-11ea-90d5-0a9cd3354c10",
      "LogicalResourceId" : "MySeleniumTester",
      "PhysicalResourceId" : "Tester2"
   }
   ```

   Para obtener información detallada sobre el objeto de respuesta de las solicitudes `Update`, consulte el tema [Referencia de solicitud y respuesta](crpg-ref.md).

   Los campos `StackId`, `RequestId` y `LogicalResourceId` deben copiarse textualmente de la solicitud.

1. <a name="crpg-walkthrough-stack-updates-stack-status"></a>CloudFormation declara el estado de pila como `UPDATE_COMPLETE` o `UPDATE_FAILED`. Si falla la actualización, la pila vuelve a su estado anterior. Si la pila se ha actualizado correctamente, template developer puede obtener acceso a cualquier nuevo valor de salida del recurso personalizado creado con `Fn::GetAtt`.

### Paso 3: Eliminación de pila
<a name="crpg-walkthrough-stack-deletion"></a>

1. <a name="crpg-walkthrough-stack-deletion-customer-template"></a>El desarrollador de plantillas elimina una pila que contiene un recurso personalizado. CloudFormation obtiene las propiedades actuales especificadas en la plantilla de pila junto con el tema de SNS y se prepara para realizar una solicitud al proveedor de recursos personalizados.

1. <a name="crpg-walkthrough-stack-deletion-provider-request"></a>CloudFormation envía una notificación de Amazon SNS al proveedor de recursos con un `"RequestType" : "Delete"` que contiene información actual sobre la pila, las propiedades de recursos personalizados de la plantilla de pila y una URL de S3 para la respuesta.

   Cuando se elimina una pila o se hace una actualización que elimina o sustituye el recurso personalizado, CloudFormation compara el valor de `PhysicalResourceId` de los recursos personalizados antiguos con los nuevos. Si son diferentes, CloudFormation reconoce la actualización como sustitución y envía una solicitud de eliminación para el recurso anterior (`OldPhysicalResource`), tal y como se muestra en el siguiente ejemplo de una solicitud `Delete`.

   ```
   {
      "RequestType" : "Delete",
      "RequestId" : "unique-request-id",
      "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/5b918d10-cd98-11ea-90d5-0a9cd3354c10",
      "ResponseURL" : "http://pre-signed-S3-url-for-response",
      "ResourceType" : "Custom::SeleniumTester",
      "LogicalResourceId" : "MySeleniumTester",
      "PhysicalResourceId" : "Tester1",
      "ResourceProperties" : {
         "seleniumTester" : "SeleniumTest()",
         "endpoints" : [ "http://mysite.com", "http://myecommercesite.com/", "http://search.mysite.com",
            "http://mynewsite.com" ],
         "frequencyOfTestsPerHour" : [ "3", "2", "4", "3" ]
      }
   }
   ```

   Para obtener información detallada sobre el objeto de solicitud de las solicitudes `Delete`, consulte el tema [Referencia de solicitud y respuesta](crpg-ref.md).

   `DescribeStackResource`, `DescribeStackResources` y `ListStackResources` muestran el nombre definido por el usuario en caso de que se haya especificado.

1. <a name="crpg-walkthrough-stack-deletion-provider-response"></a>El proveedor de recursos personalizados procesa los datos enviados por CloudFormation y determina si la solicitud `Delete` se realizó correctamente. El proveedor de recursos usa luego la URL de S3 que CloudFormation ha enviado para remitir una respuesta `SUCCESS` o `FAILED`. Para poder eliminar correctamente una pila con un recurso personalizado, el custom resource provider debe responder correctamente a una solicitud de eliminación.

   A continuación se muestra un ejemplo de respuesta de custom resource provider a una solicitud de `Delete`:

   ```
   {
      "Status" : "SUCCESS",
      "RequestId" : "unique-request-id",
      "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/5b918d10-cd98-11ea-90d5-0a9cd3354c10",
      "LogicalResourceId" : "MySeleniumTester",
      "PhysicalResourceId" : "Tester1"
   }
   ```

   Para obtener información detallada sobre el objeto de respuesta de las solicitudes `Delete`, consulte el tema [Referencia de solicitud y respuesta](crpg-ref.md).

   Los campos `StackId`, `RequestId` y `LogicalResourceId` deben copiarse textualmente de la solicitud.

1. <a name="crpg-walkthrough-stack-updates-stack-status-delete"></a>CloudFormation declara el estado de pila como `DELETE_COMPLETE` o `DELETE_FAILED`.