aws cloudformation 使用CommandRunner在堆栈中运行脚本
创始人
2024-05-24 08:05:12
0

参考资料

  • Running bash commands in AWS CloudFormation templates

  • 如何使用 AWSUtility::CloudFormation::CommandRunner 在 CloudFormation 堆栈中的资源之前或之后运行命令?

由于cloudformation语法和资源的限制,有些场景下我们可能会希望执行一些自定义逻辑。实际上cloudformation已经提供了自定义资源和宏实现这个目的。而CommandRunner则从另一个角度解决此问题。

commandrunner本质上就是启动额外的ec2来执行指定的逻辑,和自定义资源的lambda类似的思路,只是资源类型不同

测试过程

安装commandrunner

git clone https://github.com/aws-cloudformation/aws-cloudformation-resource-providers-awsutilities-commandrunner.git
cd aws-cloudformation-resource-providers-awsutilities-commandrunner
curl -LO https://github.com/aws-cloudformation/aws-cloudformation-resource-providers-awsutilities-commandrunner/releases/latest/download/awsutility-cloudformation-commandrunner.zip
./scripts/register.sh --set-default

具体的执行过程如下,核心具体就是将awsutility-cloudformation-commandrunner.zip注册到cfn中,需要临时s3桶存储该zip文件

Creating Execution Role...
Waiting for execution role stack to complete...
Waiting for execution role stack to complete...
Creating/Updating Execution Role complete.
Creating temporary S3 Bucket b34239efa0b947bebd574be7fa6d7e2d...
Creating temporary S3 Bucket b34239efa0b947bebd574be7fa6d7e2d complete.
Configuring S3 Bucket Policy for temporary S3 Bucket b34239efa0b947bebd574be7fa6d7e2d...
An error occurred (MalformedPolicy) when calling the PutBucketPolicy operation: Policy has invalid resource
Configuring S3 Bucket Policy for temporary S3 Bucket b34239efa0b947bebd574be7fa6d7e2d complete.
Copying Schema Handler Package to temporary S3 Bucket b34239efa0b947bebd574be7fa6d7e2d...
Copying Schema Handler Package to temporary S3 Bucket b34239efa0b947bebd574be7fa6d7e2d complete.
Creating CommandRunner Log Group called awsutility-cloudformation-commandrunner-logs2...
Creating CommandRunner Log Group complete.
Registering AWSUtility::CloudFormation::CommandRunner to AWS CloudFormation...
RegistrationToken: 5a22a5d4-723e-4d2a-b20d-eff95352830c
Waiting for registration to complete...
Waiting for registration to complete...
Waiting for registration to complete...
Waiting for registration to complete...
Registering AWSUtility::CloudFormation::CommandRunner to AWS CloudFormation complete.
Setting current version as default...
Setting current version as default complete. (Current Version is 00000001)
Cleaning up temporary S3 Bucket...
Deleting SchemaHandlerPackage from temporary S3 Bucket b34239efa0b947bebd574be7fa6d7e2d...
Deleting SchemaHandlerPackage from temporary S3 Bucket b34239efa0b947bebd574be7fa6d7e2d complete.
Cleaning up temporary S3 Bucket complete.

以上命令会使用默认的awscli凭证在账户中创建cfn资源

在这里插入图片描述

之后可以在cfn模板中直接使用,这里创建简单的s3资源

Resources:S3Bucket:Type: AWS::S3::BucketProperties:VersioningConfiguration:Status: SuspendedBucketEncryption:ServerSideEncryptionConfiguration:- ServerSideEncryptionByDefault:SSEAlgorithm: AES256CommandRunner1:DependsOn: S3BucketType: AWSUtility::CloudFormation::CommandRunnerProperties:Command: echo justfortest > /command-output.txtRole: MyEc2AdministratorAccessSubnetId: subnet-0270xxxxxxxdCommandRunner2:Type: AWSUtility::CloudFormation::CommandRunnerProperties:Role: MyEc2AdministratorAccessCommand: echo helloworld > /command-output.txtSubnetId: subnet-02xxxxxxxdOutputs:Output1:Description: The output of the CommandRunner.Value: !GetAtt CommandRunner1.OutputOutput2:Description: The output of the CommandRunner.Value: !GetAtt CommandRunner2.Output

