Demonstração: Pesquisar IDs de imagem de máquina da Amazon - AWS CloudFormation

Demonstração: Pesquisar IDs de imagem de máquina da Amazon

Os modelos do AWS CloudFormation que declaram uma instância do Amazon Elastic Compute Cloud (Amazon EC2) também devem especificar um ID da Imagem de máquina da Amazon (AMI), que inclui um sistema operacional e outras informações de configuração e software usadas para iniciar a instância. O ID da AMI correto depende do tipo de instância e da região em que a pilha é iniciada. E os IDs podem ser alterados regularmente, como quando ocorrem atualizações de software de uma AMI.

Normalmente, você pode mapear IDs de AMI para os tipos de instância e regiões específicos. Para atualizar os IDs, altere-os manualmente em cada um dos modelos. Ao usar recursos personalizados e AWS Lambda (Lambda), você pode criar uma função que obtém os IDs de AMIs mais recentes para a região e o tipo de instância que estão em uso, de modo que não precise manter mapeamentos.

Esta descrição mostra como criar um recurso personalizado e associar uma função Lambda a ele para pesquisar IDs de AMI. Observe que a descrição pressupõe que você compreende o uso de recursos personalizados e Lambda. Para obter mais informações, consulte Recursos personalizados ou AWS Lambda Developer Guide.

Visão geral da descrição

Para esta descrição, crie uma pilha com um recurso personalizado, uma função Lambda e uma instância EC2. A descrição fornece um código de exemplo e um modelo de amostra que será usado para criar a pilha.

O modelo de amostra usa o tipo de recursos personalizado para invocar e enviar valores de entrada para a função Lambda. Quando você usa o modelo, o AWS CloudFormation invoca a função e envia informações a ela, como o tipo de solicitação, dados de entrada e um pre-signed URL do Amazon Simple Storage Service (Amazon S3). A função usa essas informações para pesquisar o ID da AMI e, em seguida, envia uma resposta para o pre-signed URL.

Após o AWS CloudFormation obter uma resposta no pre-signed URL local, ele prossegue com a criação da pilha. Quando o AWS CloudFormation cria a instância, ele usa a resposta da função Lambda para especificar o ID da AMI da instância.

A lista a seguir resume o processo. São necessárias permissões do AWS Identity and Access Management (IAM) para usar todos os serviços correspondentes, como Lambda, o Amazon EC2 e o AWS CloudFormation.

nota

O AWS CloudFormation é um serviço gratuito; no entanto, existe uma cobrança para os recursos da AWS, como a função Lambda e a instância do EC2, que são incluídos nas pilhas na taxa atual de cada um deles. Para obter mais informações sobre a definição de preço da AWS, consulte a página de detalhes de cada produto em http://aws.amazon.com.

  1. Salve o pacote de amostra do Lambda em um bucket do Amazon Simple Storage Service (Amazon S3).

    O pacote de amostra contém tudo o que é necessário para criar a função Lambda. Salve o pacote em um bucket que está na mesma região em que a pilha for criada.

  2. Use o modelo de amostra para criar uma pilha.

    A pilha demonstra como associar a função Lambda a um recurso personalizado e como usar os resultados da função para especificar um ID da AMI. A pilha também cria uma função IAM (função de execução), que o Lambda usa para fazer chamadas para o Amazon EC2.

  3. Exclua a pilha.

    Exclua a pilha para limpar todos os recursos de pilha criados; assim, você não será cobrado por recursos desnecessários.

Etapa 1: Fazer download e salvar o pacote de exemplo no Amazon S3

Quando você criar uma pilha com uma função Lambda, especifique o local do bucket do Amazon S3 que contém o código-fonte da função. O bucket deve estar na mesma região em que a pilha foi criada.

Esta descrição oferece um pacote de amostra (um arquivo .zip) necessário para criar a função Lambda. Um pacote do Lambda contém o código-fonte para a função e as bibliotecas necessárias. Para esta descrição, a função não exige bibliotecas adicionais.

A função usa uma arquitetura de instância e a região como entradas de uma solicitação de recurso personalizado do AWS CloudFormation e retorna o ID da AMI mais recente para um pre-signed URL do Amazon S3.

Para fazer download e salvar o pacote no Amazon S3

  1. Faça download do pacote de amostra do Amazon S3. Quando você salvar o arquivo, use o mesmo nome de arquivo que a amostra, amilookup.zip ou amilookup-win.zip.

  2. Abra o console do Amazon S3 em https://console.aws.amazon.com/s3/home.

  3. Escolha ou crie um bucket que esteja localizado na mesma região em que a pilha do AWS CloudFormation será criada. Registre o nome do bucket.

    Salve o pacote de amostra neste bucket. Para obter mais informações sobre como criar um bucket, consulte Criar um bucket, no Guia do usuário do console do Amazon Simple Storage Service.

  4. Faça upload do pacote de amostra no bucket que você escolheu ou criou.

    Para obter mais informações sobre o upload de objetos, consulte Upload de objetos, no Guia do usuário do console do Amazon Simple Storage Service.

