amazon-web-servicesaws-cloudformationaws-security-groupaws-auto-scaling

Setup Network Interfaces in cloudformation for EC2 LaunchTemplate


Goal: Setup EC2 launch template for ASG, with Network interface settings.

Detail: ASG is to be launched in public subnet, and trying to avoid having a public IP.

Example CFN extract

     "NetworkInterfaces": [
      {
       "AssociatePublicIpAddress": false,
       "DeviceIndex": 0,
       "Groups": [
        {
         "Ref": "asgsg123123"
        }
       ]
      }

I checked the related question, but CFN gives me a different error.

Invalid launch template: When a network interface is provided, the security groups must be
a part of it. (Service: AmazonAutoScaling; Status Code: 400; Error Code: InvalidQueryParam
eter;

While through CFN it fails, I tried editing the Launch template in the AWS UI console and it worked, and can compare the template is the same with the CLI

aws ec2 describe-launch-template-versions --launch-template-id lt-123123123 --versions 11 | jq .LaunchTemplateVersions[].LaunchTemplateData.NetworkInterfaces[]
{
  "AssociatePublicIpAddress": false,
  "DeviceIndex": 0,
  "Groups": [
    "sg-123123123"
  ]
}

I did try enforcing the SG ID manually in case the "Ref" function was the problem, but still can not deploy.

Full template to reproduce:

{
 "Parameters": {
  "myvpc" : {
    "Type" : "AWS::EC2::VPC::Id"
  },
  "pubsubnet" : {
    "Type" : "AWS::EC2::Subnet::Id",
    "Description": "Must be in selected VPC!"
  }
 },
 "Resources": {
  "ec2sg": {
   "Type": "AWS::EC2::SecurityGroup",
   "Properties": {
    "GroupDescription": "test asg",
    "SecurityGroupEgress": [
     {
      "CidrIp": "0.0.0.0/0",
      "Description": "Allow all outbound traffic by default",
      "IpProtocol": "-1"
     }
    ],
    "VpcId": { "Ref": "myvpc" }
   }
  },
  "ltemp": {
   "Type": "AWS::EC2::LaunchTemplate",
   "Properties": {
    "LaunchTemplateData": {
     "BlockDeviceMappings": [
      {
       "DeviceName": "/dev/xvda",
       "Ebs": {
        "DeleteOnTermination": true,
        "Encrypted": true,
        "VolumeSize": 8,
        "VolumeType": "gp3"
       }
      }
     ],
     "EbsOptimized": true,
     "ImageId": "ami-0da54bf2af20a74b7",
     "InstanceType": "t3a.nano",
     "Monitoring": {
      "Enabled": true
     },
     "NetworkInterfaces": [
      {
       "AssociatePublicIpAddress": false,
       "DeviceIndex": 0,
       "DeleteOnTermination": true,
       "Groups": [
        {
         "Ref": "ec2sg"
        }
       ]
      }
     ],
     "SecurityGroupIds": [
      {
       "Fn::GetAtt": [
        "ec2sg",
        "GroupId"
       ]
      }
     ],
     "UserData": {
      "Fn::Base64": "#!/bin/bash\n#!/bin/bash -v\nset -euo pipefail\nyum update -y --security"
     }
    }
   }
  },
  "asg": {
   "Type": "AWS::AutoScaling::AutoScalingGroup",
   "Properties": {
    "VPCZoneIdentifier": [{"Ref": "pubsubnet"}],
    "MaxSize": "1",
    "MinSize": "0",
    "DesiredCapacity": "1",
    "HealthCheckGracePeriod": 300,
    "HealthCheckType": "EC2",
    "MixedInstancesPolicy": {
     "InstancesDistribution": {
      "OnDemandAllocationStrategy": "prioritized",
      "OnDemandBaseCapacity": 0,
      "OnDemandPercentageAboveBaseCapacity": 0,
      "SpotAllocationStrategy": "lowest-price",
      "SpotInstancePools": 10,
      "SpotMaxPrice": ""
     },
     "LaunchTemplate": {
      "LaunchTemplateSpecification": {
       "LaunchTemplateId": {
        "Ref": "ltemp"
       },
       "Version": {
        "Fn::GetAtt": [
         "ltemp",
         "LatestVersionNumber"
        ]
       }
      }
     }
    }
   },
   "UpdatePolicy": {
    "AutoScalingScheduledAction": {
     "IgnoreUnmodifiedGroupSizeProperties": true
    }
   }
  }
 }
}

Solution

  • You have to remove your SecurityGroupIds from the AWS::EC2::LaunchTemplate resource. So it should be:

    {
     "Parameters": {
      "myvpc" : {
        "Type" : "AWS::EC2::VPC::Id"
      },
      "pubsubnet" : {
        "Type" : "AWS::EC2::Subnet::Id",
        "Description": "Must be in selected VPC!"
      }
     },
     "Resources": {
      "ec2sg": {
       "Type": "AWS::EC2::SecurityGroup",
       "Properties": {
        "GroupDescription": "test asg",
        "SecurityGroupEgress": [
         {
          "CidrIp": "0.0.0.0/0",
          "Description": "Allow all outbound traffic by default",
          "IpProtocol": "-1"
         }
        ],
        "VpcId": { "Ref": "myvpc" }
       }
      },
      "ltemp": {
       "Type": "AWS::EC2::LaunchTemplate",
       "Properties": {
        "LaunchTemplateData": {
         "BlockDeviceMappings": [
          {
           "DeviceName": "/dev/xvda",
           "Ebs": {
            "DeleteOnTermination": true,
            "Encrypted": true,
            "VolumeSize": 8,
            "VolumeType": "gp3"
           }
          }
         ],
         "EbsOptimized": true,
         "ImageId": "ami-0da54bf2af20a74b7",
         "InstanceType": "t3a.nano",
         "Monitoring": {
          "Enabled": true
         },
         "NetworkInterfaces": [
          {
           "AssociatePublicIpAddress": false,
           "DeviceIndex": 0,
           "DeleteOnTermination": true,
           "Groups": [
            {
             "Ref": "ec2sg"
            }
           ]
          }
         ],
         "UserData": {
          "Fn::Base64": "#!/bin/bash\n#!/bin/bash -v\nset -euo pipefail\nyum update -y --security"
         }
        }
       }
      },
      "asg": {
       "Type": "AWS::AutoScaling::AutoScalingGroup",
       "Properties": {
        "VPCZoneIdentifier": [{"Ref": "pubsubnet"}],
        "MaxSize": "1",
        "MinSize": "0",
        "DesiredCapacity": "1",
        "HealthCheckGracePeriod": 300,
        "HealthCheckType": "EC2",
        "MixedInstancesPolicy": {
         "InstancesDistribution": {
          "OnDemandAllocationStrategy": "prioritized",
          "OnDemandBaseCapacity": 0,
          "OnDemandPercentageAboveBaseCapacity": 0,
          "SpotAllocationStrategy": "lowest-price",
          "SpotInstancePools": 10,
          "SpotMaxPrice": ""
         },
         "LaunchTemplate": {
          "LaunchTemplateSpecification": {
           "LaunchTemplateId": {
            "Ref": "ltemp"
           },
           "Version": {
            "Fn::GetAtt": [
             "ltemp",
             "LatestVersionNumber"
            ]
           }
          }
         }
        }
       },
       "UpdatePolicy": {
        "AutoScalingScheduledAction": {
         "IgnoreUnmodifiedGroupSizeProperties": true
        }
       }
      }
     }
    }