Tutorial: Búsqueda de ID de imagen de Amazon Machine - AWS CloudFormation

Tutorial: Búsqueda de ID de imagen de Amazon Machine

Las plantillas de AWS CloudFormation que declaren una instancia de Amazon Elastic Compute Cloud (Amazon EC2) también deben especificar un ID de imagen de máquina de Amazon (AMI) que incluya un sistema operativo y otra información de software y configuración que se use para lanzar la instancia. El ID de AMI correcto depende del tipo de instancia y la región en la que desea lanzar la pila. Y los ID pueden cambiar con regularidad, como cuando una AMI se actualiza con actualizaciones de software.

Normalmente, puede asignar los ID de AMI a determinados tipos de instancias y regiones. Para actualizar los ID, cámbielos manualmente en cada una de las plantillas. Mediante el uso de los recursos personalizados y AWS Lambda (Lambda), puede crear una función que obtiene el ID de las últimas AMI para la región y el tipo de instancia que está utilizando, para no tener que mantener asignaciones.

Este tutorial muestra cómo crear un recurso personalizado y asociarle una función de Lambda para buscar los ID de AMI. Tenga en cuenta que el tutorial presupone que entiende cómo utilizar Lambda y recursos personalizados. Para obtener más información, consulte Recursos personalizados o la Guía para desarrolladores de AWS Lambda.

Información general del tutorial

En este tutorial, creará una pila con un recurso personalizado, una función de Lambda y una instancia de EC2. El tutorial proporciona un código de ejemplo y una plantilla de ejemplo que utilizará para crear la pila.

La plantilla de ejemplo utiliza el tipo de recurso personalizado para invocar y enviar los valores de entrada a la función de Lambda. Al utilizar la plantilla, AWS CloudFormation invoca la función y le envía información como el tipo de solicitud, los datos de entrada y una URL de Amazon Simple Storage Service (Amazon S3) prefirmada. La función utiliza dicha información para consultar el ID de AMI y, a continuación, envía una respuesta a la URL prefirmada.

Una vez que AWS CloudFormation obtiene una respuesta en la ubicación de URL prefirmada, procede a crear la pila. Cuando AWS CloudFormation crea la instancia, utiliza la respuesta de la función de Lambda para especificar el ID de AMI de dicha instancia.

En la siguiente lista se resume el proceso. Se necesitan permisos de AWS Identity and Access Management (IAM) para utilizar todos los servicios correspondientes, como Lambda, Amazon EC2 y AWS CloudFormation.

nota

AWS CloudFormation es un servicio gratuito; sin embargo, se le cobrará por los recursos de AWS, como la función de Lambda y la instancia de EC2, que incluya en las pilas según la tarifa actual de cada una. Para obtener más información sobre los precios de AWS, consulte la página de detalles correspondiente a cada producto en http://aws.amazon.com.

  1. Guarde el paquete Lambda de ejemplo en un bucket de Amazon Simple Storage Service (Amazon S3).

    El paquete de ejemplo contiene todo lo necesario para crear la función de Lambda. Debe guardar el paquete en un bucket que está en la misma región en la que creará la pila.

  2. Use la plantilla de ejemplo para crear una pila.

    La pila demuestra cómo asociar la función de Lambda con un recurso personalizado y cómo utilizar los resultados de la función para especificar un ID de AMI. La pila también crea un rol de IAM (rol de ejecución), que Lambda utiliza para realizar llamadas a Amazon EC2.

  3. Elimina la pila.

    Elimine la pila para limpiar todos los recursos de la pila que creó para que no se le cobren los recursos innecesarios.

Paso 1: Descargar y guardar el paquete de ejemplo en Amazon S3

Al crear una pila con una función de Lambda, debe especificar la ubicación del bucket de Amazon S3 que contiene el código fuente de la función. El bucket debe estar en la misma región en la que crea su pila.

Este tutorial proporciona un paquete de ejemplo (un archivo .zip) que es necesario para crear la función de Lambda. Un paquete Lambda contiene el código fuente de la función y las bibliotecas necesarias. En este tutorial, la función no requiere bibliotecas adicionales.

