我必须在AWS自动缩放扩展事件期间采取某些操作.ec2实例应该能够将一些日志和报告保存到S3存储桶。这可能需要5到15分钟。
我已经有一个在终止时调用的脚本:
ln -s /etc/ec2-termination /etc/rc0.d/S01ec2-termination
然而,剧本在5分钟内突然结束。我正在考虑利用AWS LifeCycle钩子来延长EC2的使用寿命。 关于以类似于用户数据脚本的方式调用脚本的文档并不清楚。
有一些方法可以使用AWS lambda或SNS来接收通知。这可能会用于通知ec2。
但是,我想知道是否有一个更简单的解决方案来解决这个问题。有没有办法使用Lifecycle钩子注册脚本,并在渐变事件中调用。
答案 0 :(得分:5)
没有
实例终止的事实在AWS基础架构中进行管理。 Auto Scaling没有能力进入"进入" EC2实例触发任何事情。
相反,您需要在实例上编写一些代码来检查实例是否处于终止状态,然后采取适当的措施。
一个例子可能是:
(请注意,在关机过程中脚本不会再次触发,否则它可能会每15秒尝试执行一次关机过程!)
或者,将关闭信息存储在Systems Manager Parameter Store或数据库中,但使用Tags似乎可以很好地扩展!
更新版本:
感谢raevilman的想法:
更简单!
答案 1 :(得分:4)
是的,您可以使用AWS Systems Manager在终止的EC2实例上运行shell脚本。
为您的Autoscaling组配置生命周期挂钩。您可以从EC2 console或CLI执行此操作:
aws自动缩放put-lifecycle-hook
--lifecycle-hook-name my-lifecycle-hook
--auto-scaling-group-name My_AutoScalingGroup
--lifecycle-transition自动缩放:EC2_INSTANCE_TERMINATING
--default-result继续
--region us-east-2
根据脚本运行的持续时间设置“心跳超时”值。 现在,当您的ASG扩大时,您的实例将进入Terminate:Wait状态,在此状态下您的脚本将运行。
另一种解决方案:当实例更改为“终止:等待”状态时,您的生命周期挂钩会将带有实例ID的消息发送到SQS。收到消息后,SQS会触发Lambda函数,该函数会将运行命令发送给系统管理器,以在终止实例上执行Shell脚本。
答案 2 :(得分:0)
根据您要实现的目标,使用这种方法,您只需要两件事,并且要简单得多):
答案 3 :(得分:0)
以下是基于this article的使用生命周期挂钩,自动化和运行命令的解决方案:
Resources:
MyTerminationHook:
Type: AWS::AutoScaling::LifecycleHook
Properties:
AutoScalingGroupName: !Ref MyAutoScalingGroup
DefaultResult: CONTINUE
HeartbeatTimeout: 900
LifecycleTransition: autoscaling:EC2_INSTANCE_TERMINATING
MyTerminationDocument:
Type: AWS::SSM::Document
Properties:
DocumentType: Automation
Content:
description: 'Run command before terminating instance'
schemaVersion: '0.3'
assumeRole: !GetAtt MyTerminationDocumentRole.Arn
parameters:
instanceId:
type: String
mainSteps:
- name: RunCommand
action: aws:runCommand
inputs:
DocumentName: AWS-RunShellScript
InstanceIds:
- '{{ instanceId }}'
TimeoutSeconds: 60
Parameters:
commands: /etc/my-termination-script.sh
executionTimeout: '900'
- name: TerminateInstance
action: aws:executeAwsApi
inputs:
Api: CompleteLifecycleAction
AutoScalingGroupName: !Ref MyAutoScalingGroup
InstanceId: '{{ instanceId }}'
LifecycleActionResult: CONTINUE
LifecycleHookName: !Ref MyTerminationHook
Service: autoscaling
MyTerminationRule:
Type: AWS::Events::Rule
Properties:
EventPattern:
source:
- aws.autoscaling
detail-type:
- EC2 Instance-terminate Lifecycle Action
detail:
AutoScalingGroupName:
- !Ref MyAutoScalingGroup
Targets:
- Id: my-termination-document
Arn: !Sub 'arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:automation-definition/${MyTerminationDocument}:$DEFAULT'
RoleArn: !GetAtt MyTerminationRuleRole.Arn
InputTransformer:
InputPathsMap:
instanceId: '$.detail.EC2InstanceId'
InputTemplate: '{"instanceId":[<instanceId>]}'
MyTerminationRuleRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: events.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: start-automation
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- ssm:StartAutomationExecution
Resource: !Sub 'arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:automation-definition/${MyTerminationDocument}:$DEFAULT'
MyTerminationDocumentRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: ssm.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: run-command-and-complete-lifecycle
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- autoscaling:CompleteLifecycleAction
Resource: !Sub 'arn:aws:autoscaling:${AWS::Region}:${AWS::AccountId}:autoScalingGroup:*:autoScalingGroupName/${MyAutoScalingGroup}'
- Effect: Allow
Action:
- ssm:DescribeInstanceInformation
- ssm:ListCommands
- ssm:ListCommandInvocations
Resource: '*'
- Effect: Allow
Action:
- ssm:SendCommand
Resource: 'arn:aws:ssm:*::document/AWS-RunShellScript'
- Effect: Allow
Action:
- ssm:SendCommand
Resource: !Sub 'arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:instance/*'
答案 4 :(得分:0)
我知道这是一个迟到的答案
但是对于新的
在这里您可以找到满足您需求的 aws 博客
答案 5 :(得分:0)
只是对我之前的评论进行更正。如果实例因 Auto Scaling 事件而终止,则 SSM 运行命令将对 Autoscaling 组中的实例起作用,而不是手动终止实例。