
The IP Changed, DNS Didn't: Building an Automated EC2 IP Change Detector with AWS Lambda
Learn how to detect public IPv4 address changes when an Amazon EC2 instance restarts using AWS EventBridge, Lambda, and SNS. This hands-on project demonstrates how to compare IP addresses, send automated alerts, and identify DNS records or application configurations that may need updating. Discover a practical way to reduce connectivity issues and make AWS troubleshooting easier for developers and beginners.
The IP Changed, DNS Didn't: Building an Automated EC2 IP Change Detector with AWS Lambda
1. Introduction
Have you ever hosted a website on Amazon EC2, stopped the instance to save costs, and started it again later, only to discover that your website was no longer accessible?
One possible reason is that your EC2 instance's public IPv4 address has changed.
When an EC2 instance is stopped and started again, its automatically assigned public IPv4 address can change. If your DNS records, application configurations, or other services still reference the previous IP address, your website may become inaccessible.
This can be confusing, especially for students and beginners who are learning AWS networking.
In this project, we will explore how to build an automated EC2 IP change detection system using Amazon EventBridge, AWS Lambda, Amazon DynamoDB, and Amazon SNS.
The goal is simple: detect when an EC2 instance starts, compare its current public IP address with the previously recorded address, and notify the user if the address has changed.
2. The Problem We Are Solving
Imagine hosting a WordPress website on an Ubuntu EC2 instance.
Your website is working correctly, and your DNS record points to the instance's public IP address.
Later, you stop the instance because you are not using it. When you start it again, AWS may assign a different public IPv4 address.
Your DNS record might still point to the old address.
This creates several potential problems:
- Your website may become inaccessible through its domain name.
- DNS records may need updating.
- Application configurations that use the old IP may stop working.
- Beginners may spend time troubleshooting Apache, Nginx, SSL, or networking when the actual issue is an IP address change.
The main problem is not that AWS changes the address. It is that users may not realize that the change happened.
3. The Proposed Solution
We will build a small automated monitoring workflow that detects public IP changes and sends an email notification.
The system will:
- Detect when an EC2 instance enters the running state.
- Retrieve the instance's current public IPv4 address.
- Compare it with the previously recorded address.
- Store the current address for future comparisons.
- Send an email notification if a previously recorded address has changed.
The first time an instance is monitored, the system will save its current IP address as the baseline. It will only report a change when a previous address exists and the new address differs from it.
This project focuses on detection and notification. Automatically updating DNS records can be added as a separate enhancement.
4. AWS Architecture
The project uses four main AWS services.
Amazon EC2: Hosts the application and provides the public IPv4 address that we want to monitor.
Amazon EventBridge: Detects EC2 instance state-change events and triggers the monitoring workflow when an instance enters the running state.
AWS Lambda: Retrieves the current public IP, compares it with the saved value, and determines whether a notification is needed.
Amazon DynamoDB: Stores the previously recorded public IP address for each instance.
Amazon SNS: Sends an email notification when the system detects a change.
How the workflow operates
EC2 instance starts → EventBridge detects the event → Lambda retrieves the current IP → DynamoDB provides the previous IP → Lambda compares the addresses → SNS sends an alert if they differ.
An important implementation detail is that the public IP may not be available immediately when the state-change event arrives. The Lambda function should therefore retry the lookup briefly before deciding that no public address is available.
5. Step 1: Create an SNS Topic
First, create an Amazon SNS topic to receive IP-change notifications.
- Open the Amazon SNS console.
- Select Topics and create a topic.
- Choose the Standard topic type.
- Give it a name such as
EC2-IP-Change-Alerts. - Create the topic and copy its ARN.
- Open the topic's subscriptions section and create an email subscription.
- Enter your email address.
- Open the confirmation email and confirm the subscription.
The email subscription must be confirmed before SNS can deliver notifications to that address.
Keep the topic ARN because we will use it in the Lambda function configuration.
6. Step 2: Create a DynamoDB Table
We need a small database to remember the previous IP address for each EC2 instance.
- Open the Amazon DynamoDB console.
- Create a table named
EC2PublicIPHistory. - Set the partition key to
InstanceId. - Choose the String data type.
- Create the table.
The table will store records similar to this example:
| InstanceId | PublicIP |
|---|---|
| i-example123 | 203.0.113.10 |
The IP shown here is an example address, not a real EC2 instance address.
When the instance starts again, Lambda will compare its current IP with the stored value.
7. Step 3: Create the Lambda Function
Open the AWS Lambda console and create a function named
EC2PublicIPChangeDetector.Choose Python as the runtime and use an execution role with the permissions required to:
- Read EC2 instance details using
ec2:DescribeInstances. - Read and update the DynamoDB table.
- Publish messages to the specific SNS topic.
Use the following environment variables in the Lambda configuration:
TABLE_NAME—EC2PublicIPHistorySNS_TOPIC_ARN— the ARN of your SNS topic.
The Lambda function should use the same AWS Region as the EC2 instance, DynamoDB table, and SNS topic for this example.
Lambda function code
The following example uses the AWS SDK for Python, known as Boto3.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import os
import time
import boto3
from botocore.exceptions import ClientError
ec2 = boto3.client("ec2")
dynamodb = boto3.resource("dynamodb")
sns = boto3.client("sns")
TABLE_NAME = os.environ["TABLE_NAME"]
SNS_TOPIC_ARN = os.environ["SNS_TOPIC_ARN"]
table = dynamodb.Table(TABLE_NAME)
def get_public_ip(instance_id):
# The public IP may not be ready immediately after startup.
for attempt in range(6):
response = ec2.describe_instances(
InstanceIds=[instance_id]
)
reservations = response.get("Reservations", [])
for reservation in reservations:
for instance in reservation.get("Instances", []):
if instance.get("State", {}).get("Name") != "running":
continue
public_ip = instance.get("PublicIpAddress")
if public_ip:
return public_ip
if attempt < 5:
time.sleep(5)
return None
def lambda_handler(event, context):
detail = event.get("detail", {})
if detail.get("state") != "running":
return {"status": "ignored"}
instance_id = detail.get("instance-id")
if not instance_id:
return {"status": "missing_instance_id"}
current_ip = get_public_ip(instance_id)
if not current_ip:
print(f"No public IPv4 address found for {instance_id}")
return {"status": "no_public_ip"}
try:
response = table.get_item(
Key={"InstanceId": instance_id},
ConsistentRead=True
)
previous_item = response.get("Item")
# First observation: save a baseline, without an alert.
if not previous_item:
table.put_item(
Item={
"InstanceId": instance_id,
"PublicIP": current_ip
}
)
print(f"Baseline recorded for {instance_id}: {current_ip}")
return {"status": "baseline_recorded"}
previous_ip = previous_item["PublicIP"]
if previous_ip == current_ip:
print(f"No IP change for {instance_id}")
return {"status": "unchanged"}
# Save the new IP before sending the notification.
table.put_item(
Item={
"InstanceId": instance_id,
"PublicIP": current_ip
}
)
message = (
f"EC2 public IP change detected!\n\n"
f"Instance ID: {instance_id}\n"
f"Previous public IP: {previous_ip}\n"
f"Current public IP: {current_ip}\n\n"
f"Check DNS records, application URLs, and any "
f"configuration that references the previous address."
)
sns.publish(
TopicArn=SNS_TOPIC_ARN,
Subject="EC2 Public IP Address Changed",
Message=message
)
print(message)
return {"status": "ip_changed"}
except ClientError as error:
print(f"AWS service error: {error}")
raiseThis is a basic demonstration implementation. For production use, consider duplicate event delivery, concurrent invocations, retry behavior, monitoring, and failure handling. The code also assumes that the DynamoDB record already represents the last successfully observed address.
8. Step 4: Configure Amazon EventBridge
Now we need to trigger Lambda whenever an EC2 instance enters the running state.
- Open the Amazon EventBridge console.
- Navigate to Rules and create a rule.
- Choose the appropriate event bus.
- Select an event pattern for AWS events.
- Choose EC2 as the source and instance state-change notifications as the event type.
- Configure the rule to match instances entering the
runningstate.
For example, the event pattern can be:
1
2
3
4
5
6
7
{
"source": ["aws.ec2"],
"detail-type": ["EC2 Instance State-change Notification"],
"detail": {
"state": ["running"]
}
}- Set the Lambda function
EC2PublicIPChangeDetectoras the target. - Allow EventBridge to invoke the Lambda function.
- Save and enable the rule.
For a shared AWS account, consider filtering the rule to the particular instance or instances you want to monitor.
9. Step 5: Test the Workflow
Do not assume the system works simply because the resources have been created. Test each part of the workflow.
Test A: First observation
Start the EC2 instance and let EventBridge trigger Lambda.
Expected behavior:
- Lambda retrieves the current public IP.
- DynamoDB records the IP as the baseline.
- No IP-change email is sent.
Test B: Restart the instance
Stop the test instance and start it again.
Wait for the new public IP to become available and allow the event-driven workflow to run.
If AWS assigns a different address, the system should:
- Retrieve the new public IP.
- Compare it with the saved address.
- Update the DynamoDB record.
- Send an SNS email containing the previous and current IP addresses.
If the address remains unchanged, no change notification should be sent.
Test C: Check the logs
Open the Lambda function's monitoring section and inspect its Amazon CloudWatch logs.
Look for messages showing that the baseline was recorded, the IP remained unchanged, or an IP change was detected.
If an alert does not arrive, check the EventBridge rule, Lambda permissions, execution logs, SNS subscription confirmation, and whether the instance has a public IPv4 address.
10. Results and Evidence
Record your actual observations after running the tests.
| Test | Expected result | Actual result |
|---|---|---|
| First observation | Baseline saved | Add your result |
| Restart with same IP | No change alert | Add your result |
| Restart with different IP | Alert sent | Add your result |
| SNS email delivery | Email received | Add your result |
| CloudWatch logs | Workflow activity visible | Add your result |
Include screenshots of the EventBridge rule, DynamoDB record, Lambda logs, and received email. Redact account IDs, email addresses, and other information you do not want to expose.
Do not report a successful IP change or notification unless you observed it during testing.
11. Important Limitations and Improvements
This implementation is deliberately small, but there are several important considerations.
Not every EC2 instance has a public IP. Instances in private subnets may not have one, and an instance can be configured without a public IPv4 address.
DNS changes are not automatic. The workflow identifies a potential problem but does not update Route 53 records. DNS updates could be added with restricted permissions and explicit checks.
An Elastic IP is an alternative. If you need a stable public IPv4 address, an Elastic IP can help. It is important to review the applicable AWS charges and release unused addresses.
Notifications can be duplicated or delayed. Event-driven systems may deliver events more than once. A production implementation should account for duplicate processing and possible race conditions.
The stored IP is only as accurate as the last successful observation. If an instance changes address without the workflow recording the change, a later comparison may not reflect the complete history. Production systems can improve this by storing event metadata, recording successful observations, and handling failures explicitly.
DNS caching can delay the visible effect of a DNS update. Even after a record is changed, clients may continue using cached results until their DNS cache expires.
12. Cost Considerations
This project uses several AWS services, and charges depend on usage, Region, account eligibility, and current pricing.
Before creating resources, review the pricing for Amazon EC2, AWS Lambda, Amazon DynamoDB, Amazon SNS, and Amazon EventBridge. Keep the test environment small and remove resources you no longer need.
Remember that stopping an EC2 instance generally stops its instance compute charges, but attached storage and other resources may continue to incur charges.
13. Conclusion
A small change in an EC2 public IP address can cause confusing connectivity problems when DNS records or application configurations still reference the old address.
By combining EventBridge, Lambda, DynamoDB, and SNS, we can create a simple workflow that detects changes and notifies the user automatically.
This project demonstrates how event-driven automation can improve visibility and reduce manual troubleshooting. It also gives beginners a practical opportunity to understand EC2 networking, DNS, serverless automation, and monitoring in one project.
The larger lesson is that cloud systems become easier to manage when important infrastructure changes are detected, recorded, and communicated rather than left for users to discover manually.
References
- Amazon EC2 User Guide: Public IPv4 addresses and Elastic IP addresses
- Amazon EventBridge User Guide: EC2 instance state-change events
- AWS Lambda Developer Guide: Environment variables and execution roles
- Amazon DynamoDB Developer Guide: Working with items
- Amazon SNS Developer Guide: Sending email notifications
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article