使用AWS CLI启动CloudFormation模板时的可选参数

问题描述:

我正在尝试创建一个将部署Lambda函数的CloudFormation模板,并且我需要将安全性选项作为可选参数。

I'm trying to create a CloudFormation template that'll deploy a Lambda function, And I need the security options to be optional parameters.

我能够使用以下问题来部分完成此任务:

I was able to partially accomplish this using the question here:

How to make a whole object in CloudFormation templates optional?

有趣的是,该方法非常有用,可以使CloudFormation模板中的整个对象成为可选对象? AWS GUI控制台中的VpcConfig属性是可选的,但无法使其对于CLI而言是可选的。不幸的是,我需要它在CLI中工作,因为我将使用CodeBuild来调用和部署此模板的资源。

Interestingly, that method worked great to make the VpcConfig property optional in the AWS GUI Console, but it did NOT work to make it optional for the CLI. And unfortunately, I need it to work in the CLI, since I'll be using CodeBuild to call and deploy this template's resources.

以下是相关参数:

"SecurityGroupIds" : {
   "Type" : "CommaDelimitedList",
   "Description" : "A list of one or more security groups IDs in the VPC that includes the resources to which your Lambda function requires access."
 },
 "SubnetIds" : {
   "Type" : "CommaDelimitedList",
   "Description" : "A list of one or more subnet IDs in the VPC that includes the resources to which your Lambda function requires access."
 }

条件:

    "HasVPC": {"Fn::And": [{"Fn::Not": [{"Fn::Equals": [{"Fn::Join": ["", {"Ref": "SubnetIds"}]}, ""]}]}, {"Fn::Not": [{"Fn::Equals": [{"Fn::Join": ["", {"Ref": "SecurityGroupIds"}]}, ""]}]}]}

这里是在模板的资源部分中定义的Lambda资源中使用该条件的地方:

And here's where that condition is used in the Lambda resource being defined in the Resources section of the template:

"VpcConfig": {
  "Fn::If": [
    "HasVPC",
    {
      "SecurityGroupIds" : {"Ref": "SecurityGroupIds"},
      "SubnetIds" : {"Ref": "SubnetIds"}
    },
    { "Ref":"AWS::NoValue" }
  ]
},

当我在命令行中发出部署此堆栈的命令时,出现以下错误:

When I issue the command to deploy this stack in the CLI, I get the following error:


在调用CreateChangeSet
操作时发生错误(ValidationError):参数:[SecurityGroupIds,SubnetIds]必须具有值

An error occurred (ValidationError) when calling the CreateChangeSet operation: Parameters: [SecurityGroupIds, SubnetIds] must have values

这是我要发出的AWS CLI命令,来自模板所在的同一目录。注意:ARN值已全部修改为不是我帐户中的真实值,但我将它们保留为正确的格式,因此您可以看到命令的真实格式:

Here's the AWS CLI command I'm issuing, from the same directory in which the template is located. Note: the ARN values have all been heavily modified to not be real values from my account, but I kept them in the right format so you can see the real format of the command:

aws cloudformation deploy --template-file lambda-template.json --stack-name "CLI-lambda-stack" --parameter-overrides S3BucketName="myBucket" S3FileLocation="lambda_function.zip" S3ObjectVersion="ZuB0iueEghOyh5q00.DiykLNudujdsc5" DeadLetterArn="arn:aws:sns:us-west-2:577898337216:CloudFormationTests" EnvironmentVariable="testing" KmsKeyArn="arn:aws:kms:us-west-2:504398934246:key/b24e7b72-a94d-6a3e-b848-165115c86212" HandlerFunctionName="lambda_function.lambda_handler" MemorySize="128" Role="arn:aws:iam::102893937243:role/serverless-test-default-us-east-1-lambdaRole" FuncName="myCLILambda"


没有提供 SecurityGroupIds 也没有提供 SubnetIds 默认值,并且您没有在上提供它们- -parameter-overrides 。因此,如果不提供任何值,CloudFormation不知道如何处理它们。

You are not providing SecurityGroupIds neither SubnetIds default values and your are not providing them on your --parameter-overrides. Therefore, CloudFormation doesn't know how to process them if no values are provided.

应添加 Default 语句做到这一点:

Adding the Default statement should do the trick:

{
  "Parameters" : {
    "SecurityGroupIds" : {
      "Type" : "CommaDelimitedList",
      "Description" : "A list of one or more security groups IDs in the VPC that includes the resources to which your Lambda function requires access.",
      "Default" : ""
    },
    "SubnetIds" : {
      "Type" : "CommaDelimitedList",
      "Description" : "A list of one or more subnet IDs in the VPC that includes the resources to which your Lambda function requires access.",
      "Default" : ""
    }
}