Procesamientos personalizados en plantillas de CloudFormation con macros de plantillas - AWS CloudFormation

Procesamientos personalizados en plantillas de CloudFormation con macros de plantillas

Las macros le permiten realizar un procesamiento personalizado de plantillas, desde acciones sencillas como operaciones de búsqueda y reemplazo, hasta amplias transformaciones de plantillas completas.

Para que se haga una idea de la gran variedad de posibilidades, piense en las transformaciones AWS::Include y AWS::Serverless, que son macros alojadas por CloudFormation:

Cómo funcionan las macros de CloudFormation

El procesamiento de plantillas con macros consta de dos fases principales: crear la macro en sí y luego usar la macro para procesar las plantillas.

Para crear una definición de macro, tiene que crear lo siguiente:

  • Una función de AWS Lambda para realizar el procesamiento de la plantilla. Esta función de Lambda acepta un fragmento de código o bien la totalidad de la plantilla, así como los parámetros adicionales que se definan. Devuelve el fragmento de código de plantilla procesados o toda la plantilla como respuesta.

  • Un recurso del tipo AWS::CloudFormation::Macro, para que los usuarios puedan llamar a la función de Lambda desde plantillas de CloudFormation. Este recurso especifica el ARN de la función de Lambda para invocar esta macro y propiedades opcionales adicionales para ayudar con la depuración. Para crear este recurso dentro de una cuenta, cree una plantilla de pila que incluya el recurso AWS::CloudFormation::Macro y, a continuación, cree otra pila a partir de la plantilla. AWS Actualmente, CloudFormation StackSets no es compatible con la creación o la actualización de conjuntos de pilas con permisos administrados por servicios a partir de plantillas que hacen referencia a macros.

Para utilizar una macro, consulte la macro en su plantilla:

  • Para procesar una sección o un fragmento de una plantilla, consulte la macro en una función que se encuentre ubicada en relación con el contenido de la plantilla que desea transformar. Cuando utilice Fn::Transform, también puede transferir todos los parámetros especificados que requiera.

  • Para procesar una plantilla completa, consulte la macro en la sección Sección de Transform para las plantillas de CloudFormation de la plantilla.

A continuación, se suele crear un conjunto de cambios y, a continuación, ejecutarlo. (El procesamiento de macros puede agregar varios recursos de los que quizás no esté al tanto. Para asegurarse de que está al tanto de todos los cambios hechos por las macros, le recomendamos usar conjuntos de cambios). CloudFormation pasa el contenido de la plantilla especificada, junto con cualquier parámetro especificado adicional, a la función de Lambda especificada en el recurso de macro. La función de Lambda devuelve el contenido de la plantilla procesada, ya sea como fragmento o como una plantilla completa.

Después de que se hayan llamado a todas las macros de la plantilla, CloudFormation genera un conjunto de cambios que incluye el contenido de la plantilla procesada. Después de revisar el conjunto de cambios, ejecútelo para aplicar los cambios.

importante

Si la plantilla del conjunto de pilas hace referencia a una o más macros, debe crear el conjunto de pilas directamente desde la plantilla procesada, sin revisar primero los cambios resultantes en un conjunto de cambios. Para crear o actualizar el conjunto de pilas directamente, debe utilizar las acciones CreateStackSet o UpdateStackSet y especificar la capacidad CAPABILITY_AUTO_EXPAND. Antes de crear o actualizar un conjunto de pilas a partir de una plantilla que haga referencia directamente a macros, asegúrese de saber qué procesamiento realiza cada macro.

Use la función Fn::Transform intrínseca o la sección Transform de la plantilla, para pasar el contenido de la plantilla y sus parámetros asociados a la función de Lambda subyacente de la macro, que devuelve el contenido de la plantilla procesada.
nota

Si se siente cómodo creando o actualizando una pila directamente desde una plantilla procesada, sin antes haber revisado los cambios propuestos en un conjunto de cambios, puede hacerlo especificando la capacidad CAPABILITY_AUTO_EXPAND durante una solicitud UpdateStack o CreateStack. Solo debe crear pilas directamente desde una plantilla de pila que haga referencia a macros si sabe qué procesamiento realiza cada macro.

