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:
-
Transformación AWS::Include le permite insertar fragmentos de código reutilizable en las plantillas.
-
Transformación AWS::Serverless toma una plantilla completa escrita en la sintaxis de AWS Serverless Application Model (AWS SAM) y la transforma y amplía en una plantilla de CloudFormation conforme. (Para obtener más información acerca de las aplicaciones sin servidor y AWS SAM, consulte Implementación de aplicaciones basadas en Lambda en la Guía para desarrolladores de AWS Lambda.)
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.
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ónTransform
. -
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ónFn::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.
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:
-
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.
-
Cree una plantilla que contenga un tipo de recursos
AWS::CloudFormation::Macro
.-
Tiene que especificar las propiedades
Name
yFunctionName
. La propiedadFunctionName
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
yLogRoleArn
.
-
-
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:
-
Utilice plantillas de pila anidadas para encapsular las partes de la plantilla. Para obtener más información, consulte Integre pilas dentro de otras pilas mediante pilas anidadas.
-
Cree varias pilas y utilice referencias de pila cruzadas para intercambiar información entre ellas. Para obtener más información, consulte Consulta de las salidas de recursos en otra pila de CloudFormation.
-
-
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.
-
Incluya una referencia a la macro en la plantilla.
-
Para procesar un fragmento de código de una plantilla, haga referencia a la macro en una función
Fn::Transform
que se encuentre ubicada en relación con el contenido de la plantilla que desea procesar. -
Para procesar la plantilla completa, consulte la macro en la sección Sección de Transform para las plantillas de CloudFormation de la plantilla.
-
-
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. -
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
Véase también
Sección de Transform para las plantillas de CloudFormation
Transformación AWS::Serverless