Amazon web services 在UserData中实现If函数
我试图理解是否可以在UserData中使用if函数。当我使用下面的CloudFormation模板时,一切都按预期执行Amazon web services 在UserData中实现If函数,amazon-web-services,amazon-cloudformation,Amazon Web Services,Amazon Cloudformation,我试图理解是否可以在UserData中使用if函数。当我使用下面的CloudFormation模板时,一切都按预期执行 Type: 'AWS::EC2::Instance' Properties: <OMIT> BlockDeviceMappings: - DeviceName: /dev/sda1 Ebs: VolumeSize: 50 - !If [Volu
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>
我在引用时找不到任何语法问题。我的场景的唯一解决方案是将条件应用于此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
查看验证模板时发生的情况:
$ 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参数。谢谢,这让我走上了正确的方向。我在powershell脚本中使用了定义变量的相同逻辑,并使用powershell语法执行了if语句。它现在工作正常。
$ 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
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
}
]
}