Para obtener más información, consulte CreateStack o UpdateStack en la Referencia de la API de AWS CloudFormation.

Creación de una definición de macro de CloudFormation

Al crear una definición de macro, la definición de macro hace que la función de Lambda subyacente esté disponible en la cuenta especificada, de modo que CloudFormation la llame para procesar las plantillas.

Interfaz de la función de macro de CloudFormation

En el caso de las macros, CloudFormation llama a las funciones de Lambda subyacentes con la siguiente asignación de eventos. CloudFormation envía su solicitud en formato JSON y espera que la respuesta de la función también esté en formato JSON.

{ "region" : "us-east-1", "accountId" : "$ACCOUNT_ID", "fragment" : { ... }, "transformId" : "$TRANSFORM_ID", "params" : { ... }, "requestId" : "$REQUEST_ID", "templateParameterValues" : { ... } }
  • region

    La región en la que la reside la macro.

  • accountId

    El ID de la cuenta desde la que la macro invoca la función de Lambda.

  • fragment

    El contenido de la plantilla disponible para el procesamiento personalizado, en formato JSON.

    • Para las macros incluidas en la sección de plantilla Transform, esto es toda la plantilla, a excepción de la sección Transform.

    • Para macros incluidas en una llamada de función intrínseca Fn::Transform, esto incluye todos los nodos secundarios (y sus hijos) en función de la ubicación de la función intrínseca dentro de la plantilla, excepto para la función Fn::Transform. Para obtener más información, consulte Ámbito de las macros de CloudFormation.

  • transformId

    El nombre de la macro que invoca esta función.

  • params

    Para las llamadas de la función Fn::Transform, todos los parámetros especificados para la función. CloudFormation no evalúa estos parámetros antes de transferirlos a la función.

    Para macros incluidas en la sección de plantilla Transform, esta sección está vacía.

  • requestId

    El ID de la solicitud que invoca esta función.

  • templateParameterValues

    Todos los parámetros especificados en la sección Referencia sintáctica de la sección Parameters para las plantillas de CloudFormation de la plantilla. CloudFormation evalúa estos parámetros antes de transferirlos a la función.

CloudFormation espera que la función subyacente devuelva una respuesta con formato JSON siguiente:

{ "requestId" : "$REQUEST_ID", "status" : "$STATUS", "fragment" : { ... } "errorMessage": "optional error message for failures" }
  • requestId

    El ID de la solicitud que invoca esta función. Debe coincidir con el ID de la solicitud que proporciona CloudFormation al invocar la función.

  • estado

    El estado de la solicitud (no distingue entre mayúsculas y minúsculas). Debe definirse en success. CloudFormation trata todas las demás respuestas como error.

  • fragment

    El contenido de la plantilla procesada para que CloudFormation lo incluya en la plantilla procesada, incluidos los elementos secundarios. CloudFormation sustituye el contenido de la plantilla que se transfiere a la función de Lambda con el fragmento de código de plantilla que recibe en la respuesta de Lambda.

    El contenido de la plantilla procesada tiene que ser un formato JSON válido, y su inclusión en la plantilla procesada debe generar una plantilla válida.

    Si la función no cambia realmente el contenido de la plantilla que CloudFormation le pasa, pero el usuario sigue necesitando incluir ese contenido en la plantilla procesada, la función debe devolver dicho contenido de plantilla a CloudFormation en su respuesta.

  • errorMessage

    El mensaje de error que explica por qué falló la transformación. CloudFormation muestra este mensaje de error en el panel Events (Eventos) de la página Stack details (Detalles de la pila) para la pila.

    Por ejemplo, “(Error al crear un conjunto de cambios. Se produjo un error en la transformación del Cuenta de AWS número de cuenta::nombre de macro: cadena de mensaje de error)”.

Para obtener más información sobre consideraciones adicionales al crear macros, consulte Consideraciones sobre la creación de definiciones de macros de CloudFormation.

Ámbito y permisos de la cuenta de macro de CloudFormation

