Ripristino di un volume radice dall'ultimo snapshot - AWS Systems Manager

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Ripristino di un volume radice dall'ultimo snapshot

Il sistema operativo su un volume radice può danneggiarsi per vari motivi. Ad esempio, a seguito di un'operazione di patch, le istanze potrebbero non riuscire ad avviarsi correttamente a causa di un kernel o di un registro di sistema danneggiato. L'automazione delle attività di risoluzione dei problemi più comuni, come il ripristino di un volume root dall'ultima istantanea scattata prima dell'operazione di patching, può ridurre i tempi di inattività e accelerare le attività di risoluzione dei problemi. AWS Systems Manager Le azioni di automazione possono aiutarti a raggiungere questo obiettivo. L'automazione è uno strumento in AWS Systems Manager.

Il seguente AWS Systems Manager runbook di esempio esegue queste azioni:

  • Utilizza l'operazione di automazione aws:executeAwsApi per recuperare i dettagli dal volume principale dell'istanza.

  • Utilizza l'operazione di automazione aws:executeScript per recuperare lo snapshot più recente per il volume radice.

  • Utilizza l'operazione di automazione aws:branch per continuare l'automazione se viene trovato uno snapshot per il volume radice.

YAML
--- description: Custom Automation Troubleshooting Example 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 use this runbook." default: '' InstanceId: type: String description: "(Required) The Instance Id whose root EBS volume you want to restore the latest Snapshot." default: '' mainSteps: - name: getInstanceDetails action: aws:executeAwsApi onFailure: Abort inputs: Service: ec2 Api: DescribeInstances InstanceIds: - "{{ InstanceId }}" outputs: - Name: availabilityZone Selector: "$.Reservations[0].Instances[0].Placement.AvailabilityZone" Type: String - Name: rootDeviceName Selector: "$.Reservations[0].Instances[0].RootDeviceName" Type: String nextStep: getRootVolumeId - name: getRootVolumeId action: aws:executeAwsApi onFailure: Abort inputs: Service: ec2 Api: DescribeVolumes Filters: - Name: attachment.device Values: ["{{ getInstanceDetails.rootDeviceName }}"] - Name: attachment.instance-id Values: ["{{ InstanceId }}"] outputs: - Name: rootVolumeId Selector: "$.Volumes[0].VolumeId" Type: String nextStep: getSnapshotsByStartTime - name: getSnapshotsByStartTime action: aws:executeScript timeoutSeconds: 45 onFailure: Abort inputs: Runtime: python3.8 Handler: getSnapshotsByStartTime InputPayload: rootVolumeId : "{{ getRootVolumeId.rootVolumeId }}" Script: |- def getSnapshotsByStartTime(events,context): import boto3 #Initialize client ec2 = boto3.client('ec2') rootVolumeId = events['rootVolumeId'] snapshotsQuery = ec2.describe_snapshots( Filters=[ { "Name": "volume-id", "Values": [rootVolumeId] } ] ) if not snapshotsQuery['Snapshots']: noSnapshotFoundString = "NoSnapshotFound" return { 'noSnapshotFound' : noSnapshotFoundString } else: jsonSnapshots = snapshotsQuery['Snapshots'] sortedSnapshots = sorted(jsonSnapshots, key=lambda k: k['StartTime'], reverse=True) latestSortedSnapshotId = sortedSnapshots[0]['SnapshotId'] return { 'latestSnapshotId' : latestSortedSnapshotId } outputs: - Name: Payload Selector: $.Payload Type: StringMap - Name: latestSnapshotId Selector: $.Payload.latestSnapshotId Type: String - Name: noSnapshotFound Selector: $.Payload.noSnapshotFound Type: String nextStep: branchFromResults - name: branchFromResults action: aws:branch onFailure: Abort inputs: Choices: - NextStep: createNewRootVolumeFromSnapshot Not: Variable: "{{ getSnapshotsByStartTime.noSnapshotFound }}" StringEquals: "NoSnapshotFound" isEnd: true - name: createNewRootVolumeFromSnapshot action: aws:executeAwsApi onFailure: Abort inputs: Service: ec2 Api: CreateVolume AvailabilityZone: "{{ getInstanceDetails.availabilityZone }}" SnapshotId: "{{ getSnapshotsByStartTime.latestSnapshotId }}" outputs: - Name: newRootVolumeId Selector: "$.VolumeId" Type: String nextStep: stopInstance - name: stopInstance action: aws:executeAwsApi onFailure: Abort inputs: Service: ec2 Api: StopInstances InstanceIds: - "{{ InstanceId }}" nextStep: verifyVolumeAvailability - name: verifyVolumeAvailability action: aws:waitForAwsResourceProperty timeoutSeconds: 120 inputs: Service: ec2 Api: DescribeVolumes VolumeIds: - "{{ createNewRootVolumeFromSnapshot.newRootVolumeId }}" PropertySelector: "$.Volumes[0].State" DesiredValues: - "available" nextStep: verifyInstanceStopped - name: verifyInstanceStopped action: aws:waitForAwsResourceProperty timeoutSeconds: 120 inputs: Service: ec2 Api: DescribeInstances InstanceIds: - "{{ InstanceId }}" PropertySelector: "$.Reservations[0].Instances[0].State.Name" DesiredValues: - "stopped" nextStep: detachRootVolume - name: detachRootVolume action: aws:executeAwsApi onFailure: Abort inputs: Service: ec2 Api: DetachVolume VolumeId: "{{ getRootVolumeId.rootVolumeId }}" nextStep: verifyRootVolumeDetached - name: verifyRootVolumeDetached action: aws:waitForAwsResourceProperty timeoutSeconds: 30 inputs: Service: ec2 Api: DescribeVolumes VolumeIds: - "{{ getRootVolumeId.rootVolumeId }}" PropertySelector: "$.Volumes[0].State" DesiredValues: - "available" nextStep: attachNewRootVolume - name: attachNewRootVolume action: aws:executeAwsApi onFailure: Abort inputs: Service: ec2 Api: AttachVolume Device: "{{ getInstanceDetails.rootDeviceName }}" InstanceId: "{{ InstanceId }}" VolumeId: "{{ createNewRootVolumeFromSnapshot.newRootVolumeId }}" nextStep: verifyNewRootVolumeAttached - name: verifyNewRootVolumeAttached action: aws:waitForAwsResourceProperty timeoutSeconds: 30 inputs: Service: ec2 Api: DescribeVolumes VolumeIds: - "{{ createNewRootVolumeFromSnapshot.newRootVolumeId }}" PropertySelector: "$.Volumes[0].Attachments[0].State" DesiredValues: - "attached" nextStep: startInstance - name: startInstance action: aws:executeAwsApi onFailure: Abort inputs: Service: ec2 Api: StartInstances InstanceIds: - "{{ InstanceId }}"
JSON
{ "description": "Custom Automation Troubleshooting Example", "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 run this runbook.", "default": "" }, "InstanceId": { "type": "String", "description": "(Required) The Instance Id whose root EBS volume you want to restore the latest Snapshot.", "default": "" } }, "mainSteps": [ { "name": "getInstanceDetails", "action": "aws:executeAwsApi", "onFailure": "Abort", "inputs": { "Service": "ec2", "Api": "DescribeInstances", "InstanceIds": [ "{{ InstanceId }}" ] }, "outputs": [ { "Name": "availabilityZone", "Selector": "$.Reservations[0].Instances[0].Placement.AvailabilityZone", "Type": "String" }, { "Name": "rootDeviceName", "Selector": "$.Reservations[0].Instances[0].RootDeviceName", "Type": "String" } ], "nextStep": "getRootVolumeId" }, { "name": "getRootVolumeId", "action": "aws:executeAwsApi", "onFailure": "Abort", "inputs": { "Service": "ec2", "Api": "DescribeVolumes", "Filters": [ { "Name": "attachment.device", "Values": [ "{{ getInstanceDetails.rootDeviceName }}" ] }, { "Name": "attachment.instance-id", "Values": [ "{{ InstanceId }}" ] } ] }, "outputs": [ { "Name": "rootVolumeId", "Selector": "$.Volumes[0].VolumeId", "Type": "String" } ], "nextStep": "getSnapshotsByStartTime" }, { "name": "getSnapshotsByStartTime", "action": "aws:executeScript", "timeoutSeconds": 45, "onFailure": "Continue", "inputs": { "Runtime": "python3.8", "Handler": "getSnapshotsByStartTime", "InputPayload": { "rootVolumeId": "{{ getRootVolumeId.rootVolumeId }}" }, "Attachment": "getSnapshotsByStartTime.py" }, "outputs": [ { "Name": "Payload", "Selector": "$.Payload", "Type": "StringMap" }, { "Name": "latestSnapshotId", "Selector": "$.Payload.latestSnapshotId", "Type": "String" }, { "Name": "noSnapshotFound", "Selector": "$.Payload.noSnapshotFound", "Type": "String" } ], "nextStep": "branchFromResults" }, { "name": "branchFromResults", "action": "aws:branch", "onFailure": "Abort", "inputs": { "Choices": [ { "NextStep": "createNewRootVolumeFromSnapshot", "Not": { "Variable": "{{ getSnapshotsByStartTime.noSnapshotFound }}", "StringEquals": "NoSnapshotFound" } } ] }, "isEnd": true }, { "name": "createNewRootVolumeFromSnapshot", "action": "aws:executeAwsApi", "onFailure": "Abort", "inputs": { "Service": "ec2", "Api": "CreateVolume", "AvailabilityZone": "{{ getInstanceDetails.availabilityZone }}", "SnapshotId": "{{ getSnapshotsByStartTime.latestSnapshotId }}" }, "outputs": [ { "Name": "newRootVolumeId", "Selector": "$.VolumeId", "Type": "String" } ], "nextStep": "stopInstance" }, { "name": "stopInstance", "action": "aws:executeAwsApi", "onFailure": "Abort", "inputs": { "Service": "ec2", "Api": "StopInstances", "InstanceIds": [ "{{ InstanceId }}" ] }, "nextStep": "verifyVolumeAvailability" }, { "name": "verifyVolumeAvailability", "action": "aws:waitForAwsResourceProperty", "timeoutSeconds": 120, "inputs": { "Service": "ec2", "Api": "DescribeVolumes", "VolumeIds": [ "{{ createNewRootVolumeFromSnapshot.newRootVolumeId }}" ], "PropertySelector": "$.Volumes[0].State", "DesiredValues": [ "available" ] }, "nextStep": "verifyInstanceStopped" }, { "name": "verifyInstanceStopped", "action": "aws:waitForAwsResourceProperty", "timeoutSeconds": 120, "inputs": { "Service": "ec2", "Api": "DescribeInstances", "InstanceIds": [ "{{ InstanceId }}" ], "PropertySelector": "$.Reservations[0].Instances[0].State.Name", "DesiredValues": [ "stopped" ] }, "nextStep": "detachRootVolume" }, { "name": "detachRootVolume", "action": "aws:executeAwsApi", "onFailure": "Abort", "inputs": { "Service": "ec2", "Api": "DetachVolume", "VolumeId": "{{ getRootVolumeId.rootVolumeId }}" }, "nextStep": "verifyRootVolumeDetached" }, { "name": "verifyRootVolumeDetached", "action": "aws:waitForAwsResourceProperty", "timeoutSeconds": 30, "inputs": { "Service": "ec2", "Api": "DescribeVolumes", "VolumeIds": [ "{{ getRootVolumeId.rootVolumeId }}" ], "PropertySelector": "$.Volumes[0].State", "DesiredValues": [ "available" ] }, "nextStep": "attachNewRootVolume" }, { "name": "attachNewRootVolume", "action": "aws:executeAwsApi", "onFailure": "Abort", "inputs": { "Service": "ec2", "Api": "AttachVolume", "Device": "{{ getInstanceDetails.rootDeviceName }}", "InstanceId": "{{ InstanceId }}", "VolumeId": "{{ createNewRootVolumeFromSnapshot.newRootVolumeId }}" }, "nextStep": "verifyNewRootVolumeAttached" }, { "name": "verifyNewRootVolumeAttached", "action": "aws:waitForAwsResourceProperty", "timeoutSeconds": 30, "inputs": { "Service": "ec2", "Api": "DescribeVolumes", "VolumeIds": [ "{{ createNewRootVolumeFromSnapshot.newRootVolumeId }}" ], "PropertySelector": "$.Volumes[0].Attachments[0].State", "DesiredValues": [ "attached" ] }, "nextStep": "startInstance" }, { "name": "startInstance", "action": "aws:executeAwsApi", "onFailure": "Abort", "inputs": { "Service": "ec2", "Api": "StartInstances", "InstanceIds": [ "{{ InstanceId }}" ] } } ], "files": { "getSnapshotsByStartTime.py": { "checksums": { "sha256": "sampleETagValue" } } } }