繁体   English   中英

AWS Boto3-等待直到将卷附加到EC2实例

[英]AWS boto3 - wait until volume is attached to EC2 instance

我需要实现的是具有Lambda函数来创建EBS卷,将其附加到EC2实例,对其进行格式化并将其安装在/data目录下。

我正在使用ssm:RunCommandclient.send_command )执行应该格式化和装入卷的shell脚本,但是代码失败,因为在我调用RunCommand时卷尚未附加到实例。

我正在使用EC2.Waiter.VolumeInUse等待连接卷,但似乎无法正常工作。

这是我的代码

import boto3

# HARDCODED VALUES FOR TESTING
AVAILABILITY_ZONE = 'us-east-1d'
INSTANCE_ID = 'i-0bd640b495fd7d77c'

ec2_client = boto3.client('ec2')
ssm_client = boto3.client('ssm')

volume_available_waiter = ec2_client.get_waiter('volume_available')
volume_attached_waiter = ec2_client.get_waiter('volume_in_use')


def lambda_handler(event, context):
    try:
        # create 8 GB general purpose volume in given AZ
        create_volume_response = ec2_client.create_volume(
            AvailabilityZone=AVAILABILITY_ZONE,
            Size=8,
            VolumeType='gp2'
        )

        # retrieve volume id and wait till it is available
        volume_id = create_volume_response['VolumeId']
        volume_available_waiter.wait(
            VolumeIds=[volume_id]
        )

        # attach newly created volume to a given instance
        ec2_client.attach_volume(
            Device='/dev/xvdh',
            InstanceId=INSTANCE_ID,
            VolumeId=volume_id
        )

        # wait till the volume is properly attached to EC2 instance
        volume_attached_waiter.wait(
            VolumeIds=[volume_id]
        )

        # use SSM RunCommand to format and mount volume
        ssm_client.send_command(
            InstanceIds=[INSTANCE_ID],
            DocumentName='AWS-RunShellScript',
            Parameters={
                'commands': [
                    'echo "STARTING MOUNT SEQUENCE"'
                    'echo $(lsblk)'
                    'mkfs -t xfs /dev/xvdh',
                    'mkdir /data',
                    'mount /dev/xvdh /data'
                ]
            }
        )

    except Exception as e:
        print(e)

    return 0

当检查log cat /var/log/messages ,我可以清楚地看到echo $(lsblk)输出尚未附加新卷。

等待将卷连接到EC2实例之前的正确方法是什么?

在这种情况下,正确的方法是等待直到在SSM中附加了卷,而不是让lambda挂起并等待。
由于已经在使用SSM,因此您将需要制作一个SSM Automation文档 ,该文档将等待卷被附加,然后执行RunCommand来格式化和挂载该卷。
您的文档将需要添加2个步骤:
1- aws:waitForAwsResourceProperty等待连接卷
2- aws:runCommand执行您的Shell脚本

首先,创建您的SSM自动化文档:

---
description: "Automation Document Example YAML Template"
schemaVersion: "0.3"
assumeRole: "{{ AutomationAssumeRole }}"
parameters:
  InstanceId:
    type: "String"
    description: "(Required) The ID of the EC2 Instance."
  VolumeId:
    type: "String"
    description: "(Required) The ID of the volume."
  AutomationAssumeRole:
    type: "String"
    description: "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf."
    default: ""

mainSteps:
- name: "VerifyVolumeAttached"
  action: "aws:waitForAwsResourceProperty"
  timeoutSeconds: 600
  inputs:
    Service: "ec2"
    Api: "DescribeVolumes"
    VolumeIds: ["{{ VolumeId }}"]
    PropertySelector: "$.Volumes[0].Attachments[0].State"
    DesiredValues:
    - "attached"

- name: "MountVolume"
  action: "aws:runCommand"
  inputs:
    DocumentName: "AWS-RunShellScript"
    InstanceIds:
    - "{{InstanceId}}"
    Parameters:
      commands: ['echo "STARTING MOUNT SEQUENCE"','echo $(lsblk)','mkfs -t xfs /dev/xvdh','mkdir /data','mount /dev/xvdh /data']

然后,您将需要为SSM创建IAM角色,并具有对Runcommand和DescribeVolumes的必需权限。
然后将lambda中的send命令块替换为:

# Start SSM automation execution    
ssm_client.start_automation_execution(DocumentName=your_automation_document_name,Parameters={"InstanceId": [INSTANCE_ID],"VolumeId":[volume_id],"AutomationAssumeRole":[ssm_automation_role_arn]}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM