- EC2 — Elastic Compute Cloud
- ENI — Elastic Network Interface (AWS — concept)
- NIC — Network Interface Card (General IT — concept)
- NIC = ENI — they are both technically the same. ENI is just how AWS calls it. I often use these interchangeably, but they are the same concept.
The technology used to accomplish this automation tool is:
- AWS Lambda
- Python using Boto3
Although all of these services are very important concepts to achieve automation and devops in AWS cloud environment, I won’t go into a lot of details since it is not the scope of this post. However, I will have some references to Lambda and Boto3 at the end.
Boto3, however, it’s really helpful for executing actions within your AWS environment using Python. The function calls that are used for this tool are: client.describe_instances() and client.describe_network_interfaces().
It is worth mentioning that the code is written to consider a great number of if conditions to execute effectively without any errors. The solution could have been simplified if simpler parameters were to be considered.
Comprehensive guide to develop an automation tool that assigns name tags to Network Interfaces in AWS.
As an example, I deployed 10 EC2 instances with at least 1 NIC associated with these instances to show how this tool works.
Why is this important?
Troubleshooting in the dark is very complicated. When the instance is experiencing networking issues, i.e. instance is not reachable, it’s very important to check the Cloudwatch Logs to see where the packets are getting dropped. Therefore, knowing which ENI you’re looking can simplify the troubleshooting job.
The logic is divided in four major steps:
Step 1: Initial setup
In this step we start to manipulate the powerful library Boto3, which lets us control AWS resources. In addition, we also declare the Create Tag class which will be used for tagging NIC resources attached to EC2 instances.
There are couple of important points to highlight here:
- def lambda_handler(event, context): is required by a lambda function to be executed
- client = boto3.client(‘ec2’): will call the resource EC2 that holds certain attributes
- ec2 = client.describe_instances(): will describe the EC2 instance from the previous line
- Looper variables: will help us iterate through EC2 instances, Tags and NICs. Without them, the logic cannot be accomplished.
- Global variables: will hold the information such as EC2 tag key and value or NIC_ids, which help us assign a name tag to the NIC resource.
Step 2: Pull the EC2 Name Tags from Instances
In this step, we are just pulling the name of the EC2 name tag. From the previous step (ec2 = client.describe_instances()), we will get an attribute that holds all the EC2 instances information. So we iterate through this object, ec2[‘Instances’], to find the name tag for the specific EC2.
Important points to highlight:
- if areThereEC2Tags in instance: checks whether there are tags in the instance. it is important to have this check before proceeding. Otherwise, the code is going to give an error.
- for tags in instance[“Tags”]: will iterate through a loop of EC2 instance tags if previous condition was met.
- if (tags[‘Key’] == ‘Name’): will evaluate if the loop is in the key ‘Name’, where we want to pull the value of the EC2 name tag.
- elif (instance_tag_loop >= len_tags-1): this condition evaluates whether tag iterator has reached the last tag. In case that there are no tags with Key “Name,” then the code creates one.
Note: there are chances where EC2 instances have other tags that are not necessarily ‘Name.’ So this condition applies for such cases.
- ec2_tag_key.append(‘Name’) & ec2_tag_value.append($Value): will assign the key and the value to an array variable
Step 3: Get NIC from EC2 instances
In this step, we are looking for the NIC attached to the Instance for which the current instance_loop is iterating. We store this in a variable and then call another method provided by the boto3.client(‘ec2’) function call in the beginning of Step 1.
- for nic in instance[“NetworkInterfaces”]: will iterate through all the NICs in the specified EC2 instance.
- ec2[‘Instances’], from (for instance in ec2[‘Instance’]), has a property called “NetworkInterfaces.”
- eni_ids.append(nic[‘NetworkInterfaceId’]): will store the NetworkInterfaceId in the global variable for later use.
- ec2_eni = client.describe_network_interfaces(NetworkInterfaceIds=[eni_ids[y]]): will provide us with properties for the selected NIC.
Just as client.describe_instances(), client.describe_network_interfaces() is another method that is provided by the boto3.client(‘ec2’) function call.
- for networkinterfaces in ec2_eni[‘NetworkInterfaces’]: will iterate through the properties of Network Interface. We want to get to the tags property.
Step 4: Assign EC2 name tag to NIC
This step is going to be very similar to Step 2 in the sense that is going to iterate through a set of tags. In this case, it’s going to iterate through the tags belonging to the NIC attached to the EC2 instance. Most importantly, it’s going to assign the value of EC2 Name tag if values are not the same.
Again the important things to consider in this last steps are:
- if (len(networkinterfaces[‘TagSet’]) > 0): will check if there are any tags associated with the NIC
- for nic_tags in networkinterfaces[‘TagSet’]: will loop through the NIC tags
- if (nic_tags[‘Key’] == ‘Name’): will consider the key that are with the ‘Name’
- if (ec2_tag_value[instance_loop] != “”): will check if the instance name tag value is not an empty string
- if(nic_tags[‘Value’] != ec2_tag_value[instance_loop]): will check if the value of the instance name tag is not equal to the NIC name tag. This condition is the most important line of the code
Let me know if you have any questions or suggestions.
I’d be open to chat and exchange knowledge!