1
votes

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?

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.

Here are the relevant 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."
 },
 "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."
 }

And conditions:

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

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:

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

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"
1

1 Answers

2
votes

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.

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" : ""
    }
}