Puede utilizar macros solo en la cuenta en la que se han creado como un recurso. El nombre de la macro tiene que ser único en una cuenta determinada. Sin embargo, puede hacer que la misma funcionalidad esté disponible en varias cuentas habilitando el acceso entre cuentas en la función de Lambda subyacente y, a continuación, creando definiciones de macro que haga referencia a dicha función en varias cuentas. En el ejemplo siguiente, tres cuentas macro contienen definiciones y cada una de ellas apunta a la misma función de Lambda.

Al permitir el acceso entre cuentas en la función de Lambda, AWS le permite crear macros en varias cuentas que hacen referencia a esa función.

Para obtener más información, consulte Información general de la administración de permisos de acceso a sus recursos de AWS Lambda) en la Guía para desarrolladores de AWS Lambda.

Para crear una definición de macro, el usuario debe tener permisos para crear una pila o un conjunto de pilas dentro de la cuenta especificada.

Para que CloudFormation ejecute correctamente una macro incluida en una plantilla, el usuario debe tener permisos Invoke para la función de Lambda subyacente. Para evitar posibles transmisiones de permisos, CloudFormation representa al usuario al ejecutar la macro. Para obtener más información, consulte Modelo de permisos de Lambda en la Guía para desarrolladores de AWS Lambda y Claves de contexto de condición y acciones para AWS Lambda en la Guía del usuario de IAM.

Las transformaciones Transformación AWS::Serverless y Transformación AWS::Include son macros alojadas por CloudFormation. No se necesitan permisos especiales para utilizarlas y están disponibles desde cualquier cuenta en CloudFormation.

Depuración de macros de CloudFormation

Para ayudar en la depuración, también puede especificar las propiedades LogRoleArn y LogGroupName cuando cree el tipo de recurso AWS::CloudFormation::Macro para su macro. Estas propiedades le permiten especificar el grupo de registro de CloudWatch al que CloudFormation envía la información de registro de errores al invocar la función de AWS Lambda subyacente de la macro y el rol que CloudFormation debe asumir al enviar entradas de registro a dichos registros.

Facturación

Cuando se ejecuta una macro, se factura al propietario de la función de Lambda todos los gastos relacionados con la ejecución de esa función.

Las transformaciones Transformación AWS::Serverless y Transformación AWS::Include son macros alojadas por CloudFormation. No se cobra por usarlas.

Consideraciones sobre la creación de definiciones de macros de CloudFormation

Al crear definiciones de macros, tenga en cuenta lo siguiente:

  • Las macros se admiten únicamente en Regiones de AWS donde AWS Lambda está disponible. Para ver una lista de las regiones en las que Lambda está disponible, consulte Puntos de conexión y cuotas de AWS Lambda.

  • Todos los fragmentos de código de plantilla procesados tienen que ser un JSON válido.

  • Cualquier fragmento de plantilla procesado debe pasar las comprobaciones de validación para una operación de creación de pila, actualización de pila, creación de conjunto de pilas o actualización de conjunto de pilas.

  • CloudFormation resuelve en primer lugar las macros y, a continuación, procesa la plantilla. La plantilla obtenida tiene que ser un JSON válido y no debe superar el límite de tamaño de la plantilla.

  • Debido al orden en que CloudFormation procesa los elementos de una plantilla, una macro no puede incluir módulos en el contenido de la plantilla procesada que devuelve a CloudFormation. Para obtener más información sobre módulos, consulte Developing modules (Desarrollo de módulos) en la Guía del usuario de la CLI de CloudFormation.

  • Cuando se utiliza la característica de restauración de actualizaciones, CloudFormation utiliza una copia de la plantilla original. Se restaura en la plantilla original incluso si el fragmento de código incluido se ha cambiado.

  • La inclusión de macros dentro de otras macros no funciona porque no procesamos las macros de forma recursiva.

  • La función intrínseca Fn::ImportValue no es compatible actualmente en las macros.

  • Las funciones intrínsecas incluidas en la plantilla se evalúan después de cualquier macro. Por lo tanto, el contenido de plantilla procesado que su macro devuelve puede incluir llamadas a funciones intrínsecas y se evalúan como de costumbre.

  • Actualmente, StackSets no es compatible con la creación o la actualización de conjuntos de pilas con permisos administrados por servicios a partir de plantillas que hacen referencia a macros de CloudFormation.

  • Si la plantilla del conjunto de pilas hace referencia a una o más macros, debe crear o actualizar el conjunto de pilas directamente desde la plantilla procesada, sin revisar primero los cambios resultantes en un conjunto de cambios. Para crear o actualizar el conjunto de pilas directamente, utilice las acciones CreateStackSet o UpdateStackSet y especifique la capacidad CAPABILITY_AUTO_EXPAND. El procesamiento de macros puede añadir numerosos recursos que usted podría desconocer. Antes de crear o actualizar un conjunto de pilas a partir de una plantilla que haga referencia directamente a macros, asegúrese de saber qué procesamiento realiza cada macro.

  • Actualmente, los conjuntos de cambios no admiten pilas anidadas. Si desea crear o actualizar una pila mediante una plantilla de pilas que haga referencia a macros y contenga pilas anidadas, deberá crear o actualizar la pila directamente. Para hacerlo, use la acción CreateStack o UpdateStack y especifique la capacidad CAPABILITY_AUTO_EXPAND.