由于创建了两个commandrunner资源,因此会创建额外的两个堆栈

在这里插入图片描述

启动两台ec2示例,默认为t2.medium

在这里插入图片描述

以下是AWSUtility-CloudFormation-CommandRunner资源的模板截取,逻辑较为简单,只需要关注userdata部分,相关的概念的命令在之前的文章中都提到过,不赘述

  • 执行init初始化
  • 执行指定的command命令
  • 执行signal,向cfn响应,响应内容是command-output.txt文件中的内容
Parameters:
...略Command:Type: StringDefault: >-yum install jq -y && aws ssm get-parameter --name RepositoryName --regionus-east-1 | jq -r .Parameter.Value > /commandrunner-output.txtLogGroup:Type: StringDefault: cloudformation-commandrunner-log-group
Resources:SecurityGroup:Condition: CreateSecurityGroupType: AWS::EC2::SecurityGroupEC2Instance:Type: AWS::EC2::InstanceMetadata:AWS::CloudFormation::Init:config:packages:yum:awslogs: []files:/etc/awslogs/awslogs.conf:content:Fn::Sub: |[general]state_file= /var/awslogs/state/agent-state[/var/log/cloud-init.log]file = /var/log/cloud-init.log\nlog_group_name = ${LogGroup}log_stream_name = {instance_id}/cloud-init.log... 略/etc/awslogs/awscli.conf:content:Fn::Sub: |[plugins]cwlogs = cwlogs[default]region = ${AWS::Region}commands:01_create_state_directory:command: mkdir -p /var/awslogs/stateservices:sysvinit:awslogsd:enabled: trueensureRunning: truefiles:- /etc/awslogs/awslogs.confProperties:UserData:Fn::Base64:Fn::Sub: >-#!/bin/bashyum install -y aws-cfn-bootstrap/opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resourceEC2Instance  --region ${AWS::Region}${Command}/opt/aws/bin/cfn-signal -r 'Command ran successfully.' -e 0 --id'Command Output' --data "$(cat /command-output.txt)"'${WaitConditionHandle}'echo Contents of /command-output.txt = $(cat /command-output.txt)WaitConditionHandle:Type: AWS::CloudFormation::WaitConditionHandleWaitCondition:Type: AWS::CloudFormation::WaitConditionProperties:Count: 1Handle:Ref: WaitConditionHandleTimeout:Ref: Timeout
Outputs:Result:Description: The output of the commandrunner.Value:Fn::Select:- 3- Fn::Split:- '"'- Fn::GetAtt:- WaitCondition- Data

最终能够获取到output

在这里插入图片描述

总结commandrunner的特点如下

  • 便宜,据说短时间的ec2启动费用要小于lambda
  • 灵活,用户自行决定资源的阻塞和依赖
  • 方便,不需要写代码,lambda不能直接执行bash脚本,降低了使用门槛
  • 慢,启动ec2的相比调用lambda慢很多,而且貌似没法进行资源复用
  • 不好排查,因为都是在实例上,需要查日志,而且这个资源类型具体做什么我们看不到

相关错误

(1)waitcondition超时

可能是由于ec2没有权限,ec2网络配置有误,在syslog中能看到相关信息

(2)输出结果无效,cli命令要确保写入到文件中

Resource handler returned message: "Either the command failed to execute, the value written to /command-output.txt was invalid or the Subnet specified did not have internet access. The value written to /command-output.txt must be a non-empty single word value without quotation marks. Check cloud-init.log in the LogGroup specified for more information." (RequestToken: c7ebb7d1-ec0a-43e0-ea18-f13a331fc00d, HandlerErrorCode: NotStabilized)

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
【PdgCntEditor】解... 一、问题背景 大部分的图书对应的PDF,目录中的页码并非PDF中直接索引的页码...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
修复 爱普生 EPSON L4... L4151 L4153 L4156 L4158 L4163 L4165 L4166 L4168 L4...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...