Updating Security Group with Dynamic IPs from External Application Using AWS Lambda

Updating Security Group with Dynamic IPs from External Application Using AWS Lambda

ยท

3 min read

In this tutorial, we'll explore the process of setting up an AWS Lambda function to automatically update the inbound rules of a security group with IP addresses provided by an external application. We'll cover everything from creating the necessary IAM roles to writing and deploying the Lambda function.

Prerequisites

Before we begin, ensure you have an AWS account and the necessary permissions to create IAM roles, Lambda functions, and manage security groups.

Understanding the Problem

In many scenarios, applications need to communicate with external services whose IP addresses may change dynamically. This creates a challenge when configuring security groups to allow inbound traffic only from specific IP addresses. By using AWS Lambda, we can automate the process of updating security group rules based on the IP addresses provided by the external application.

Solution Overview

We will create an AWS Lambda function that fetches IP addresses from the external application, compares them with the existing security group rules, and updates the security group accordingly.

Step-by-Step Guide

1. Creating IAM Role

We begin by creating an IAM role that grants the Lambda function the necessary permissions to manage security groups. The policy attached to this role should include permissions like ec2:DescribeSecurityGroups, ec2:AuthorizeSecurityGroupIngress, and ec2:RevokeSecurityGroupIngress and basicexecutionpolicy for lambda.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeSecurityGroups",
                "ec2:AuthorizeSecurityGroupIngress",
                "ec2:RevokeSecurityGroupIngress"
            ],
            "Resource": "*"
        }
    ]
}

2. Writing Lambda Function

Let's dive into the Lambda function code. The below code will fetch ip from the external URL and attach all the IPs to the Security Group. You can change the port number and URL as you wish.

import json
import requests
import boto3
import ipaddress
from botocore.exceptions import ClientError
ec2 = boto3.client('ec2')
def lambda_handler(event, context):
    # Getting the security group ID
    security_group_id = 'Your Security Group id'
    # Getting security group rules.
    group_rules = ec2.describe_security_group_rules(Filters=[{'Name': 'group-id', 'Values': [security_group_id]}], MaxResults=1000)
    # Storing security group rules id in rule_ids variable.
    rule_ids = [rule['SecurityGroupRuleId'] for rule in group_rules['SecurityGroupRules']]
    # Deleting previous ingress rules of security group.
    for rule_id in rule_ids:
        try:
            ec2.revoke_security_group_ingress(GroupId=security_group_id, SecurityGroupRuleIds=[rule_id])
        except ClientError:
            continue
    # Getting IP addresses from the provided URL
    response = requests.get('https://stripe.com/files/ips/ips_webhooks.json')
    ips_data = response.json()
    webhook_ips = ips_data['WEBHOOKS']
    cidr_blocks = [f"{ip}/32" for ip in webhook_ips]
    # Authorize inbound traffic for each IP address in webhook block.
    for cidr_block in cidr_blocks:
        try:
            ipaddress.IPv4Network(cidr_block)
            ip_permission = {
                'IpProtocol': 'tcp',
                'FromPort': 80,
                'ToPort': 80,
                'IpRanges': [{'CidrIp': cidr_block, 'Description': 'Stripe IP'}]
            }
        except ValueError:
            ip_permission = {
                'IpProtocol': 'tcp',
                'FromPort': 80,
                'ToPort': 80,
                'Ipv6Ranges': [{'CidrIpv6': cidr_block, 'Description': 'Stripe IP'}]
            }
        try:
            ec2.authorize_security_group_ingress(GroupId=security_group_id, IpPermissions=[ip_permission])
        except ClientError:
            continue
    return {
        'statusCode': 200,
        'body': json.dumps('The security group ingress rules have been successfully updated with the latest IP addresses of Stripe services')
    }

Conclusion

In this tutorial, we've explored how to create an AWS Lambda function to automatically update the inbound rules of a security group with IP addresses provided by an external application. By leveraging Lambda functions, we can automate the process of managing security groups, ensuring that our applications stay secure while allowing dynamic access from external services.

Did you find this article valuable?

Support NavyaDevops by becoming a sponsor. Any amount is appreciated!

ย