Security Group and Network Access Control List Migration between different VPCs

By 11/27/2018 December 3rd, 2018 No Comments

Few Words of Introduction

Our everyday work often finds us with situations when we need to recreate identical environments in a virtual (VPC) network in an AWS cloud.

In this article, I would like to share our experiences and focus on two basic elements such as Security Groups and Network Access Control List. Both the elements are a part of a virtual network in the AWS Cloud and revolve around the secure access to VPC services. You could call them the first and second line of security, the details are listed below:

Security Group Network Access Control List
Stateful – the incoming traffic is allowed by default Stateless – specific rules are required to allow incoming traffic
It operates on the level of an instance: one group can be assigned to multiple instances or multiple groups can be assigned to a single instance It operates on the subnet level: one ACL Network can be assigned to a single subnet or to multiple subnets
Only ‘allow’ rules are controlling the traffic Both ‘allow’ and ‘deny’ rules are controlling the traffic
Complete set of rules is analyzed, and the analysis of the rules dictates if access is allowed Rules are analyzed in the order of their ids and then applied
Rules are activated now when the group is assigned (at the time of startup or on an active instance) Rules are activated instantly after assigning to a subnet

The diagram below shows when the Security Group and Network ACL are used in the communication:

But what’s it all for?

Usually, to simplify and automate the SG and NACL migration process between different AWS accounts or regions. Unfortunately, at present, we only have the ability to copy SG in a single region and a single account to the same or different VPC.

To execute such an operation, you need to:

  1. Mark the group you want to copy in the EC2 servicein the Security Groups section,
  2. Pick Actions and then Copy to new in the menu

    3. Next window shows automatic rules from the previous SG and all you need to pick is the VPC and set the name and description of the new group.

Keeping in mind that this is still being done for a single region and a single account, it does not make thing simple for the migration process or cloning of a given environment.

Ok, so how did we do it?

We wrote a tool in Python which uses the Boto3 library and, trough the AWS API access, we were able to simplify the migration of Security Groups and Network Access Control Lists. Our script, depending on the scenario, connects to one or two AWS accounts and automatically copies SG and NACL.

We incorporated two authorization methods which are used during the awscli configuration:

  • using a pair of keys (Access Key, Secret Access Key),
  • using IAM role trough providing a unique

Using one of the above methods we prepared a profile configuration of the access account, depending on either of the scenarios:

  • single AWS account migration – one profile,
  • two different AWS accounts – two profiles (scrProfileA, dstProfileB).

Profiles should be placed in the correct configuration files (the localization are for the following operating systems: Linux, OS X, Unix, while for Windows it is: %UserProfile%\.aws ):

  • ~/.aws/credentials







  • ~/.aws/config
[profile srcProfileA]


[profile dstProfileB]


[profile srcProfileRoleA]

role_arn = arn:aws:iam::123456789012:role/adminA

region = eu-west-2

source_profile = default

[profile dstProfileRoleB]

role_arn = arn:aws:iam::123456789021:role/adminB

region = us-east-1

source_profile = default

While using MFA for IAM accounts, you need to add the mfa_serial parameter to a given section

Having a configured access from our workstation / instance, we can use our tool to execute the migration of SG or NACL, for instance:

  1. copying SG using srcProfileA and dstProfileB profiles:
python –sg_migration –aws_src_profile srcProfileA –aws_dst_profile dstProfileB –sg_id SG_ID –aws_dst_vpc DST_VPC_ID

As a result, the target VPC obtains the same security group as the source one.  Additionally, there is a possibility of doing a search in all the groups by tag and migrating all the selected ones at the same time. 

  1. copying NACL using roles on the source and target account:
python -sr arn:aws:iam::SRC_ACCOUNT_ID:role/ROLE_NAME -dr arn:aws:iam::DST_ACCOUNT_ID:role/ROLE_NAME –region AWS_SOURCE_REGION –dstregion AWS_DESTINATION_REGION –nacl_migration –aws_dst_vpc VPC_DESTINATION_ID –srcnacl_id SOURCE_NACL_ID


As a result, the target account will have Network Access Control List with a set of rules for incoming and outgoing traffic, same as the source one. If we want to assign it to appropriate subnets on the target account, then we need to add the srcnacl_id_association parameter and provide the id of the current NACL subnet arrangement.

So, what did we achieve?

Automation of the migration process: thanks to our solution we do not have to manually repeat the same activities, and the time needed to execute such a migration decreased a few times over.  Another major benefit of implementing this solution into the migration process or cloning process, is eliminating human errors that had a tendency to appear after the process was finished. The errors were either incorrect rules or lack of rules altogether. While using this solution on a daily basis, we also noticed its benefits for the programming environments, where CloudFormation plays a major role. It erects a base infrastructure while the script syncs specified SG and NACL from a specified VPC, without the need for cyclical updates of many environments via templates of the CloudFormation