Para crear una definición de macro de CloudFormation:
  1. Desarrolle una función AWS Lambda que procese plantillas de CloudFormation.

    La función de Lambda que crea realiza el procesamiento del contenido de la plantilla. Su función puede procesar cualquier parte de una plantilla, incluida la plantilla entera. Para obtener más información acerca del mapeo de eventos que la función debe cumplir, consulte Interfaz de la función de macro de CloudFormation. Para obtener más información sobre consideraciones adicionales al crear macros, consulte Consideraciones sobre la creación de definiciones de macros de CloudFormation.

  2. Cree una plantilla que contenga un tipo de recursos AWS::CloudFormation::Macro.

    • Tiene que especificar las propiedades Name y FunctionName. La propiedad FunctionName especifica el ARN de la función de Lambda para invocar cuándo CloudFormation ejecuta la macro.

    • Para ayudar en la depuración, también puede especificar las propiedades LogGroupName y LogRoleArn.

  3. Cree una pila a partir de la plantilla que contiene la macro en la cuenta deseada, o cree un conjunto de pilas con permisos autoadministrados a partir la plantilla que hace referencia a la macro en la cuenta de administrador y, a continuación, cree instancias de pilas en las cuentas de destino deseadas.

    Una vez que CloudFormation haya creado correctamente las pilas que contienen la definición de la macro, esta estará disponible para su uso en dichas cuentas.

Uso de macros de CloudFormation en sus plantillas

Una vez que CloudFormation haya creado correctamente las pilas que contienen la definición de la macro, esta estará disponible para su uso en dichas cuentas. Una macro se utiliza haciendo referencia a ella en una plantilla, en la ubicación adecuada relevante para el contenido de la plantilla que desea procesar.

Orden de evaluación de macros de CloudFormation

Puede consultar varias macros de una determinada plantilla, incluidas transformaciones alojadas por CloudFormation, como Transformación AWS::Include y Transformación AWS::Serverless.

Las macros se evalúan en orden, en función de su ubicación en la plantilla, desde la que esté más profundamente anidada hasta la más general. Las macros que están en la misma ubicación de la plantilla se evalúan en serie en función del orden en que aparecen en la lista.

Las transformaciones como, por ejemplo, AWS::Include y AWS::Transform, se tratan de la misma manera que cualquier otra macro en términos de orden y ámbito de acción.

Por ejemplo, en la siguiente plantilla de ejemplo, CloudFormation evalúa primero la macro PolicyAdder, ya que es la macro que está anidada más profundamente en la plantilla. A continuación, CloudFormation evalúa MyMacro antes de evaluar AWS::Serverless, ya que aparece antes de AWS::Serverless en la sección Transform.

AWSTemplateFormatVersion: 2010-09-09 Transform: [MyMacro, AWS::Serverless] Resources: WaitCondition: Type: AWS::CloudFormation::WaitCondition MyBucket: Type: 'AWS::S3::Bucket' Properties: BucketName: amzn-s3-demo-bucket Tags: [{"key":"value"}] 'Fn::Transform': - Name: PolicyAdder CorsConfiguration: [] MyEc2Instance: Type: 'AWS::EC2::Instance' Properties: ImageID: ami-1234567890abcdef0