Com o pacote no Amazon S3, agora você pode especificar seu local na declaração do recurso Lambda do modelo do AWS CloudFormation. A próxima etapa demonstra como declarar a função e invocá-la usando um recurso personalizado. Veja também como usar os resultados da função para especificar o ID da AMI de uma instância EC2.

Etapa 2: Criar a pilha

Para criar a pilha do Amazon EC2 de amostra, use um modelo de amostra que inclui uma função Lambda, uma função de execução IAM, um recurso personalizado que invoca a função e uma instância do EC2 que usa os resultados da função.

Durante a criação da pilha, o recurso personalizado invoca a função Lambda e espera ela enviar uma resposta para o pre-signed URL do Amazon S3. Em resposta, a função retorna o ID da AMI mais recente que corresponde ao tipo de instância EC2 e a região em que a instância está sendo criada. Os dados de resposta da função são armazenados como um atributo do recurso personalizado, que é usado para especificar o ID da AMI da instância EC2.

Os seguintes trechos explicam relevantes partes do modelo de amostra para ajudá-lo a entender como associar uma função Lambda a um recurso personalizado e como usar a resposta da função.

Para visualizar todo o modelo de amostra, consulte:

Trechos do modelo da pilha

Para criar a função Lambda, declare o recurso AWS::Lambda::Function, que requer o código-fonte da função, o nome do manipulador, o ambiente do runtime e a função de execução do Nome de região da Amazon (ARN).

exemplo Sintaxe do JSON

"AMIInfoFunction": { "Type": "AWS::Lambda::Function", "Properties": { "Code": { "S3Bucket": { "Ref": "S3Bucket" }, "S3Key": { "Ref": "S3Key" } }, "Handler": { "Fn::Join" : [ "", [{ "Ref": "ModuleName" },".handler"] ] }, "Runtime": "nodejs8.10", "Timeout": "30", "Role": { "Fn::GetAtt" : ["LambdaExecutionRole", "Arn"] } } }

exemplo Sintaxe do YAML

AMIInfoFunction: Type: AWS::Lambda::Function Properties: Code: S3Bucket: !Ref S3Bucket S3Key: !Ref S3Key Handler: !Sub "${ModuleName}.handler" Runtime: nodejs8.10 Timeout: 30 Role: !GetAtt LambdaExecutionRole.Arn

A propriedade Code especifica o local do Amazon S3 (nome do bucket e nome de arquivo) onde você fez upload do pacote de amostra. O modelo de amostra usa parâmetros de entrada ("Ref": "S3Bucket" e "Ref": "S3Key") para definir o bucket e nomes de arquivos para que você possa especificar os nomes quando criar a pilha. Da mesma forma, o nome do manipulador, que corresponde ao nome do arquivo de origem (o arquivo JavaScript) no pacote .zip, também usa um parâmetro de entrada ("Ref": "ModuleName"). Como o arquivo de origem é código JavaScript, o runtime é especificado como nodejs8.10.

Para esta descrição, o tempo de execução para a função excede o valor padrão de 3 segundos, de modo que o timeout é definido em 30 segundos. Se você não especificar um timeout suficientemente longo, o Lambda poderá atingi-lo antes de a função ser concluída e fazer com que a criação da pilha falhe.

A função de execução, que é declarada em outro lugar no modelo, é especificada com o uso da função intrínseca Fn::GetAtt na propriedade Role. A função de execução concede permissão à função Lambda para enviar logs à AWS e chamar a API DescribeImages do EC2. O seguinte trecho mostra a função e a política que concede a permissão apropriada:

exemplo Sintaxe do 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": "*" }] } }] } }

exemplo Sintaxe do 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 os modelos Linux e Windows, o recurso personalizado invoca a função Lambda associada a ele. Para associar uma função a um recurso personalizado, especifique o Nome de recurso da Amazon (ARN) da função para a propriedade ServiceToken, usando a função intrínseca Fn::GetAtt. O AWS CloudFormation envia as propriedades adicionais que estão incluídas na declaração de recurso personalizada, como Region e Architecture, para a função Lambda como entradas. A função Lambda determina os nomes e valores corretos para essas propriedades de entrada.

exemplo Sintaxe do JSON

"AMIInfo": { "Type": "Custom::AMIInfo", "Properties": { "ServiceToken": { "Fn::GetAtt" : ["AMIInfoFunction", "Arn"] }, "Region": { "Ref": "AWS::Region" }, "Architecture": { "Fn::FindInMap" : [ "AWSInstanceType2Arch", { "Ref" : "InstanceType" }, "Arch" ] } } }

exemplo Sintaxe do YAML

