IPV6 address for your EC2 instance

Assigning IPV6 address to an existing EC2 instance

With IPV6 picking up in recent years, it is now more sensible to also have a IPV6 address for your website. If you have one hosted on AWS EC2, you can get an IPV6 address with just a little bit of work. The good news is that working with dual stack VPCs (required for assigning IPV6 address to an instance) is not as difficult as it appears. When you create an IPV4 instance, it is assigned a public ip.

If you want, you can convert to a dual stack instance (IPV4 + IPV6) and add IPV6 addresses.
You can assign an IPV6 address only to dual stack instances (instances that can connect on IPV4 and IPV6). If you have already created an instance and it is in running state, you can still convert it to dual stack and assign IPV6 addressses.
A few things that you will need to edit to accomplish your objective include the VPC, subnet, security groups, and route table. Just head over to the AWS management console and start editing. Apart from adding IPV6 CIDR blocks to your VPS and subnet, you will need to update your route table and security groups. 

Assign IPV6 Address to your EC2 instance via the AWS management console

Edit the VPC (Add IPV6 CIDR Block)

VPC or Virtual Private Cloud is a virtual network that resembles a traditional network and a subnet is a range of IP addresses in your VPC. You can deploy resources in aws after creating subnets. When you create an instance for the first time, it assigns a default VPC. However, the default VPC does not include any IPV6 CIDR block and neither do the subnets in the VPC, which you can add if you need.

In the first step, you need to add an IPV6 CIDR block to your vpc. To do this, go to your AWS management console. Follow the link below to go to VPC:

https://console.aws.amazon.com/vpc/

Now, select the VPC associated with your instance. From the ‘Actions’ dropdown menu on the right at the top, select edit CIDRs. You will see an ipv4 cidr is already associated with your VPC.

Click on add new ipv6 CIDR and select Amazon provided ipv6 CIDR block (as in above figure). Click save.  You have successfully added a new ipv6 CIDR to your VPC. 

Edit the subnet (Add IPV6 CIDR block)


In the first step, you added an ipv6 CIDR block to your VPC. In the second step, you will edit the subnet associated with your instance that you want to assign an IPV6 address to and add ipv6 CIDR to it. Select subnets in the left sidebar and then select the subnet associated with your instance. (You can edit all the subnets in your VPC and add IPV6 CIDR to them). After you have selected a subnet, go to the actions drop down menu on the right at the top and select ‘edit IPV6 CIDRs’.

Now, you can add a new IPV6 CIDR to your subnet. Add 2 hexadecimal digits into the box like 01 or 00 and then click on save. In the next step, we will edit the route table.

Edit route table (Add new route for IPV6)

A route table determines where the network traffic from your subnet or gateway is directed. when you edit route tables to add new routes to connect your VPC to the internet network, you use an internet gateway. A gateway connects your VPC to another network. 

Now, we have to edit the route table and the security group. Open route tables from the left sidebar and then select the route table you want to edit.  Click on edit routes (near the bottom). Add a new route and select ::/0 for destination. For target select internet gateway and it will load the associated target (like igw-067d9e7d). Select the target and then save changes.

Edit security group and add inbound rules for ipv6

We will also need to make some changes to the security groups associated with the EC2 instance we are working upon to enable ipv6 address. Go to the concerned security group and edit the inbound rules first. The system already adds an IPV6 entry for the outbound rules. If there is none, you can add it manually. So, lets first edit the inbound rules and add a rule corresponding to the each rule included in the security group for ipv4 and with ::/0 as the source. 

Assign IPV6 address to your instance


Now, your task is done here and you can go and edit the ip addresses for your instance. Go to the concerned instance and then from the actions dropdown menu go to networking and then click on manage IP addresses. You will see a network interface for eth0 on that page. It looks like: eth0: eni-0e885255aaa6555d – 171.31.15.0/20.


Click on the network interface to expand it and the IPV4 address assigned to your instance will be visible here. It is from here that you can assign additional ipv4 or IPV6 addresses to your instance. While you will see an IPV4 address entry under the IPV4 addresses, there are no entries under the IPV6 addresses. Click on assign new ip address. The system will auto assign an IPV6 address to your instance. Click on save and the system will prompt you to confirm the changes. Click on confirm. You will be back on the instance detail page where you will see the newly assigned IPV6 address.

Create ‘AAAA’ DNS entry/entries in your hosted zone (Route 53) and your site is now available on IPV6.

Assign IPV6 address to an existing EC2 instance using AWS CLI

To assign an IPV6 address to an EC2 instance using the AWS CLI, you first need to have the AWS CLI installed and configured. We will repeat the same process as above but using the AWS CLI. First, we need to associate an IPV6 CIDR block to the VPC and subnet. Then, we will need to edit the route table and security group, following which we will assign an IPV6 address to the instance.

Edit VPC (Add CIDR Block using AWS CLI)