Ámbito de las macros de CloudFormation

Las macros a las que se hace referencia en la sección Transform de una plantilla pueden procesar todo el contenido de dicha plantilla.

Las macros a las que se hace referencia en una función Fn::Transform pueden procesar el contenido de cualquiera de los elementos del mismo nivel (incluidos los elementos secundarios) de dicha función Fn::Transform en la plantilla.

Por ejemplo, en la siguiente plantilla de ejemplo, AWS::Include puede procesar todas las propiedades MyBucket, en función de la ubicación de la función Fn::Transform que lo contiene. MyMacro puede procesar el contenido de toda la plantilla debido a su inclusión en la sección Transform.

# Start of processable content for MyMacro AWSTemplateFormatVersion: 2010-09-09 Transform: [MyMacro] Resources: WaitCondition: Type: AWS::CloudFormation::WaitCondition MyBucket: Type: 'AWS::S3::Bucket' # Start of processable content for AWS::Include Properties: BucketName: amzn-s3-demo-bucket1 Tags: [{"key":"value"}] 'Fn::Transform': - Name: 'AWS::Include' Parameters: Location: s3://amzn-s3-demo-bucket2/MyFileName.yaml CorsConfiguration: [] # End of processable content for AWS::Include MyEc2Instance: Type: 'AWS::EC2::Instance' Properties: ImageID: ami-1234567890abcdef0 # End of processable content for MyMacro

Conjuntos de cambios y macros de CloudFormation

Para crear o actualizar una pila utilizando una plantilla que hace referencia a macros, normalmente debe crear un conjunto de cambios y ejecutarlo. Un conjunto de cambios describe las acciones que CloudFormation realizará en función de la plantilla procesada. El procesamiento de macros puede añadir numerosos recursos que usted podría desconocer. Para asegurarse de estar al tanto de todos los cambios hechos por las macros, sugerimos usar conjuntos de cambios. Después de revisar el conjunto de cambios, puede ejecutarlo para aplicar realmente los cambios.

Una macro puede añadir recursos de IAM a su plantilla. Para estos recursos, CloudFormation necesita que reconozca sus capacidades. Dado que CloudFormation no puede saber qué recursos se agregan antes de procesar su plantilla, es posible que tenga que reconocer las capacidades de IAM al crear el conjunto de cambios, en función de si las macros a las que se hace referencia contienen recursos de IAM. De este modo, al ejecutar el conjunto de cambios, CloudFormation tiene las capacidades necesarias para crear recursos de IAM.

importante

Si la plantilla del conjunto de pilas hace referencia a una o más macros, debe crear el conjunto de pilas directamente desde la plantilla procesada, sin revisar primero los cambios resultantes en un conjunto de cambios. Para crear o actualizar el conjunto de pilas directamente, debe utilizar las acciones CreateStackSet o UpdateStackSet y especificar la capacidad CAPABILITY_AUTO_EXPAND. Antes de crear o actualizar un conjunto de pilas a partir de una plantilla que haga referencia directamente a macros, asegúrese de saber qué procesamiento realiza cada macro.

nota

Si se siente cómodo creando o actualizando una pila directamente desde una plantilla procesada, sin antes haber revisado los cambios propuestos en un conjunto de cambios, puede hacerlo especificando la capacidad CAPABILITY_AUTO_EXPAND durante una solicitud UpdateStack o CreateStack. Solo debe crear pilas directamente desde una plantilla de pila que contiene macros si sabe qué procesamiento realiza la macro. No puede utilizar conjuntos de cambios con macros de conjuntos de pilas y debe actualizar el conjunto de pilas directamente.

Para obtener más información, consulte CreateStack o UpdateStack en la Referencia de la API de AWS CloudFormation.

Si utiliza la AWS CLI, puede utilizar los comandos package y deploy para reducir el número de pasos para lanzar pilas desde plantillas que hacen referencia a macros. Para obtener más información, consulte Implementación de aplicaciones basadas en Lambda en la Guía para desarrolladores de AWS Lambda.

Fase de plantilla y macros de CloudFormation

