Understanding Security Groups with AWS CloudFormation: A VPC with Bastion Hosts and Private Instances

Daniel HerDaniel Her
3 min read

AWS CloudFormation simplifies infrastructure as code, making it easier to deploy complex environments consistently. In this blog, we'll design and deploy a Virtual Private Cloud (VPC) using CloudFormation that spans two Availability Zones (AZs). This setup will emphasize security by exploring security groups, proper configuration, and secure access workflows.


Architecture Overview

The CloudFormation template will create the following resources:

  1. VPC: A secure virtual network with isolated subnets.

  2. Public Subnets: One in each AZ, hosting bastion hosts.

  3. Private Subnets: Two sets per AZ, hosting application instances.

  4. Security Groups: Fine-tuned rules to control traffic between a bastion host and a private instance.

  5. Internet Gateway: To allow bastion hosts to connect to the internet.


Security Use Case

We'll demonstrate:

  • SSH Access: Use bastion hosts in public subnets to SSH into private instances.

  • Inter-AZ Communication: Ping the private instance in the other AZ.

  • Restricted Internet Access: Allow private instances to connect to the internet via the bastion host while blocking inbound traffic.


Key Security Group Configuration

  1. Bastion Hosts Security Group:

    • Allow inbound SSH traffic (port 22) from your IP range.

    • Allow outbound SSH traffic to private instances (port 22).

  2. Private Instances Security Group:

    • Allow inbound SSH traffic only from bastion hosts.

    • Allow inbound ICMP (ping) traffic from instances in the other AZ.


Deploying the Environment

Step 1: Create the CloudFormation Template

Here’s a snippet of the CloudFormation YAML for this setup specifically regarding security group configuration:

Bastion Host Security Group

This security group allows SSH access to the bastion host from your public IP and enables it to connect to private instances via SSH.

BastionSG:
  Type: AWS::EC2::SecurityGroup
  Properties:
    GroupDescription: "Allow SSH access to the bastion host"
    VpcId: !Ref VPC
    SecurityGroupIngress:
      - IpProtocol: tcp
        FromPort: 22
        ToPort: 22
        CidrIp: # Replace with your public IP

Private Instance Security Group

This security group restricts access to private instances, allowing only SSH from the bastion host and ICMP traffic (ping) from other private instances.

PrivateInstanceSG:
  Type: AWS::EC2::SecurityGroup
  Properties:
    GroupDescription: "Allow SSH and ICMP traffic for private instances"
    VpcId: !Ref VPC
    SecurityGroupIngress:
      - IpProtocol: tcp
        FromPort: 22
        ToPort: 22
        SourceSecurityGroupId: !Ref BastionSG  # SSH only from bastion
      - IpProtocol: icmp
        FromPort: -1
        ToPort: -1
        CidrIp: # Include private IP from other instance

Step 2: Deploy the Template

  1. Save the template as vpc.yaml.

  2. Use the AWS CLI or Management Console to deploy:

     aws cloudformation create-stack --stack-name vpc-stack --template-body file://vpc.yaml
    

Step 3: Testing Security Group Configuration

  1. SSH into Bastion Host:

     ssh -i bastion.pem ec2-user@<bastion-public-ip>
    
  2. SSH into Private Instance: From the bastion host:

     ssh -i bastion.pem ec2-user@<private-instance-ip>
    
  3. Ping the Other AZ Instance: From the private instance:

     ping <private-instance-ip-in-other-az>
    

Security Best Practices

  1. Restrict SSH Access: Always limit SSH access to specific IPs using CIDR blocks (e.g., x.x.x.x/32).

  2. Avoid Overly Permissive Rules: Ensure security groups only allow the minimum required traffic.

  3. Use Bastion Hosts: Never open SSH access directly to private instances or databases.


Final Thoughts

This project demonstrates how CloudFormation can create robust VPCs while maintaining a security-first approach. By understanding and properly configuring security groups, you can ensure secure communication between resources without exposing your environment unnecessarily.

What other networking or security challenges have you faced with AWS? Let me know in the comments!

0
Subscribe to my newsletter

Read articles from Daniel Her directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Daniel Her
Daniel Her