When working with AWS infrastructure, you'll often need to create similar security groups across different environments (dev/stage/prod) or regions. Manually recreating complex rule sets is time-consuming and error-prone. While AWS doesn't provide a direct "copy" button in the console, there are several programmatic approaches.
The most straightforward method uses AWS CLI to describe the source group and create a new one:
# Describe the source security group
SOURCE_GROUP_ID="sg-12345678"
TARGET_GROUP_NAME="my-cloned-sg"
TARGET_VPC_ID="vpc-87654321"
# Get existing rules
RULES=$(aws ec2 describe-security-group-rules \
--filter Name="group-id",Values=$SOURCE_GROUP_ID \
--query "SecurityGroupRules[].{IpProtocol: IpProtocol, FromPort: FromPort, ToPort: ToPort, CidrIpv4: CidrIpv4, Description: Description}" \
--output json)
# Create new group
NEW_GROUP_ID=$(aws ec2 create-security-group \
--group-name $TARGET_GROUP_NAME \
--description "Cloned from $SOURCE_GROUP_ID" \
--vpc-id $TARGET_VPC_ID \
--output text)
# Apply rules to new group
echo $RULES | jq -c '.[]' | while read rule; do
aws ec2 authorize-security-group-ingress \
--group-id $NEW_GROUP_ID \
--ip-permissions "$rule"
done
For infrastructure-as-code workflows, exporting to CloudFormation provides better version control:
Resources:
ClonedSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Ref TargetGroupName
GroupDescription: "Cloned security group"
VpcId: !Ref TargetVpcId
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
Description: "HTTP access"
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
Description: "HTTPS access"
SecurityGroupEgress:
- IpProtocol: "-1"
CidrIp: 0.0.0.0/0
Description: "Allow all outbound"
For enterprise scenarios requiring cross-account or cross-region copies:
# Assuming proper assume-role permissions are configured
TARGET_ACCOUNT="123456789012"
TARGET_REGION="eu-west-1"
# Assume role in target account
CREDS=$(aws sts assume-role \
--role-arn "arn:aws:iam::$TARGET_ACCOUNT:role/SecurityGroupReplicator" \
--role-session-name "SG-Replication")
export AWS_ACCESS_KEY_ID=$(echo $CREDS | jq -r '.Credentials.AccessKeyId')
export AWS_SECRET_ACCESS_KEY=$(echo $CREDS | jq -r '.Credentials.SecretAccessKey')
export AWS_SESSION_TOKEN=$(echo $CREDS | jq -r '.Credentials.SessionToken')
export AWS_DEFAULT_REGION=$TARGET_REGION
# Now run the create-security-group commands in the new context
- Security group limits apply (60 rules per direction per group)
- VPC peering requires explicit references to peer security groups
- Tags are not automatically copied - add them manually
- For production use, implement error handling in your scripts
For teams preferring GUI tools:
- AWS Explorer in Visual Studio
- Third-party tools like CloudFormation Designer
- Terraform's AWS provider with import functionality
Anyone who's managed AWS infrastructure knows the frustration: you've painstakingly configured a security group with dozens of finely-tuned rules, only to need a nearly identical variant for another environment. Manually recreating these rules is error-prone and time-consuming - especially when dealing with complex setups like:
- Microservices architectures requiring multiple similar groups
- Environment-specific variations (dev/stage/prod)
- Regional deployments needing identical configurations
While AWS doesn't provide direct "clone" buttons, these methods achieve the same result:
1. AWS CLI Copy Method
# Export rules from source group aws ec2 describe-security-groups \ --group-ids sg-0a1b2c3d4e5f6g7h8 \ --query 'SecurityGroups[0].IpPermissions' > inbound.json # Create new group (VPC required) aws ec2 create-security-group \ --group-name "Cloned-SG" \ --description "Cloned from existing SG" \ --vpc-id vpc-12345678 # Apply saved rules to new group aws ec2 authorize-security-group-ingress \ --group-id sg-newgroupid123 \ --ip-permissions file://inbound.json
2. CloudFormation Template Export
Resources: ClonedSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: "Cloned Production SG" SecurityGroupIngress: - IpProtocol: tcp FromPort: 80 ToPort: 80 CidrIp: 0.0.0.0/0 - IpProtocol: tcp FromPort: 443 ToPort: 443 CidrIp: 192.168.1.0/24 VpcId: vpc-12345678
For teams managing hundreds of SGs, consider:
- AWS Console Extensions: Browser plugins that add clone functionality
- Terraform import: Import existing SGs as Terraform state
- Custom Lambda Functions: Automated SG replication across regions/accounts
When copying security groups:
- VPC boundaries matter - can't copy rules between VPCs directly
- Security group references (sg-*) are copied as-is - may need manual adjustment
- Tags aren't automatically copied in native methods
- Always verify new group's rules match your security requirements
For production environments, treat security groups as code:
# Using AWS CDK (TypeScript) const cloneSecurityGroup = (sourceGroupId: string, newGroupName: string) => { const vpc = ec2.Vpc.fromLookup(this, 'VPC', { isDefault: true }); const sourceGroup = ec2.SecurityGroup.fromSecurityGroupId(this, 'SourceSG', sourceGroupId); return new ec2.SecurityGroup(this, newGroupName, { vpc, description: Cloned from ${sourceGroupId}, allowAllOutbound: sourceGroup.allowAllOutbound, securityGroupName: newGroupName }); };