La función toma la región y la arquitectura de una instancia como entradas de una solicitud de recurso personalizado de AWS CloudFormation y devuelve los últimos ID de AMI a una URL de Amazon S3 prefirmada.

Para descargar y guardar el paquete en Amazon S3
  1. Descargue el paquete de ejemplo de Amazon S3. Cuando guarde el archivo, utilice el mismo nombre de archivo que la muestra amilookup.zip o amilookup-win.zip.

  2. Abra la consola de Amazon S3 en https://console.aws.amazon.com/s3/home.

  3. Elija o cree un bucket que se encuentre en la misma región en la que creará su pila de AWS CloudFormation. Registre el nombre del bucket.

    Guardará el paquete de ejemplo en este bucket. Para obtener más información acerca de la creación de un bucket, consulte Crear un bucket en la Guía del usuario de Amazon Simple Storage Service.

  4. Cargue el paquete de ejemplo al bucket que haya elegido o creado.

    Para obtener más información acerca de cómo cargar objetos, consulte Carga de objetos en la Guía del usuario de Amazon Simple Storage Service.

Con el paquete en Amazon S3, ahora puede especificar su ubicación en la declaración del recurso de Lambda de la plantilla de AWS CloudFormation. El siguiente paso demuestra cómo declarar la función e invocarla mediante un recurso personalizado. También observará cómo utilizar los resultados de la función para especificar el ID de AMI de una instancia de EC2.

Paso 2: Creación de la pila

Para crear la pila de Amazon EC2 de ejemplo, utilizará una plantilla de ejemplo que incluya una función de Lambda, un rol de ejecución de IAM, un recurso personalizado que invoca la función y una instancia de EC2 que utilice los resultados de la función.

Durante la creación de la pila, el recurso personalizado invoca la función de Lambda y espera hasta que la función envía una respuesta a la URL de Amazon S3 prefirmada. En la respuesta, la función devuelve el ID de la última AMI que se corresponda con el tipo de instancia de EC2 y la región en la que está creando la instancia. Los datos de la respuesta de la función se almacenan como un atributo del recurso personalizado, que se utiliza para especificar el ID de AMI de la instancia de EC2.

Los siguientes fragmentos explican las partes importantes de la plantilla de ejemplo para ayudarle a entender cómo asociar una función de Lambda a un recurso personalizado y cómo utilizar la respuesta de la función.

Para ver toda la plantilla de ejemplo, consulte:

Fragmentos de plantilla de pila

Para crear la función de Lambda, declare el recurso AWS::Lambda::Function, que requiere el código fuente de la función, el nombre del gestor, el entorno del tiempo de ejecución y el ARN del rol de ejecución.

ejemplo Sintaxis JSON
"AMIInfoFunction": { "Type": "AWS::Lambda::Function", "Properties": { "Code": { "S3Bucket": { "Ref": "S3Bucket" }, "S3Key": { "Ref": "S3Key" } }, "Handler": { "Fn::Join" : [ "", [{ "Ref": "ModuleName" },".handler"] ] }, "Runtime": "nodejs18.x", "Timeout": "30", "Role": { "Fn::GetAtt" : ["LambdaExecutionRole", "Arn"] } } }
ejemplo Sintaxis del YAML
AMIInfoFunction: Type: AWS::Lambda::Function Properties: Code: S3Bucket: !Ref S3Bucket S3Key: !Ref S3Key Handler: !Sub "${ModuleName}.handler" Runtime: nodejs18.x Timeout: 30 Role: !GetAtt LambdaExecutionRole.Arn

La propiedad Code especifica la ubicación de Amazon S3 (nombre de bucket y de archivo) donde ha cargado el paquete de ejemplo. La plantilla de ejemplo utiliza parámetros de entrada ("Ref": "S3Bucket" y "Ref": "S3Key") para establecer los nombres de bucket y archivo para poder especificar los nombres al crear la pila. Del mismo modo, el nombre del gestor, que se corresponde con el nombre del archivo de origen (el archivo JavaScript) en el paquete .zip, también utiliza un parámetro de entrada ("Ref": "ModuleName"). Dado que el archivo de origen es un código JavaScript, se especifica el tiempo de ejecución como nodejs18.x.

