Using Lambda to Disable IAM Users
Problem
Picture this. You work as a cloud IT professional at a medium size company and you recently hired some AWS contractors. They do a good job, and you get permission to hire more in the future. So you do, and this goes on for some time. However, you get tired of manually removing old contractor users from your IAM groups. What’s an IT pro to do?
Solution
A good way to solve this problem would be to use a scheduled Lambda function and good tagging practices to identify old users and remove their permissions. If you tag any new contractors as role: contractor, you can use a script to identify and remove them from groups automatically using this boto3 method. We will be using the serverless framework to handle the infrastructure deployment for this lambda function. Let’s get into it.
You will need three files for this solution to work:
- A serverless.yml file to configure the serverless deployment.
- A YAML file to define your Lambda function.
- A Python file that contains your actual script.
Your file structure should look something like this:
[IMAGE]
Let’s start by walking through the serverless.yml file, here’s the code:
|
|
This file allows you to name and configure your serverless application. The provider section specifies the runtime environment, metadata, memory size, and IAM permissions that are passed to your Lambda function. The function section points to the path where your Lambda function lives, i.e. the contractorCheck.yml file in the functions folder.
contractorCheck.yml code:
|
|
This file points to the lambda_handler method in our python file and sets up a scheduled cloudwatch event that triggers our function once per day (via the handler).
And now for the actual script:
|
|
There’s a lot going on here, so let’s break it down by method:
-
main()_: Here we create an iam client object that we pass to our methods and we control the program flow.
-
getUsers(client): This method creates a ‘list_users’ paginator, which returns a paginated dictionary containing information about each user in the account.
-
listUsers(pages): This method accepts the pagination dictionary as an argument, then parses out and returns a list of user names.
-
getDates(pages): This also accepts the pagination dictionary as an argument, parsing out and returning a dictionary of usernames and user creation dates.
-
getContractors(users, client): This method accepts the list of users returned by listUsers() and checks each user in the list for the tags ‘role: contractor’. If a user has those tags, their username is appended to a list of contractors, which is returned.
-
checkContractors(contractors, createDates, client): This method accepts the list of contractors and the dictionary of creation dates as arguments, compares the creation date of each user in the list of contractors to the current date, then removes them from any groups they are members of, if they are over 45 days old.
-
lambda_handler(event, client): This function allows CloudWatch to trigger your Lambda function. It prints the event information it receives and calls the main() method.
Summary We have created a Lambda function that checks each user in an account and removes them from all groups if the following conditions are true:
- They have the tag role:contractor.
- They are older than 45 days.
This Lambda function was deployed using the Serverless Framework, simplifying the deployment process. We now have a Lambda function that checks our users for old contractors once per day, and automatically disables contractors older than 45 days.
This particular script may not save you more than 30 minutes over the course of a month, but once this principle is applied to other routine tasks that number will continue to grow like an automation snowball.