6 Steps to Configure CloudFormation Security Groups
Updated September 30, 2024.
Convenience often comes with a catch. While AWS CloudFormation simplifies infrastructure deployment, misconfigured Security Groups can expose your environment to critical vulnerabilities, such as overly permissive rules.
The numbers tell the story: 95% of AWS principals are granted excessive privileges. But the problem isn’t just sloppy permissions. Unrestricted ports and unencrypted data also put your AWS environment at risk for compliance failures, data breaches, and system exploits.
As cloud infrastructure grows more complex, even minor misconfigurations in CloudFormation Security Groups can lead to massive exposure for your organization. With all this at stake, it’s safer to properly configure CloudFormation Security Groups from the get-go.
What Are AWS CloudFormation Security Groups?
AWS CloudFormation is an Infrastructure as Code (IaC) tool that automates the provisioning of AWS resources. You can streamline everything from EC2 instances to networking components while keeping the infrastructure version-controlled and scalable.
Security Groups in AWS act as virtual firewalls, providing granular control over your cloud resources' inbound and outbound traffic. They follow a strict "deny all" model, meaning you must explicitly define which traffic is allowed based on IP addresses, protocols, and ports. By default, a new security group allows all outbound traffic but denies all inbound traffic.
However, you must configure Security Groups correctly to avoid misconfiguration vulnerabilities, such as having too many open ports or overly broad IP ranges, which can introduce significant security gaps. Instead of manually configuring your infrastructure, you can define it using CloudFormation templates that consistently deploy and manage resources across your environments.
CloudFormation templates allow you to define Security Groups as code, enabling consistent and repeatable deployment of these virtual firewalls across your AWS infrastructure. This integration means you can version control your security configurations and deploy them alongside other resources.
6 Steps to Configure CloudFormation Security Groups
1. Access the CloudFormation Template
The AWS Management Console makes it easy to create and manage your CloudFormation templates visually:
Go to the AWS CloudFormation section of the console.
Click Create Stack or Design Template to start building or uploading a template.
If you’re working from a previously deployed stack, you can select an existing stack, click Template, and view or download the template used to create that stack.
Many organizations store their CloudFormation templates in version control systems like Git. In this scenario, you can clone the repository to your local machine to access the template files.
2. Define the Security Group in the CloudFormation Template
Define a Security Group in your CloudFormation template using the AWS::EC2::SecurityGroup resource type. This resource lets you control your AWS resources' inbound and outbound traffic, particularly within your Virtual Private Cloud (VPC).
Here's a basic example:
Resources:
MySecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow HTTP and SSH traffic
VpcId: vpc-123456
The VpcId property is crucial as it specifies which Virtual Private Cloud (VPC) the Security Group will be associated with. This ensures that the Security Group's rules only apply to resources within the specified VPC, maintaining network isolation and security.
3. Set Up Ingress (Inbound) Rules
To configure inbound (ingress) traffic rules, you define the SecurityGroupIngress property. Here’s how you might specify an ingress rule in your template:
Properties:
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 203.0.113.0/32 # EXAMPLE IP (Replace with your trusted IP range)
In this example, SSH access (on TCP port 22) is restricted to a hypothetical trusted IP address (203.0.113.0/32). This is a best practice because it restrains access to known sources, limiting cyber risk. Avoid using 0.0.0.0/0 (which allows access from any IP) unless necessary and closely monitored.
4. Set Up Egress (Outbound) Rules
Configuring the SecurityGroupEgress property controls the traffic leaving your AWS resources. Here’s how you should define a secure egress rule:
Properties:
SecurityGroupEgress:
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
This rule allows HTTPS traffic (TCP port 443) to any destination (0.0.0.0/0). While limiting outbound traffic can be part of a zero-trust architecture, it's important to note that AWS Security Groups allow all outbound traffic by default. Explicitly defining outbound rules is an additional security measure. You can tighten this further by specifying trusted IP ranges or endpoints to reduce the risk of unauthorized external connections.
5. Reference Parameters for Dynamic Values
To make your CloudFormation templates more flexible, you can use parameters to inject dynamic values. These parameters allow you to reuse the same template across different environments or regions simply by passing different parameter values during deployment. You reference these parameters using the !Ref intrinsic function.
In this example:Parameters:
MyVpcId:
Type: String
Description: VPC ID for the security group
Resources:
MySecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow HTTPS traffic
VpcId: !Ref MyVpcId
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: !Ref TrustedIpRange
Outputs:
SecurityGroupId:
Description: The security group ID
Value: !Ref MySecurityGroup
VpcId: !Ref MyVpcId dynamically references the VPC ID passed as a parameter during stack creation.
CidrIp: !Ref TrustedIpRange allows you to specify a trusted IP range as a parameter, making the template adaptable for different environments.
Outputs: This section returns the security group ID, which helps reference it in other templates or scripts.
Using parameters in your CloudFormation templates offers several benefits:
Reusability: The same template can be used across different environments by changing parameter values.
Flexibility: You can easily update specific values without modifying the entire template.
Security: Sensitive information can be passed as parameters rather than hardcoded in the template.
6. Add Security Group to EC2 Instance or Resource
To associate a Security Group with an EC2 instance (or any other resource that supports security groups), you'll reference the Security Group in the resource definition within your CloudFormation template. This binds the Security Group's rules to the instance, controlling inbound and outbound traffic for that resource.
You can attach multiple Security Groups by adding additional IDs under SecurityGroupIds.Resources:
MySecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow HTTPS traffic
VpcId: !Ref MyVpcId
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: !Ref TrustedIpRange
MyEC2Instance:
Type: AWS::EC2::Instance
Properties:
InstanceType: t2.micro
ImageId: ami-0abcdef1234567890
SecurityGroupIds:
- !Ref MySecurityGroup
SubnetId: !Ref MySubnetId
7. Validate and Deploy the CloudFormation Template
Before deploying, it's essential to validate your CloudFormation template to catch syntax errors:
aws cloudformation validate-template --template-body file://path-to-your-template.yaml
After validation, you can deploy the stack in one step using the AWS CLI.
Please note that before deploying to your production environment, it's crucial to test your CloudFormation template in a non-production environment. This allows you to verify that the Security Groups and associated resources are configured correctly and traffic is allowed as expected without risking your live environment. Once tested, you can confidently deploy to production using the following command:
aws cloudformation create-stack --stack-name my-stack --template-body
file://path-to-your-template.yaml --parameters
ParameterKey=VpcId,ParameterValue=vpc-123456
ParameterKey=TrustedIpRange,ParameterValue=203.0.113.0/32
Best Practices to Secure CloudFormation Security Groups
Over time, as your CloudFormation Security Groups expand and become more intricate, maintaining best practices can get challenging. With numerous rules and groups, losing track of each rule’s intent is easy without real-time visibility. This lack of oversight can lead to mistakes like overly permissive configurations and unnoticed unauthorized changes, leaving your cloud infrastructure vulnerable.
Manually auditing security groups is time-consuming and prone to error, especially in large-scale environments where many security groups exist across multiple resources. It’s nearly impossible to keep up without automation.
Jit tackles these problems head-on by plugging straight into your CI/CD pipelines, making sure your CloudFormation Security Groups follow best practices and meet compliance requirements. With integrations like KICS and Kubescape, Jit automates security scans to catch gaps like open ports or unencrypted storage before they pose serious threats. Real-time monitoring and instant alerts call out misconfigurations as they happen, while automated policy enforcement locks down your security groups and aligns them with industry standards.
Automate CloudFormation Security with Jit
CloudFormation Security Groups are your first line of defense, but risks can slip through unnoticed without careful setup and consistent monitoring. Outdated rules, unchecked traffic, and missed audits can quietly weaken your security – and you might be none the wiser until it's too late.
Now that you’ve got a handle on setting up secure CloudFormation Security Groups, you can automate ongoing checks and balances with Jit.
The ASPM platform integrates directly into your GitHub workflows, bringing tools like KICS and Kubescape to scan for security issues in your CloudFormation environment. Plus, it automates enforcement and provides real-time monitoring, flagging any mistakes or unauthorized changes the moment they happen. Discover more.