尝试创建云形成堆栈,以创建一个具有一个点实例的自动缩放组
并且该实例应使用生命周期策略挂钩 lambda 函数自动附加卷
这是我的堆栈:
AWSTemplateFormatVersion: '2010-09-09'
Description: Auto Scaling with Spot Instances and Lifecycle Hooks
Parameters:
ImageId:
Type: String
Default: 'ami-xxxxxx'
Description: AMI ID for the instances.
VolumeId:
Type: String
Default: 'vol-xxxxxxxxx'
Description: EBS Volume ID to attach.
AvailabilityZone:
Type: String
Default: 'xx-xxxxxxx-xx'
Description: Availability Zone for the instance.
SecurityGroup:
Type: String
Default: 'sg-xxxxxxxxx'
Description: Security Group ID for the instances.
KeyName:
Type: String
Default: 'xxxxxxxxxx'
Description: The EC2 Key Pair to allow SSH access to the instances.
Resources:
MyRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- autoscaling.amazonaws.com
- lambda.amazonaws.com
Action: 'sts:AssumeRole'
Policies:
- PolicyName: MyPolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- ec2:AttachVolume
- ec2:DetachVolume
Resource: '*'
MyAutoScalingGroup:
Type: 'AWS::AutoScaling::AutoScalingGroup'
Properties:
AvailabilityZones:
- !Ref AvailabilityZone
LaunchTemplate:
LaunchTemplateId: !Ref MyLaunchTemplate
Version: !GetAtt MyLaunchTemplate.LatestVersionNumber
MinSize: '1'
MaxSize: '1'
DesiredCapacity: '1'
MyLaunchTemplate:
Type: 'AWS::EC2::LaunchTemplate'
Properties:
LaunchTemplateData:
ImageId: !Ref ImageId
InstanceType: t2.xlarge
KeyName: !Ref KeyName
SecurityGroupIds:
- !Ref SecurityGroup
InstanceMarketOptions:
MarketType: spot
SpotOptions:
MaxPrice: '0.1'
LifecycleHookFunction:
Type: 'AWS::Lambda::Function'
Properties:
Handler: index.handler
Role: !GetAtt MyRole.Arn
Code:
ZipFile: |
import boto3
import time
def handler(event, context):
ec2 = boto3.client('ec2')
if event['detail-type'] == 'EC2 Instance-launch Lifecycle Action':
# Retry logic to ensure volume is detached before attaching
while True:
response = ec2.describe_volumes(VolumeIds=[event['detail']['VolumeId']])
if response['Volumes'][0]['State'] == 'available':
break
time.sleep(10)
ec2.attach_volume(VolumeId=event['detail']['VolumeId'], InstanceId=event['detail']['EC2InstanceId'], Device='/dev/sdf')
elif event['detail-type'] == 'EC2 Instance-terminate Lifecycle Action':
ec2.detach_volume(VolumeId=event['detail']['VolumeId'], InstanceId=event['detail']['EC2InstanceId'])
return 'Success'
Runtime: python3.8
Timeout: 120
LifecycleHook:
Type: 'AWS::AutoScaling::LifecycleHook'
Properties:
AutoScalingGroupName: !Ref MyAutoScalingGroup
LifecycleTransition: autoscaling:EC2_INSTANCE_LAUNCHING
NotificationTargetARN: !GetAtt LifecycleHookFunction.Arn
RoleARN: !GetAtt MyRole.Arn
HeartbeatTimeout: 3600
DefaultResult: CONTINUE
Outputs:
AutoScalingGroupName:
Description: Name of the Auto Scaling Group
Value: !Ref MyAutoScalingGroup
但在创建过程中出现此错误:
资源处理程序返回消息:“无法使用 IAM 角色 arn:aws:iam::yyyyy:role/xxxxxxxxxxxxxxx 将测试消息发布到通知目标 arn:aws:lambda:eu-central-1:yyyy:function:xxxxxxxxxxxxxxxxx。
请检查您的目标和角色配置,并尝试再次放置生命周期挂钩。 (服务:AutoScaling,状态代码:400,请求 ID:xxxxx-ce2a-4d25-9986-yy)”(RequestToken:xxxxxxx-b982-bb06-0fe2-yy,HandlerErrorCode:InvalidRequest)
我在您的模板中没有看到 AWS::Lambda::Permission。您需要授予自动缩放服务调用 lambda 函数的权限。请参阅此指南了解更多详细信息。