La fase de una plantilla indica si se trata de la plantilla enviada por el usuario original o una plantilla en la que CloudFormation ha procesado las macros.

  • Original: la plantilla que el usuario envió originalmente para crear o actualizar la pila o el conjunto de pilas.

  • Processed: la plantilla que CloudFormation utilizó para crear o actualizar la pila o el conjunto de pilas después de procesar todas las macros de referencia. La plantilla procesada se formatea como JSON, incluso si la plantilla original tenía el formato YAML.

Utilice la plantilla procesada para la resolución de problemas de la pila. Si una plantilla no hace referencia a macros, las plantillas original y procesada son idénticas.

Puede utilizar la consola de CloudFormation o AWS CLI para ver la fase de la plantilla de una pila.

nota

El tamaño máximo de una plantilla de pila procesada es de 51 200 bytes cuando se pasa directamente a una solicitud CreateStack, UpdateStack o ValidateTemplate, o 1 MB cuando se pasa como un objeto S3 utilizando una URL de plantilla de Amazon S3. Sin embargo, durante el procesamiento, CloudFormation actualiza el estado temporal de la plantilla, ya que procesa en serie las macros contenidas en la plantilla. Por este motivo, el tamaño de la plantilla durante el procesamiento puede superar temporalmente el tamaño máximo permitido de una plantilla totalmente procesada. CloudFormation permite cierta cantidad de búfer para estas plantillas en proceso. Sin embargo, debería diseñar las plantillas y macros teniendo en cuenta el tamaño máximo permitido para una plantilla de pila procesada.

Si CloudFormation devuelve un error Transformation data limit exceeded al procesar su plantilla, significa que la plantilla ha superado el tamaño máximo de plantilla que CloudFormation permite durante el procesamiento.

Para resolver este problema, realice lo siguiente:

  • Reestructure la plantilla en varias plantillas para evitar superar el tamaño máximo de las plantillas en proceso. Por ejemplo:

  • Reduzca el tamaño de fragmento de plantilla devuelto por una determinado macro. CloudFormation no modifica el contenido de los fragmentos devuelto por macros.

Para utilizar una macro de CloudFormation en la plantilla
nota

Para que CloudFormation ejecute correctamente una macro a la que se hace referencia en una plantilla, el usuario debe tener permisos Invoke para la función de Lambda subyacente. Para obtener más información, consulte Información general de la administración de permisos de acceso a sus recursos de AWS Lambda) en la Guía para desarrolladores de AWS Lambda.

  1. Incluya una referencia a la macro en la plantilla.

  2. Cree un conjunto de cambios con la plantilla.

    importante

    Si la plantilla del conjunto de pilas hace referencia a una o más macros, debe crear el conjunto de pilas directamente desde la plantilla procesada, sin revisar primero los cambios resultantes en un conjunto de cambios. Para crear o actualizar el conjunto de pilas directamente, debe utilizar las acciones CreateStackSet o UpdateStackSet y especificar la capacidad CAPABILITY_AUTO_EXPAND. Antes de crear o actualizar un conjunto de pilas a partir de una plantilla que haga referencia directamente a macros, asegúrese de saber qué procesamiento realiza cada macro.

  3. Revise y ejecute el conjunto de cambios.

    importante

    Si la plantilla del conjunto de pilas hace referencia a una o más macros, debe crear el conjunto de pilas directamente desde la plantilla procesada, sin revisar primero los cambios resultantes en un conjunto de cambios. Para crear o actualizar el conjunto de pilas directamente, debe utilizar las acciones CreateStackSet o UpdateStackSet y especificar la capacidad CAPABILITY_AUTO_EXPAND. Antes de crear o actualizar un conjunto de pilas a partir de una plantilla que haga referencia directamente a macros, asegúrese de saber qué procesamiento realiza cada macro.

Ejemplos de macros

Además del tutorial Ejemplo de macro: creación y uso de una macro de esta guía, encontrará ejemplos de macros, incluido el código fuente y las plantillas, en nuestro repositorio de GitHub. Estos ejemplos se proporcionan “tal cual” para fines pedagógicos.

Véase también

AWS::CloudFormation::Macro

Sección de Transform para las plantillas de CloudFormation

Fn::Transform

Transformación AWS::Serverless

Transformación AWS::Include