

# Uso do EC2 Image Builder para criar AMIs personalizadas otimizadas para Amazon ECS
<a name="image-builder-tutorial"></a>

A AWS recomenda usar as AMIs otimizadas para Amazon ECS por serem pré-configuradas com os requisitos e recomendações para executar as workloads de contêiner. Pode haver momentos em que você precise personalizar a AMI para adicionar software. É possível usar o EC2 Image Builder para criar, gerenciar e implantar suas imagens de servidor. Você retém a propriedade das imagens personalizadas criadas na sua conta. É possível usar os pipelines do EC2 Image Builder para automatizar atualizações e patches do sistema das imagens ou utilizar um comando autônomo para criar uma imagem com seus recursos de configuração definidos.

Você cria uma fórmula para a imagem. A fórmula inclui uma imagem pai e quaisquer componentes adicionais. Você também cria um pipeline que distribui sua AMI personalizada.

Você cria uma fórmula para a imagem. Uma fórmula de imagem do Image Builder é um documento que define a imagem de base e os componentes que são aplicados à imagem de base para produzir a configuração desejada para a imagem AMI de saída. Você também cria um pipeline que distribui sua AMI personalizada. Para obter mais informações, consulte [How EC2 Image Builder works](https://docs.aws.amazon.com/imagebuilder/latest/userguide/how-image-builder-works.html) no *Guia do usuário do EC2 Image Builder*.

Recomendamos usar uma das seguintes AMIs otimizadas para o Amazon ECS como “imagem pai” no EC2 Image Builder:
+ Linux
  + AL2023 x86 otimizado para o Amazon ECS
  + AMI do Amazon Linux 2023 (arm64) otimizada para Amazon ECS
  + AMI do kernel 5 do Amazon Linux 2 otimizada para o Amazon ECS
  + AMI do Amazon Linux 2 x86 otimizada para o Amazon ECS
+ Windows
  + Windows 2022 Full x86 otimizado para o Amazon ECS
  + Windows 2022 Core x86 otimizado para o Amazon ECS
  + Windows 2019 Full x86 otimizado para o Amazon ECS
  + Windows 2019 Core x86 otimizado para o Amazon ECS
  + Windows 2016 Full x86 otimizado para o Amazon ECS

Também recomendamos selecionar “Usar a versão mais recente do sistema operacional disponível”. O pipeline usará o versionamento semântico para a imagem pai, o que ajuda a detectar as atualizações de dependência em trabalhos programados automaticamente. Para obter mais informações, consulte [Semantic versioning](https://docs.aws.amazon.com/imagebuilder/latest/userguide/ibhow-semantic-versioning.html) no *Guia do usuário do EC2 Image Builder*.

A AWS atualiza regularmente as imagens de AMI otimizadas para Amazon ECS com patches de segurança e a nova versão do agente de contêiner. Ao usar um ID de AMI como imagem pai na fórmula de imagem, você precisa verificar regularmente se há atualizações na imagem pai. Se houver atualizações, é preciso criar uma versão da fórmula com a AMI atualizada. Isso garante que suas imagens personalizadas incorporem a versão mais recente da imagem pai. Para obter informações sobre como criar um fluxo de trabalho para atualizar automaticamente as instâncias do EC2 no cluster do Amazon ECS com as AMIs recém-criadas, consulte [How to create an AMI hardening pipeline and automate updates to your ECS instance fleet](https://aws.amazon.com/blogs/security/how-to-create-an-ami-hardening-pipeline-and-automate-updates-to-your-ecs-instance-fleet/).

Você também pode especificar o nome do recurso da Amazon (ARN) de uma imagem pai publicada por meio de um pipeline gerenciado do EC2 Image Builder. A Amazon publica rotineiramente imagens de AMI otimizadas para Amazon ECS por meio de pipelines gerenciados. Essas imagens são acessíveis ao público. Você deve ter as permissões corretas para acessar a imagem. Ao usar um ARN de imagem em vez de uma AMI na fórmula do Image Builder, seu pipeline usa automaticamente a versão mais recente da imagem pai sempre que é executada. Essa abordagem elimina a necessidade de criar manualmente versões da fórmula para cada atualização. 

## Limpar a AMI otimizada para o Amazon ECS
<a name="cleanup-ecs-optimized-ami"></a>

Ao usar uma AMI otimizada para o Amazon ECS como imagem principal, você deve limpar a imagem para evitar problemas transitórios. A AMI otimizada para o Amazon ECS é pré-configurada para que o agente do Amazon ECS seja iniciado automaticamente e se registre como instância de contêiner no Amazon ECS. Usá-la como imagem base sem a limpeza correta pode causar problemas na sua AMI personalizada.

Para limpar a imagem para uso futuro, crie um componente que execute os seguintes comandos para interromper o pacote ecs-init e os processos do Docker:

```
sudo systemctl stop ecs
sudo systemctl stop docker
```

Remova todos os arquivos de log da instância atual para evitar preservá-los ao salvar a imagem. Use o script de exemplo em [Práticas recomendadas de segurança do EC2 Image Builder](https://docs.aws.amazon.com/imagebuilder/latest/userguide/security-best-practices.html) para limpar os vários arquivos da instância.

Para limpar dados específicos do Amazon ECS, execute os seguintes comandos:

```
sudo rm -rf /var/log/ecs/*
sudo rm /var/lib/ecs/data/agent.db
```

Para obter mais informações sobre a criação de AMIs personalizadas otimizadas para o Amazon ECS, consulte [Como criar uma AMI personalizada usando uma AMI otimizada para o Amazon ECS?](https://forums.aws.amazon.com/knowledge-center/ecs-create-custom-amis/) no Centro de Conhecimento da AWS.

## Uso do ARN de imagem com a infraestrutura como código (IaC)
<a name="infrastructure-as-code-arn"></a>

É possível configurar a fórmula usando o console do EC2 Image Builder, a infraestrutura como código (por exemplo, o CloudFormation) ou o AWS SDK. Ao especificar uma imagem pai na fórmula, você pode especificar um ID de AMI do EC2, um ARN de imagem do Image Builder, um ID de produto do AWS Marketplace ou uma imagem de contêiner. A AWS disponibiliza publicamente IDs de AMI e ARNs de imagem do Image Builder de AMIs otimizadas para Amazon ECS. Este é o formato de ARN da imagem:

```
arn:${Partition}:imagebuilder:${Region}:${Account}:image/${ImageName}/${ImageVersion}
```

A `ImageVersion` tem o formato a seguir. Substitua {{principal}}, {{secundário}} e {{patch}} pelos valores mais recentes.

```
<{{major}}>.<{{minor}}>.<{{patch}}>
```

É possível substituir `major`, `minor` e `patch` por valores específicos ou usar o ARN sem versão de uma imagem, para que o pipeline permaneça atualizado com a versão mais recente da imagem pai. Um ARN sem versão usa o formato curinga ‘x.x.x’ para representar a versão da imagem. Essa abordagem permite que o serviço Image Builder seja resolvido automaticamente para a versão mais recente da imagem. Usar o ARN sem versão garante que sua referência sempre direcione para a imagem mais recente disponível, simplificando o processo de manutenção de imagens atualizadas na implantação. Ao criar uma fórmula com o console, o EC2 Image Builder identifica automaticamente o ARN da imagem pai. Ao usar o IaC para criar a fórmula, você deve identificar o ARN e selecionar a versão da imagem desejada ou usar o ARN sem versão para indicar a última imagem disponível. Recomendamos criar um script automatizado para filtrar e exibir somente imagens que estejam alinhadas com seus critérios. O script em Python a seguir mostra como recuperar uma lista de AMIs otimizadas para Amazon ECS. 

O script aceita dois argumentos opcionais: `owner` e `platform`, com valores padrão de “Amazon” e “Windows”, respectivamente. Os valores válidos do argumento do proprietário são: `Self`, `Shared`, `Amazon` e `ThirdParty`. Os valores válidos do argumento da plataforma são `Windows` e `Linux`. Por exemplo, se você executar o script com o argumento `owner` definido como `Amazon` e o `platform` definido como `Linux`, o script gera uma lista de imagens publicadas pela Amazon, incluindo imagens otimizadas para Amazon ECS.

```
import boto3
import argparse

def list_images(owner, platform):
    # Create a Boto3 session
    session = boto3.Session()
    
    # Create an EC2 Image Builder client
    client = session.client('imagebuilder')

    # Define the initial request parameters
    request_params = {
        'owner': owner,
        'filters': [
            {
                'name': 'platform',
                'values': [platform]
            }
        ]
    }

    # Initialize the results list
    all_images = []

    # Get the initial response with the first page of results
    response = client.list_images(**request_params)

    # Extract images from the response
    all_images.extend(response['imageVersionList'])

    # While 'nextToken' is present, continue paginating
    while 'nextToken' in response and response['nextToken']:
        # Update the token for the next request
        request_params['nextToken'] = response['nextToken']

        # Get the next page of results
        response = client.list_images(**request_params)

        # Extract images from the response
        all_images.extend(response['imageVersionList'])

    return all_images

def main():
    # Initialize the parser
    parser = argparse.ArgumentParser(description="List AWS images based on owner and platform")
    
    # Add the parameters/arguments
    parser.add_argument("--owner", default="Amazon", help="The owner of the images. Default is 'Amazon'.")
    parser.add_argument("--platform", default="Windows", help="The platform type of the images. Default is 'Windows'.")

    # Parse the arguments
    args = parser.parse_args()

    # Retrieve all images based on the provided owner and platform
    images = list_images(args.owner, args.platform)

    # Print the details of the images
    for image in images:
        print(f"Name: {image['name']}, Version: {image['version']}, ARN: {image['arn']}")

if __name__ == "__main__":
    main()
```

## Uso do ARN de imagem com o CloudFormation
<a name="arn-with-cloudformation"></a>

Uma fórmula de imagem do Image Builder é um esquema que especifica a imagem pai e os componentes necessários para alcançar a configuração pretendida da imagem de saída. Use o recurso `AWS::ImageBuilder::ImageRecipe`. Defina o valor de `ParentImage` para o ARN de imagem. Use o ARN sem versão da imagem desejada para garantir que o pipeline sempre use a versão mais recente da imagem. Por exemplo, `arn:aws:imagebuilder:us-east-1:aws:image/amazon-linux-2023-ecs-optimized-x86/x.x.x`. A definição do recurso `AWS::ImageBuilder::ImageRecipe` a seguir usa um ARN de imagem gerenciada pela Amazon:

```
ECSRecipe:
    Type: AWS::ImageBuilder::ImageRecipe
    Properties:
      Name: MyRecipe
      Version: '1.0.0'
      Components:
        - ComponentArn: [<The component arns of the image recipe>]
      ParentImage: "arn:aws:imagebuilder:us-east-1:aws:image/amazon-linux-2023-ecs-optimized-x86/x.x.x"
```

Para obter mais informações sobre o recurso [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-imagerecipe.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-imagerecipe.html), consulte o *Guia do usuário do AWS CloudFormation*.

É possível automatizar a criação de imagens no pipeline definindo a propriedade de `Schedule` do recurso `AWS::ImageBuilder::ImagePipeline`. O cronograma inclui uma condição inicial e uma expressão cron. Consulte mais informações em [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-imagepipeline.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-imagepipeline.html) no *Guia de Usuário AWS CloudFormation*.

 O exemplo de `AWS::ImageBuilder::ImagePipeline` a seguir faz com que o pipeline execute uma compilação às 10h do Tempo Universal Coordenado (UTC) todos os dias. Defina os seguintes valores de `Schedule`:
+ Defina `PipelineExecutionStartCondition` como `EXPRESSION_MATCH_AND_DEPENDENCY_UPDATES_AVAILABLE`. A compilação é iniciada somente se os recursos dependentes, como a imagem pai ou os componentes, que usam o caractere curinga ‘x’ em suas versões semânticas, forem atualizados. Isso garante que a compilação incorpore as atualizações mais recentes desses recursos.
+ Defina ScheduleExpression como a expressão cron `(0 10 * * ? *)`.

```
ECSPipeline:
    Type: AWS::ImageBuilder::ImagePipeline
    Properties:
      Name: my-pipeline
      ImageRecipeArn: <arn of the recipe you created in previous step>
      InfrastructureConfigurationArn: <ARN of the infrastructure configuration associated with this image pipeline>
      Schedule:
        PipelineExecutionStartCondition: EXPRESSION_MATCH_AND_DEPENDENCY_UPDATES_AVAILABLE
        ScheduleExpression: 'cron(0 10 * * ? *)'
```

## Uso do ARN de imagem com o Terraform
<a name="arn-with-terraform"></a>

A abordagem para especificar a imagem pai e o cronograma do pipeline no Terraform está alinhada com a do AWS CloudFormation. Use o recurso `aws_imagebuilder_image_recipe`. Defina o valor de `parent_image` para o ARN de imagem. Use o ARN sem versão da imagem desejada para garantir que o pipeline sempre use a versão mais recente da imagem. Para obter mais informações, consulte [https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/imagebuilder_image_recipe#argument-reference](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/imagebuilder_image_recipe#argument-reference) na documentação do Terraform. 

No bloco de configuração de agendamento do `aws_imagebuilder_image_pipeline resource`, defina o valor do argumento `schedule_expression` como uma expressão cron de sua escolha para especificar a frequência de execução do pipeline e defina a `pipeline_execution_start_condition` como `EXPRESSION_MATCH_AND_DEPENDENCY_UPDATES_AVAILABLE`. Para obter mais informações, consulte [https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/imagebuilder_image_pipeline#argument-reference](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/imagebuilder_image_pipeline#argument-reference) na documentação do Terraform. 