En este tutorial, el tiempo de ejecución de la función supera el valor predeterminado de 3 segundos, por lo que el tiempo de espera se establece en 30 segundos. Si no especifica un tiempo de espera lo bastante largo, Lambda podría agotar dicho tiempo antes de que se complete la función, fracasando la creación de la pila.

El rol de ejecución, que se declara en otra parte de la plantilla, se especifica usando la Fn::GetAtt función intrínseca de la propiedad Role. El rol de ejecución concede permiso a la función de Lambda para enviar registros a AWS y para llamar a la API DescribeImages de EC2. El siguiente fragmento muestra el rol y la política que conceden el permiso correspondiente:

ejemplo Sintaxis JSON
"LambdaExecutionRole": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": {"Service": ["lambda.amazonaws.com"]}, "Action": ["sts:AssumeRole"] }] }, "Path": "/", "Policies": [{ "PolicyName": "root", "PolicyDocument": { "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action": ["logs:CreateLogGroup","logs:CreateLogStream","logs:PutLogEvents"], "Resource": "arn:aws:logs:*:*:*" }, { "Effect": "Allow", "Action": ["ec2:DescribeImages"], "Resource": "*" }] } }] } }
ejemplo Sintaxis del YAML
LambdaExecutionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - lambda.amazonaws.com Action: - sts:AssumeRole Path: "/" Policies: - PolicyName: root PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Resource: arn:aws:logs:*:*:* - Effect: Allow Action: - ec2:DescribeImages Resource: "*"

Para las plantillas de Linux y Windows, el recurso personalizado invoca la función de Lambda que tiene asociada. Para asociar una función con un recurso personalizado, debe especificar el nombre de recurso de Amazon (ARN) de la función de la propiedad ServiceToken, mediante la función intrínseca Fn::GetAtt. AWS CloudFormation envía las propiedades adicionales que se incluyen en la declaración de los recursos personalizados, como Region y Architecture, a la función de Lambda como entradas. La función de Lambda determina los nombres y los valores correctos de estas propiedades de entrada.

ejemplo Sintaxis JSON
"AMIInfo": { "Type": "Custom::AMIInfo", "Properties": { "ServiceToken": { "Fn::GetAtt" : ["AMIInfoFunction", "Arn"] }, "Region": { "Ref": "AWS::Region" }, "Architecture": { "Fn::FindInMap" : [ "AWSInstanceType2Arch", { "Ref" : "InstanceType" }, "Arch" ] } } }
ejemplo Sintaxis del YAML
AMIInfo: Type: Custom::AMIInfo Properties: ServiceToken: !GetAtt AMIInfoFunction.Arn Region: !Ref "AWS::Region" Architecture: Fn::FindInMap: - AWSInstanceType2Arch - !Ref InstanceType - Arch

En el caso de Windows, el recurso personalizado proporciona la versión de Windows a la función de Lambda en lugar de la arquitectura de la instancia.

ejemplo Sintaxis JSON
"AMIInfo": { "Type": "Custom::AMIInfo", "Properties": { "ServiceToken": { "Fn::GetAtt" : ["AMIInfoFunction", "Arn"] }, "Region": { "Ref": "AWS::Region" }, "OSName": { "Ref": "WindowsVersion" } } }
ejemplo Sintaxis del YAML
AMIInfo: Type: Custom::AMIInfo Properties: ServiceToken: !GetAtt AMIInfoFunction.Arn Region: !Ref "AWS::Region" OSName: !Ref "WindowsVersion"

Cuando AWS CloudFormation invoca la función de Lambda, la función llama a la API DescribeImages de EC2, que usa la región y la arquitectura de instancias o el nombre del sistema operativo para filtrar la lista de imágenes. A continuación, la función ordena la lista de imágenes por fecha y devuelve el ID de la AMI más reciente.

