Finding unused Elastic IP's and notifying on email using publish SNS
Tags: aws, lambda, boto3, devops
Published: 2023-11-24 08:48:56

**Overview**

When it comes to saving cost in cloud, finding unused resources and deleting them becomes a tedious task. Hence finding those resources and getting information only of those unused resources at one place is first thing to carry out. Once you have required information, then deleting them should be done carefully.

With the help of AWS resources this can be achieved without manual intervention, exception that you define and validate code written in Lambda function before deploying. This will help to control occuring costs and cut on them. As cost will be incurred only when Lambda function triggers, approximately 50% cost reduction can be achieved using this stratergy. Since this is an automated process, you only need to provision Lambda function once using Amazon boto3 methodology.


![case](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qiyarxvsidohmo7xmmdv.png)

**Requirements**

- Knowledge on how to write Lambda function

- Associate SNS, EC2 permissions for your Lambda IAM role

- Good understanding of Elastic IPs and its association

- Using Amazon boto3 official documentation, Python scripting(OOPS not required)

- Creating Amazon SNS Topic, Subscriptions, how to write customized rules in Amazon EventBridge 

**Methodology**

Lets go ahead and create Lambda function. 

- Navigate to AWS Management Console. Login in to your account, search for Lambda service in searchbar. Goto Lambda and click on Create function. You should be right on this page.

![lambda_fun_creation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wopo80ua9lbtxe46o8s1.jpg)

Give a meaningful, distinguishing name for your Function name. Choose **Author from scratch**. I have chosen **Python 3.11** as Runtime because I'm comfortable in scripting code in Python. You can choose and available languages from dropdown, not necessary to use Python. You can use existing IAM role for Lambda function if you have created earlier, else Lambda will create one for you. Keep rest of things as default, as I dont want to go in depth of function creation in Lambda. Now, click on Create function. You can use above image for reference and also can find more information on how to Create function [here](https://docs.aws.amazon.com/lambda/latest/dg/getting-started.html).

- Great! Now that you have created Lambda function, lets develop code. I have used AWS official boto3 documentation for reference and to input required attributes. You can visit boto3 documentation [here](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ec2/client/describe_addresses.html). Check the code below for reference. 
![lambda_code](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/19aqw6sn2fsw8n57ollo.png)
I have validated this code multiple times which you will also have to do on your end. Enter your own **Topic ARN** once created.You need to change variables, again use meaningful, simple, understandable variables in your code. You can customize your code as per your requirement.

```
import json,boto3

def lambda_handler(event, context):
    eips = boto3.client("ec2")
    sns_console = boto3.client("sns")
    result = eips.describe_addresses()
    eip_addresses = result['Addresses']
    for each_ip in eip_addresses:
        alloc_id = result['Addresses'][0]['AssociationId']
        print("Associated Elastic IPs are:\t", alloc_id)
        if alloc_id == 0:
            unused_eip = result['Addresses'][0]['AllocationId']
            print("Unused Elastic IPs are:", unused_eip)
        else:
            inst_id = result['Addresses'][0]['InstanceId']
            print("No unused Elastic IPs found, all are associated to instances\t",inst_id)
    sns_email = sns_console.publish(
        TopicArn = 'Your_sns_arn',
        Message = '\t\t*******************IMPORTANT**************************\n' + '\nList of Unused Elastic IPs are:\n\n' +
        '\nNo unused Elastic IPs found, all are associated to instances:\n' + inst_id + 
        '\n\n\n\t\t********Make sure to delete Unused EIPs to avoid incurring costs********'
        )
    # TODO implement
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }
```

- Lets quickly create SNS topic. Goto searchbar of console, enter SNS. Click on it.
![topic_creat](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1fxwq05iphjdrsqbys8z.jpg) 
Enter meaningful Topic name. After creating it, choose **Type-Standard** as we want this trigger to happen everytime. FIFO will send email only once. Enter meaningful Display name(this will be the **same** name displayed as email subject.  Click on create.

- Once done with Topic creation, go to subscriptions, you can choose it from left pane list. Choose Topic ARN from dropdown. I have chosen Protocol as **Email**, you can choose any other as per your requirement. **Endpoint** will be that email address on which you want to receive email alert. More detailed information can be found on Topic creation [here](https://docs.aws.amazon.com/sns/latest/dg/sns-create-topic.html) and [here](https://docs.aws.amazon.com/sns/latest/dg/sns-create-subscribe-endpoint-to-topic.html) for subscriptions.

- Lastly, we will create **Eventbridge rule** using **Scheduler** to trigger this Lambda event after specific intervals. 

![event_creation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7ko5hpxb9rsyommmjqov.jpg)

- Goto searchbar and type, Eventbridge. In left side panel, select Rule. I have used Scheduler to create rule. Give suitable Schedule name, description if you want. For Schedule group you can make a choice of your own. I have used **Recurring** schedule as I want this event to be triggered repeatedly. You can use Cron-based schedule or Rate-based schedule. Choose Flexible time window, Time zone specify start date, end date and click on Next.
![event_last](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/52vhw4t7pc6da2srnmox.jpg) 

- Select **Target** as **Lambda function** created earlier, it will look for targets specified and invoke Lambda function. More detailed steps can be found [here](https://docs.aws.amazon.com/scheduler/latest/UserGuide/getting-started.html#getting-started-console).I'm not going in depth on how to Schedule event as my intention is to deliver on how to cut on costs using Lambda function, writing code using boto3 and getting notified when triggered. You can also use [Crontab.guru](https://crontab.guru/) for reference on writing Crontab expression.

- Additionally you can find all logs in Cloudwatch, provided that you have already chosen to **monitor logs** during Lambda function creation.
![cloudwatch](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kg1bl0ja1afm4yyubizl.png)

You should see similiar email alert. Of course you can customize it and make it look more informative.
![email](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ilb2eu4w5krltjsgxzfy.png)

**Conclusion**

Thats it! You are now set to reduce costs by using above method which will make use of AWS resources and automate the complete process in a simple way. This methodology helps preventing unnecessary monthly bills and helps to keep track of unused resources, making us delete them when not required.