如何解决在 UserData 中实现 If 函数
我想了解是否可以在 UserData 中使用 If 函数。当我使用下面的 CloudFormation 模板时,一切都按预期执行。
Type: 'AWS::EC2::Instance'
Properties:
<OMIT>
BlockDeviceMappings:
- DeviceName: /dev/sda1
Ebs:
VolumeSize: 50
- !If [VolumeCreationCondition,{DeviceName: xvdh,Ebs:{VolumeSize: 150,VolumeType: st1}},!Ref AWS::Novalue]
UserData:
!Base64 |
<powershell>
Install-WindowsFeature Net-Framework-Core;
Initialize-disk 1;
New-Partition -diskNumber 1 -AssignDriveLetter -UseMaximumSize | Format-Volume -FileSystem NTFS -NewFileSystemLabel Video;
& "C:\Program Files\Amazon\AmazonCloudWatchAgent\amazon-cloudwatch-agent-ctl.ps1" -a fetch-config -m ec2 -s -c ssm:WindowsAgentConfig
</powershell>
但是,当我引入 2 个新的 If 条件时,不会执行单个 PowerShell 命令。
Type: 'AWS::EC2::Instance'
Properties:
<OMIT>
BlockDeviceMappings:
- DeviceName: /dev/sda1
Ebs:
VolumeSize: 50
- !If [VolumeCreationCondition,!Ref AWS::Novalue]
UserData:
!Base64 |
<powershell>
Install-WindowsFeature Net-Framework-Core;
!If [VolumeCreationCondition,Initialize-disk 1;,!Ref AWS::Novalue]
!If [VolumeCreationCondition,New-Partition -diskNumber 1 -AssignDriveLetter -UseMaximumSize | Format-Volume -FileSystem NTFS -NewFileSystemLabel Video;,!Ref AWS::Novalue]
& "C:\Program Files\Amazon\AmazonCloudWatchAgent\amazon-cloudwatch-agent-ctl.ps1" -a fetch-config -m ec2 -s -c ssm:WindowsAgentConfig
</powershell>
VolumeCreationCondition
没有问题,因为它在这里工作正常。
!If [VolumeCreationCondition,!Ref AWS::Novalue]
我在引用 AWS Condition functions 时找不到任何语法问题。将条件应用于此 EC2 资源是我的方案的唯一解决方案吗?这并不理想,因为我还有其他几个资源引用了这个 EC2,这意味着我也必须对所有这些资源实施条件。
解决方法
您不能在 PowerShell 脚本中使用 CloudFormation IF
语句。
实际上在任何 userdata
脚本中。
我不了解 PowerShell,但我会告诉你如何用 Bash 做你想做的事。只需遵循相同的方法即可。
Type: 'AWS::EC2::Instance'
Properties:
<OMIT>
BlockDeviceMappings:
- DeviceName: /dev/sda1
Ebs:
VolumeSize: 50
- !If [VolumeCreationCondition,{DeviceName: xvdh,Ebs:{VolumeSize: 150,VolumeType: st1}},!Ref AWS::NoValue]
UserData:
Fn::Base64: !Sub |
#!/bin/bash
export need_to_init="${VolumeCreationCondition}"
if [[ "${need_to_init}" != "" ]]
then
# "Run your command to init disk here"
fi
您不能直接在用户数据脚本中使用 CloudFormation 条件。
请参阅下面尝试使用它的示例。
Parameters:
Production:
Type: String
Default: ''
Conditions:
CreateProdResources: !Not [!Equals [!Ref Production,'']]
Resources:
CloudNetPingTargetInstance:
Type: AWS::EC2::Instance
Properties:
InstanceType: t2.micro
ImageId: amzn2-ami-hvm-2.0.20210427.0-x86_64-gp2
NetworkInterfaces:
- DeviceIndex: '0'
DeleteOnTermination: true
SubnetId: subnet-11111c86
UserData:
Fn::Base64: !Sub |
#!/bin/bash
export PRODUCTION="${CreateProdResources}"
if [[ "$PRODUCTION" != "" ]]
then
echo "##### IS PRODUCTION"
fi
看看当我们验证模板时会发生什么:
$ aws cloudformation validate-template --template-body file://test.yaml
An error occurred (ValidationError) when calling the ValidateTemplate operation: Template format error: Unresolved resource dependencies [CreateProdResources] in the Resources block of the template
但是您可以在脚本中执行与 CloudFormation 条件相同的逻辑。见下文。
Parameters:
Production:
Type: String
Default: ''
Conditions:
CreateProdResources: !Not [!Equals [!Ref Production,'']]
Resources:
CloudNetPingTargetInstance:
Type: AWS::EC2::Instance
Properties:
InstanceType: t2.micro
ImageId: amzn2-ami-hvm-2.0.20210427.0-x86_64-gp2
NetworkInterfaces:
- DeviceIndex: '0'
DeleteOnTermination: true
SubnetId: subnet-11111c86
UserData:
Fn::Base64: !Sub |
#!/bin/bash
export PRODUCTION="${Production}"
if [[ "$PRODUCTION" != "" ]]
then
echo "##### IS PRODUCTION"
fi
现在当我验证时,它起作用了。
$ aws cloudformation validate-template --template-body file://test.yaml
{
"Parameters": [
{
"ParameterKey": "Production","DefaultValue": "","NoEcho": false
}
]
}
诀窍是使用 CloudFormation Sub
函数创建一个带有 CloudFormation 参数值的脚本变量。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。