Cuando devuelve el ID de la última AMI, la función envía el ID a una URL prefirmada en la propiedad Data del objeto de respuesta. Los datos se estructuran como un par de nombre-valor, como se muestra en el ejemplo siguiente:

"Data": { "Id": "ami-43795473" }

El siguiente fragmento muestra cómo obtener los datos de una función de Lambda. Utiliza la función intrínseca Fn::GetAtt, proporcionando el nombre del recurso personalizado y el nombre de atributo del valor que desee obtener. En este tutorial, el nombre del recurso personalizado es AMIInfo y el nombre del atributo es Id.

ejemplo Sintaxis JSON
"SampleInstance": { "Type": "AWS::EC2::Instance", "Properties": { "InstanceType" : { "Ref" : "InstanceType" }, "ImageId": { "Fn::GetAtt": [ "AMIInfo", "Id" ] } } }
ejemplo Sintaxis del YAML
SampleInstance: Type: AWS::EC2::Instance Properties: InstanceType: !Ref InstanceType ImageId: !GetAtt AMIInfo.Id

Ahora que entiende lo que hace la plantilla, utilice la plantilla de ejemplo para crear una pila.

Para crear la pila
  1. Abra la consola de AWS CloudFormation en https://console.aws.amazon.com/cloudformation/.

  2. Elija Crear pila.

  3. En la sección Template (Plantilla), elija Specify an Amazon S3 template URL (Especificar una URL de plantilla de Amazon S3) y, a continuación, copie y pegue la siguiente URL en el cuadro de texto:

  4. Seleccione Siguiente.

  5. En el campo Stack name (Nombre de pila), escriba SampleEC2Instance.

  6. En la sección Parameters (Parámetros), especifique el nombre del bucket de Amazon S3; que ha creado y, a continuación, elija Next (Siguiente).

    Los valores predeterminados para el resto de los parámetros son los mismos nombres que se utilizan en el paquete .zip de ejemplo.

  7. Para este tutorial, no tiene que añadir etiquetas ni especificar una configuración avanzada, así que elija Next (Siguiente).

  8. Asegúrese de que el nombre de la pila y la URL de la plantilla sean correctos y elija Create (Crear).

Podría llevarle varios minutos a AWS CloudFormation crear la pila. Para monitorizar el progreso, vea los eventos de la pila. Para obtener más información, consulte Visualización de recursos y datos de la pila de AWS CloudFormation en la AWS Management Console.

Si se crea la pila correctamente, se crean todos los recursos de la pila, como la función de Lambda, el recurso personalizado y la instancia de EC2. Ha utilizado de forma satisfactoria una función de Lambda y un recurso personalizado para especificar el ID de AMI de una instancia de EC2. No es necesario crear y mantener un mapeo de los ID de AMI en esta plantilla.

Para ver qué ID de AMI usó AWS CloudFormation para crear la instancia de EC2, vea las salidas de la pila.

Si la función de Lambda devuelve un error, vea los registros de la función en la consola de Amazon CloudWatch Logs. El nombre de la flujo de registros es el ID físico del recurso personalizado, que puede encontrar al visualizar los recursos de la pila. Para obtener más información, consulte la sección de visualización de datos de registro en la Guía del usuario de Amazon CloudWatch.

Paso 3: Limpiar recursos

Para asegurarse de que no se le cobra por servicios no deseados, elimine la pila.

Para eliminar la pila
  1. En la consola de AWS CloudFormation, elija la pila SampleEC2Instance.

  2. Elija Actions (Acciones) y, a continuación, Delete Stack (Eliminar pila).

  3. En el mensaje de confirmación, elija Yes, Delete (Sí, eliminar).

Se eliminan todos los recursos que creó.

Ahora que entiende cómo crear y utilizar funciones de Lambda con AWS CloudFormation, puede usar el código y la plantilla de ejemplo de este tutorial para crear otras pilas y funciones.

Información relacionada