Atualização de AMIs para grupos do Auto Scaling - AWS Systems Manager

Atualização de AMIs para grupos do Auto Scaling

O seguinte exemplo atualiza um grupo do Auto Scaling com uma AMI com patch recém-aplicado. Essa abordagem garante que as novas imagens sejam automaticamente disponibilizadas para diferentes ambientes de computação que usam grupos do Auto Scaling.

A etapa final da automação neste exemplo usa uma função do Python para criar um novo modelo de execução que usa a AMI que acabou de receber patch. Em seguida, o grupo do Auto Scaling é atualizado para usar o novo modelo de execução. Neste tipo de cenário de Auto Scaling, os usuários podem encerrar instâncias existentes no grupo do Auto Scaling para forçar a execução de uma nova instância que usa a nova imagem. Como alternativa, os usuários podem aguardar e permitir que eventos de aumento ou redução de escala aconteçam para executar instâncias mais recentes.

Antes de começar

Conclua as seguintes tarefas antes de começar este exemplo.

  • Configure as funções do IAM para o Automation, um recurso do AWS Systems Manager. O Systems Manager requer uma função de perfil da instância e um ARN da função de serviço para processar automações. Para ter mais informações, consulte Configurar a automação.

Criar o runbook PatchAMIAndUpdateASG

Use o procedimento a seguir para criar o runbook PatchAMIAndUpdateASG, que aplica patch à AMI que você especifica para o parâmetro SourceAMI. O runbook também atualiza o grupo do Auto Scaling para usar a AMI que recebeu o patch mais recente.