To associate an ipv6 CIDR block to a VPC, you need to have the VPC id. Run the following command to associate the CIDR block to the VPC after replacing the VPC id in the command with your own. If you do not have the vpc id, you ca find it out using the describe-vpcs command:

$ aws ec2 describe-vpcs

Find out the vpc id and then run the following command:


$ aws ec2 associate-vpc-cidr-block --amazon-provided-ipv6-cidr-block --vpc-id vpc-08dd320e3353d1279


The output will look like the following:
{
    “Ipv6CidrBlockAssociation”: {
        “AssociationId”: “vpc-cidr-assoc-0b121e7d9c50620c0”,
        “Ipv6CidrBlockState”: {
            “State”: “associating”
        },
        “NetworkBorderGroup”: “us-east-1”,
        “Ipv6Pool”: “Amazon”
    },
    “VpcId”: “vpc-08dd320e3353d1279”
}
You can see in the above output that the state of the CIDR block is associating. We have associated an IPV6 CIDR block to the VPC and now need to associate one with the subnet. First, we will need the IPV6 CIDR block associated with the VPC. To know the IPV6 CIDR block associated with the VPC, run the describe VPCs command again with the output limited to the particular VPC. 

$ aws ec2 describe-vpcs --vpc-ids vpc-08dd320e3353d1279


You can copy the IPV6 CIDR associated with the VPC from the output.
{
    “Vpcs”: [
        {
            “CidrBlock”: “172.31.0.0/16”,
            “DhcpOptionsId”: “dopt-d6edb4ad”,
            “State”: “available”,
            “VpcId”: “vpc-08dd320e3353d1279”,
            “OwnerId”: “3029854637686”,
            “InstanceTenancy”: “default”,
            “Ipv6CidrBlockAssociationSet”: [
                {
                    “AssociationId”: “vpc-cidr-assoc-09aed97ea277a53da”,
                    “Ipv6CidrBlock”: “2600:1f18:73ce:5400::/56”,     < — IPV6 CIDR
                    “Ipv6CidrBlockState”: {
                        “State”: “associated”
                    },
                    “NetworkBorderGroup”: “us-east-1”,
                    “Ipv6Pool”: “Amazon”
                }
            ],
            “CidrBlockAssociationSet”: [
                {
                    “AssociationId”: “vpc-cidr-assoc-eed35b82”,
                    “CidrBlock”: “172.31.0.0/16”,
                    “CidrBlockState”: {
                        “State”: “associated”
                    }
                }
            ],
            “IsDefault”: true
        }
    ]
}

Associate IPV6 CIDR block to a subnet using AWS CLI


To add IPV6 cidr block to a subnet, you need only the subnet id and the ipv6 cidr block (associated with the VPC). You cannot select any IPV6 CIDR block to associate with your subnet. First, you associate an IPV6 CIDR blck with your VPC and then associate a /64 CIDR block from that same range to each subnet in that VPC. For example, the ipv6 CIDR block associated with the above VPC is 2600:1f18:73ce:5400::/56.

You can associate 2600:1f18:73ce:5400::/64 with a subnet or 2600:1f18:73ce:5408::/64. You can replace the last two zeros in the CIDR block associated with your VPC with a different pair of hexadecimal digits. However, make sure that the block ends with /64. Otherwise, it will not associate with the subnet.


$ aws ec2 associate-subnet-cidr-block --subnet-id subnet-6aa6c844 --ipv6-cidr-block 2600:1f18:73ce:5400::/64

Output :-
{
    “Ipv6CidrBlockAssociation”: {
        “AssociationId”: “subnet-cidr-assoc-0d833a496321c8cde”,
        “Ipv6CidrBlock”: “2600:1f18:73ce:5400::/64”,
        “Ipv6CidrBlockState”: {
            “State”: “associating”
        }
    },
    “SubnetId”: “subnet-6aa6c844”
}
By now, we have added the IPV6 CIDR block to the VPC and subnet. The remaining part includes editing the route table and security groups to enabled internet traffic on IPV6.

Add a rule to route table using AWS CLI


First let’s edit the route table and all that we need to do is to add a route with ::/0 as destination. When we edit the route table and add a new route, we also need the internet gateway associated with our VPC and the route table id. To learn both the values, you can run the describe-route-table command. 

$ aws ec2 describe-route-tables