AMIInfo: Type: Custom::AMIInfo Properties: ServiceToken: !GetAtt AMIInfoFunction.Arn Region: !Ref "AWS::Region" Architecture: Fn::FindInMap: - AWSInstanceType2Arch - !Ref InstanceType - Arch

Para o Windows, o recurso personalizado fornece a versão do Windows à função Lambda, em vez da arquitetura da instância.

exemplo Sintaxe do JSON

"AMIInfo": { "Type": "Custom::AMIInfo", "Properties": { "ServiceToken": { "Fn::GetAtt" : ["AMIInfoFunction", "Arn"] }, "Region": { "Ref": "AWS::Region" }, "OSName": { "Ref": "WindowsVersion" } } }

exemplo Sintaxe do YAML

AMIInfo: Type: Custom::AMIInfo Properties: ServiceToken: !GetAtt AMIInfoFunction.Arn Region: !Ref "AWS::Region" OSName: !Ref "WindowsVersion"

Quando o AWS CloudFormation invoca a função Lambda, a função invoca a API DescribeImages do EC2, usando a região e arquitetura de instância ou o nome de sistema para filtrar a lista de imagens. Em seguida, a função classifica a lista de imagens por data e retorna o ID da AMI mais recente.

Ao retornar o ID da AMI mais recente, a função envia o ID para um pre-signed URL na propriedade Data do objeto de resposta. Os dados são estruturados como um par nome-valor, como mostrado no exemplo a seguir:

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

O seguinte trecho mostra como obter os dados de uma função Lambda. Ele usa a função intrínseca Fn::GetAtt, fornecendo o nome do recurso personalizado e o nome de atributo do valor a ser obtido. Nessas descrição, o nome do recurso personalizado é AMIInfo e o nome do atributo é Id.

exemplo Sintaxe do JSON

"SampleInstance": { "Type": "AWS::EC2::Instance", "Properties": { "InstanceType" : { "Ref" : "InstanceType" }, "ImageId": { "Fn::GetAtt": [ "AMIInfo", "Id" ] } } }

exemplo Sintaxe do YAML

SampleInstance: Type: AWS::EC2::Instance Properties: InstanceType: !Ref InstanceType ImageId: !GetAtt AMIInfo.Id

Agora que você compreende o que o modelo faz, use o modelo de amostra para criar uma pilha.

Para criar a stack

  1. Abra o console do AWS CloudFormation em https://console.aws.amazon.com/cloudformation/.

  2. Selecione Criar Stack.

  3. Na seção Template (Modelo), selecione Specify an Amazon S3 template URL (Especificar um URL de modelo do &S3;) e, em seguida, copie e cole o seguinte URL na caixa de texto:

  4. Selecione Next (Próximo).

  5. No campo Stack name (Nome da pilha), digite SampleEC2Instance.

  6. Na seção Parameters (Parâmetros), especifique o nome do bucket do Amazon S3 que você criou e, em seguida, escolha Next (Próximo).

    Os valores padrão dos outros parâmetros são os mesmos nomes usados no pacote .zip de amostra.

  7. Para esta demonstração, você não precisa adicionar tags ou especificar configurações avançadas, portanto escolha Próximo.

  8. Certifique-se de que o nome da pilha e o modelo de URL estão corretos e, em seguida, escolha Criar.

Pode levar vários minutos para o AWS CloudFormation criar sua pilha. Para monitorar o progresso, exiba os eventos da pilha. Para obter mais informações, consulte Visualizar dados e recursos da pilha do AWS CloudFormation no AWS Management Console.

Se a criação da pilha for bem-sucedida, todos os recursos na pilha, como a função Lambda, o recurso personalizado e a instância EC2, terão sido criados. Você usou com êxito uma função Lambda e um recurso personalizado para especificar o ID da AMI e uma instância EC2. Não é preciso criar e manter um mapeamento de IDs de AMI neste modelo.

Para ver qual ID da AMI o AWS CloudFormation usou para criar a instância EC2, visualize as saídas da pilha.

Se a função Lambda retornar um erro, visualize os logs da função no console do Amazon CloudWatch Logs. O nome do stream de logs é o ID físico do recurso personalizado, que pode ser encontrado visualizando os recursos da pilha. Para obter mais informações, consulte Visualizar dados de log, no Guia do usuário do Amazon CloudWatch.

Etapa 3: Limpar os recursos

Para ter certeza de que você não será cobrado por serviços indesejados, exclua a pilha.

Para excluir a pilha

  1. No console do AWS CloudFormation, escolha a pilha SampleEC2Instance.

  2. Escolha Ações e, em seguida, Excluir pilha.

  3. Na mensagem de confirmação, escolha Sim, excluir.

Todos os recursos que você criou serão excluídos.

Agora que você compreende como criar e usar as funções Lambda com o AWS CloudFormation, use o modelo de amostra e o código desta descrição para criar outras pilhas e funções.

Informações relacionadas