Para criar e executar o runbook
  1. Abra o console AWS Systems Manager em https://console.aws.amazon.com/systems-manager/.

  2. No painel de navegação, escolha Documents.

  3. Na lista suspensa Create document (Criar documento), escolha Automation (Automação).

  4. No campo Name (Nome), insira PatchAMIAndUpdateASG.

  5. Escolha a guia Editor e escolha Edit (Editar).

  6. Escolha OK quando solicitado e exclua o conteúdo do espaço reservado no campo Document editor (Editor de documentos).

  7. No campo Document editor (Editor de documentos), cole o seguinte conteúdo do runbook de exemplo YAML:

    --- description: Systems Manager Automation Demo - Patch AMI and Update ASG schemaVersion: '0.3' assumeRole: '{{ AutomationAssumeRole }}' parameters: AutomationAssumeRole: type: String description: '(Required) The ARN of the role that allows Automation to perform the actions on your behalf. If no role is specified, Systems Manager Automation uses your IAM permissions to execute this document.' default: '' SourceAMI: type: String description: '(Required) The ID of the AMI you want to patch.' SubnetId: type: String description: '(Required) The ID of the subnet where the instance from the SourceAMI parameter is launched.' SecurityGroupIds: type: StringList description: '(Required) The IDs of the security groups to associate with the instance launched from the SourceAMI parameter.' NewAMI: type: String description: '(Optional) The name of of newly patched AMI.' default: 'patchedAMI-{{global:DATE_TIME}}' TargetASG: type: String description: '(Required) The name of the Auto Scaling group you want to update.' InstanceProfile: type: String description: '(Required) The name of the IAM instance profile you want the source instance to use.' SnapshotId: type: String description: (Optional) The snapshot ID to use to retrieve a patch baseline snapshot. default: '' RebootOption: type: String description: '(Optional) Reboot behavior after a patch Install operation. If you choose NoReboot and patches are installed, the instance is marked as non-compliant until a subsequent reboot and scan.' allowedValues: - NoReboot - RebootIfNeeded default: RebootIfNeeded Operation: type: String description: (Optional) The update or configuration to perform on the instance. The system checks if patches specified in the patch baseline are installed on the instance. The install operation installs patches missing from the baseline. allowedValues: - Install - Scan default: Install mainSteps: - name: startInstances action: 'aws:runInstances' timeoutSeconds: 1200 maxAttempts: 1 onFailure: Abort inputs: ImageId: '{{ SourceAMI }}' InstanceType: m5.large MinInstanceCount: 1 MaxInstanceCount: 1 IamInstanceProfileName: '{{ InstanceProfile }}' SubnetId: '{{ SubnetId }}' SecurityGroupIds: '{{ SecurityGroupIds }}' - name: verifyInstanceManaged action: 'aws:waitForAwsResourceProperty' timeoutSeconds: 600 inputs: Service: ssm Api: DescribeInstanceInformation InstanceInformationFilterList: - key: InstanceIds valueSet: - '{{ startInstances.InstanceIds }}' PropertySelector: '$.InstanceInformationList[0].PingStatus' DesiredValues: - Online onFailure: 'step:terminateInstance' - name: installPatches action: 'aws:runCommand' timeoutSeconds: 7200 onFailure: Abort inputs: DocumentName: AWS-RunPatchBaseline Parameters: SnapshotId: '{{SnapshotId}}' RebootOption: '{{RebootOption}}' Operation: '{{Operation}}' InstanceIds: - '{{ startInstances.InstanceIds }}' - name: stopInstance action: 'aws:changeInstanceState' maxAttempts: 1 onFailure: Continue inputs: InstanceIds: - '{{ startInstances.InstanceIds }}' DesiredState: stopped - name: createImage action: 'aws:createImage' maxAttempts: 1 onFailure: Continue inputs: InstanceId: '{{ startInstances.InstanceIds }}' ImageName: '{{ NewAMI }}' NoReboot: false ImageDescription: Patched AMI created by Automation - name: terminateInstance action: 'aws:changeInstanceState' maxAttempts: 1 onFailure: Continue inputs: InstanceIds: - '{{ startInstances.InstanceIds }}' DesiredState: terminated - name: updateASG action: 'aws:executeScript' timeoutSeconds: 300 maxAttempts: 1 onFailure: Abort inputs: Runtime: python3.8 Handler: update_asg InputPayload: TargetASG: '{{TargetASG}}' NewAMI: '{{createImage.ImageId}}' Script: |- from __future__ import print_function import datetime import json import time import boto3 # create auto scaling and ec2 client asg = boto3.client('autoscaling') ec2 = boto3.client('ec2') def update_asg(event, context): print("Received event: " + json.dumps(event, indent=2)) target_asg = event['TargetASG'] new_ami = event['NewAMI'] # get object for the ASG we're going to update, filter by name of target ASG asg_query = asg.describe_auto_scaling_groups(AutoScalingGroupNames=[target_asg]) if 'AutoScalingGroups' not in asg_query or not asg_query['AutoScalingGroups']: return 'No ASG found matching the value you specified.' # gets details of an instance from the ASG that we'll use to model the new launch template after source_instance_id = asg_query.get('AutoScalingGroups')[0]['Instances'][0]['InstanceId'] instance_properties = ec2.describe_instances( InstanceIds=[source_instance_id] ) source_instance = instance_properties['Reservations'][0]['Instances'][0] # create list of security group IDs security_groups = [] for group in source_instance['SecurityGroups']: security_groups.append(group['GroupId']) # create a list of dictionary objects for block device mappings mappings = [] for block in source_instance['BlockDeviceMappings']: volume_query = ec2.describe_volumes( VolumeIds=[block['Ebs']['VolumeId']] ) volume_details = volume_query['Volumes'] device_name = block['DeviceName'] volume_size = volume_details[0]['Size'] volume_type = volume_details[0]['VolumeType'] device = {'DeviceName': device_name, 'Ebs': {'VolumeSize': volume_size, 'VolumeType': volume_type}} mappings.append(device) # create new launch template using details returned from instance in the ASG and specify the newly patched AMI time_stamp = time.time() time_stamp_string = datetime.datetime.fromtimestamp(time_stamp).strftime('%m-%d-%Y_%H-%M-%S') new_template_name = f'{new_ami}_{time_stamp_string}' try: ec2.create_launch_template( LaunchTemplateName=new_template_name, LaunchTemplateData={ 'BlockDeviceMappings': mappings, 'ImageId': new_ami, 'InstanceType': source_instance['InstanceType'], 'IamInstanceProfile': { 'Arn': source_instance['IamInstanceProfile']['Arn'] }, 'KeyName': source_instance['KeyName'], 'SecurityGroupIds': security_groups } ) except Exception as e: return f'Exception caught: {str(e)}' else: # update ASG to use new launch template asg.update_auto_scaling_group( AutoScalingGroupName=target_asg, LaunchTemplate={ 'LaunchTemplateName': new_template_name } ) return f'Updated ASG {target_asg} with new launch template {new_template_name} which uses AMI {new_ami}.' outputs: - createImage.ImageId
  8. Escolha Criar automação.

  9. No painel de navegação, selecione Automation e Execute automation (Executar automação).

  10. Na página Choose document (Escolher documento), escolha a guia Owned by me (Pertencem a mim).

  11. Procure o runbook PatchAMIAndUpdateASG e selecione o botão no cartão PatchAMIAndUpdateASG.

  12. Escolha Próximo.

  13. Escolha Simple execution (Execução simples).

  14. Especificar valores para os parâmetro de entrada. Verifique se o SubnetId e o SecurityGroupIds especificados permitem acesso aos endpoints públicos do Systems Manager ou aos seus endpoints de interface para o Systems Manager.

  15. Clique em Executar.

  16. Após a conclusão da automação, no console do Amazon EC2, escolha Auto Scaling e depois escolha Launch Templates (Modelos de execução). Verifique se você vê o novo modelo de execução e se ele usa a nova AMI.

  17. Selecione Auto Scaling e, depois, escolhaAuto Scaling Groups (Grupos Auto Scaling). Verifique se o grupo do Auto Scaling usa o novo modelo de execução.

  18. Encerre uma ou mais instâncias no grupo de Auto Scaling. As instâncias de substituição serão executadas usando a nova AMI.