Invitation Digital Tech Blog

Building Scalable & Responsive Architecture


Adding existing Security Groups to a new Elastic Load Balancer in AWS

When creating a new Elastic Beanstalk, we sometimes require existing Security Groups to be applied to the Elastic Load Balancer associated with the Elastic Beanstalk. However as it currently stands, there is no easy way in AWS to do this. Sure, once the Elastic Load Balancer has been created, I can go into the AWS console, find the correct Elastic Load Balancer and add the existing Security Groups to this. But this is a manual process and can be forgotten about, potentially leaving the Application unsecure or inaccessible.

Time to break out the PowerShell and get this automated!

To achieve this, we’re going to use .ebextensions to configure our newly created Elastic Load Balancer. For those who haven’t used .ebextensions and the .config files, AWS supplies documentation on the topic in greater detail than I will here.

The actual content of the .config file we are going to run is as follows:

    content: |
      $securitygroups = @("sg-xxxxxxxx", "sg-yyyyyyyy", "sg-zzzzzzzz");
      $instanceid = (New-Object System.Net.WebClient).DownloadString("");
      $availzone = (New-Object System.Net.WebClient).DownloadString("");
      $region = $availzone.Substring(0, $availzone.Length-1);
      $cfstackid = (Get-EC2Instance -Region $region -Instance $instanceid).RunningInstance.Tags | ? { $_.key -eq "aws:cloudformation:stack-id" } |       select -expand Value;
      $elbname = (Get-CFNStackResource -Region $region -StackName $cfstackid -LogicalResourceId "AWSEBLoadBalancer").PhysicalResourceId;
      $elbsc = (Get-CFNStackResource -Region $region -StackName $cfstackid -LogicalResourceId "AWSEBLoadBalancerSecurityGroup").PhysicalResourceId;
      $securitygroups += $elbsc;
      Join-ELBSecurityGroupToLoadBalancer -Region $region -LoadBalancerName $elbname -SecurityGroup $securitygroups;
    command: powershell -ExecutionPolicy RemoteSigned -File .\\set_elb_security_groups.ps1
    cwd: c:\\init_scripts
    waitAfterCompletion: 0

This will add the three existing Security Groups (sg-xxxxxxxx, sg-yyyyyyyy and sg-zzzzzzzz in this example) to the newly created Elastic Load Balancer, as well as leaving the Load Balancer Security Group that is created as part of the Elastic Beanstalk. It is broken into two parts; the files section which is used to create files on an ec2 instance (in our case the PowerShell set_elb_security_groups.ps1 file), and the container_commands section which is used to execute commands (in our case to run the set_elb_security_groups.ps1 file).

If you don’t want the Load Balancer Security Group that is automatically created as part of the Elastic Beanstalk, omit the following lines:

$elbsc = (Get-CFNStackResource -Region $region -StackName $cfstackid -LogicalResourceId "AWSEBLoadBalancerSecurityGroup").PhysicalResourceId;
$securitygroups += $elbsc;

Without these lines, it will then mean that the script will replace any current Security Groups with the ones specified.

Once you have this .config file created (and it is worth noting that any .config files need to confirm to YAML or JSON formatting standards), add it to a .ebextensions directory in the top-level directory of your source bundle. For Visual Studio, .ebextensions needs to be part of the project to be included in your archive, so make sure you have the <Content Include="..." /> entry in your project for the .config file. You can additionally add conditions to this, for example you may only want a particular .config file to run on a Development instance, but not on a Live instance.

Any future Elastic Beanstalks created for the Application will now always have the existing Security Groups listed in your script added to the Elastic Load Balancer. No more manually adding the Security Groups.