In the below output, you can see that both the concerned internet gateway and the route table id. Sample output for reference: –
{
            “Associations”: [
                {
                    “Main”: true,
                    “RouteTableAssociationId”: “rtbassoc-6d17013”,
                    “RouteTableId”: “rtb-9e74e1”,
                    “AssociationState”: {
                        “State”: “associated”
                    }
                },
                {
                    “Main”: false,
                    “RouteTableAssociationId”: “rtbassoc-08a77adaef8271417”,
                    “RouteTableId”: “rtb-9e74e1”,
                    “SubnetId”: “subnet-d51732da”,
                    “AssociationState”: {
                        “State”: “associated”
                    }
                }
            ],
            “PropagatingVgws”: [],
            “RouteTableId”: “rtb-9e74e1”,
            “Routes”: [
                {
                    “DestinationCidrBlock”: “172.31.0.0/16”,
                    “GatewayId”: “local”,
                    “Origin”: “CreateRouteTable”,
                    “State”: “active”
                },
                {
                    “DestinationCidrBlock”: “0.0.0.0/0”,
                    “GatewayId”: “igw-067d9e7d”,
                    “Origin”: “CreateRoute”,
                    “State”: “active”
                },
                {
                    “DestinationIpv6CidrBlock”: “2600:1f19:74ce:5400::/56”,
                    “GatewayId”: “local”,
                    “Origin”: “CreateRouteTable”,
                    “State”: “active”
                },
                {
                    “DestinationIpv6CidrBlock”: “::/0”,
                    “GatewayId”: “igw-067d9e7d”,
                    “Origin”: “CreateRoute”,
                    “State”: “active”
                }
            ],
            “Tags”: [],
            “VpcId”: “vpc-36e8574c”,
            “OwnerId”: “302984898886”
        }
Copy the route tabled id and the gateway id and then run the following command to add the new route to your route table:


$ aws ec2 create-route --route-table-id rtb-9e744ee1 --destination-ipv6-cidr-block ::/0 --gateway-id igw-067d9e7d


Upon successful execution the output will be:
{
    “Return”: true
}

Add IPV6 inbound rules to the security groups

Now, we need to modify security group rules to include new inbound rules for ipv6.
Add inbound rules to allow IPV6 traffic on http and https. For example, I have added the rule for port 80 or http traffic below:-


$ aws ec2 authorize-security-group-ingress --group-id sg-080ac0dc18cc8aafd --ip-permissions IpProtocol=tcp,FromPort=80,ToPort=80,Ipv6Ranges="[{CidrIpv6=::/0}]"

You can use the above format to add rules for port 80, 443, 22 or any other port you need.
The output looks like this:-
{
    “Return”: true,
    “SecurityGroupRules”: [
        {
            “SecurityGroupRuleId”: “sgr-0320e01c655ce2a47”,
            “GroupId”: “sg-080ac0dd18cc8aafd”,
            “GroupOwnerId”: “302984898886”,
            “IsEgress”: false,
            “IpProtocol”: “tcp”,
            “FromPort”: 80,
            “ToPort”: 80,
            “CidrIpv6”: “::/0”
        }
    ]
}

Assign IPV6 Address to your instance


Now, we have completed the requirements and it’s time to assign an IPV6 address to our instance. You need your network interface id which you can find using describe-network-interfaces command or;
$ aws ec2 describe-network-interfaces
The output will include the id of the concerned network interface. Pick the network interface id from the output since we will need it for our next command.
Once you have the right network interface id, just run the command to assign ipv6 addresses:

$aws ec2 assign-ipv6-addresses --network-interface-id eni-04ecccc14120 --ipv6-address-count 1

The output will look like the following:
{
    “AssignedIpv6Addresses”: [
        “2600:1f14:72ce:5509:33c2:a001:f3fa:f14c”
    ],
    “NetworkInterfaceId”: “eni-04ecccc14120”
}
You have successfully assigned ipv6 addresses to your EC2 instance.

A few last words :-

To sum up the entire process, you can add an IPV6 address for your instance in four steps. First, you edit the VPC, then the subnet, then the route table and the security group. After having completed these four steps you can assign an IPV6 address to your instance and create the ‘AAAA’ DNS records to make your site available on IPV6. the commands we used to complete the process via aws cli include the following:-

1. Add IPV6 CIDR block to VPC :-

$ aws ec2 associate-vpc-cidr-block --amazon-provided-ipv6-cidr-block --vpc-id vpc-08xxxxxxxxx9

2. Associate IPV6 CIDR block with subnet:

$ aws ec2 associate-subnet-cidr-block --subnet-id subnet-6xxxxxx4 --ipv6-cidr-block 2600:1f18:73ce:5400::/64

3. Add a new route to route table :-

$ aws ec2 create-route --route-table-id rtb-9e744ee1 --destination-ipv6-cidr-block ::/0 --gateway-id igw-06789e7d 

4. Add new inbound rules to the security group :-

$ aws ec2 authorize-security-group-ingress --group-id sg-08xxxxxxxaafd --ip-permissions IpProtocol=tcp,FromPort=80,ToPort=80,Ipv6Ranges="[{CidrIpv6=::/0}]"

Finally, assign an IPV6 address to your instance with the following command:

$ aws ec2 assign-ipv6-addresses --network-interface-id eni-04ecccc14120 --ipv6-address-count 1

That’s all. Thanks for reading!