AWS Basics for DevOps Learners: How to Use User Data and IAM Roles

A Step-by-Step Guide to Using User Data and IAM Roles in AWS

Ajit Fawade
9 min readOct 23, 2023

Are you a DevOps learner who wants to get started with AWS? If yes, then this blog post is for you.

In this post, I’ll explain two important concepts that you need to know when working with AWS: user data and IAM roles.

User data is a way of passing custom configuration and commands to your EC2 instances, while IAM roles are a way of granting permissions and access to your AWS resources.

By the end of this post, you’ll be able to:

  • Understand what user data is and how to use it in AWS
  • Launch an EC2 instance with Jenkins pre-installed using user data
  • Understand what IAM roles are and how to use them in AWS
  • Create and assign IAM roles for different types of users

Let’s get started!

What is User Data in AWS?

User data is a feature of Amazon EC2 that allows you to pass custom configurations and commands to your EC2 instances when you launch them. You can use user data to perform common automated tasks such as installing software, configuring settings, running scripts, etc. User data can be very useful for DevOps learners who want to save time and manual effort every time they launch an instance and want to install any application on it like Apache, docker, Jenkins, etc.

You can pass two types of user data to Amazon EC2: shell scripts and cloud-init directives. Shell scripts are executable commands that run on the instance’s operating system, while cloud-init directives are instructions that are processed by a tool called cloud-init that runs on the instance during boot. Cloud-init can perform more advanced tasks such as setting up users, mounting volumes, writing files, etc.

You can also pass user data in different formats: as plain text, as a file, or as base64-encoded text. Plain text is the simplest format that you can enter directly into the launch instance wizard or the command line tools. File format is useful when you have a script or a file that you want to upload from your local machine. Base64-encoded text is required when you use the API calls to launch instances.

To illustrate how user data works, let’s see an example of launching an EC2 instance with Jenkins pre-installed using user data.

How to Launch an EC2 Instance with Jenkins Pre-Installed Using User Data

Jenkins is a popular open-source tool for continuous integration and continuous delivery (CI/CD) that allows you to automate the building, testing, and deployment of your software projects. Jenkins can be installed on various platforms, including AWS EC2 instances. In this section, I’ll show you how to launch an EC2 instance with Jenkins pre-installed using user data.

To do this, we’ll use a shell script that will install Jenkins and its dependencies on the instance using apt-get commands. We’ll also configure Jenkins to run on port 8080 and set up a firewall rule to allow inbound traffic on that port. Here is the shell script that we’ll use:

#!/bin/bash
# Update the package manager
sudo apt update
# Install Java
sudo apt install fontconfig openjdk-17-jre -y
# Add Jenkins repository key and source
sudo wget -O /usr/share/keyrings/jenkins-keyring.asc \
https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key
echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] \
https://pkg.jenkins.io/debian-stable binary/ | sudo tee \
/etc/apt/sources.list.d/jenkins.list > /dev/null
# Update packages again
sudo apt update
# Install Jenkins
sudo apt install jenkins -y
# Start the Jenkins service
sudo systemctl start jenkins
# Enable the Jenkins service to start at boot
sudo systemctl enable jenkins

To pass this script as user data, we’ll use the file format option in the launch instance wizard. Here are the steps:

1. Open the AWS Management Console and go to the EC2 service.

2. Click on the Launch Instance button.

3. Select the Ubuntu Server 22.04 LTS (HVM) AMI.

4. Choose an instance type.

5. Configure the instance details.

Configure security group

6. Click on the Security Groups tab.

7. Click on the Edit button for the security group that you want to configure.

8. Click on the Add Security Rule button.

9. Select the Type Custom TCP Rule.

10. Select the Protocol as TCP.

11. Enter the Port Range as 8080.

12. Select the Source as Anywhere.

13. Click on the Save button.

Configure user data

14. Under the Advanced Details section, expand the User data field.

15. In the User data section, select File from the drop-down menu and click on the Choose File button.

16. Browse to the location of the shell script that we created earlier and select it.

17. Click on the Launch Instance button.

Once your instance is up and running, you can access Jenkins by entering the instance’s public IP address followed by port 8080 in your browser. For example, http://<instance-public-ip>:8080. You should see the Jenkins welcome page that asks you to unlock Jenkins using an initial password.

To get the password, you can SSH into your instance and run the following command:

sudo cat /var/lib/jenkins/secrets/initialAdminPassword

Copy the password and paste it into the Jenkins web page. Then, follow the instructions to complete the Jenkins setup.

To verify that user data was executed successfully, you can also check the user data logs in your instance by running the following command:

sudo cat /var/log/cloud-init-output.log

You should see the output of the user data script that we passed, along with any errors or warnings if any.

Congratulations! You have successfully launched an EC2 instance with Jenkins pre-installed using user data.

What are IAM Roles in AWS?

IAM roles are another type of IAM identity that you can create in your AWS account that has specific permissions. IAM roles are similar to IAM users, in that they are AWS identities with permission policies that determine what they can and cannot do in AWS. However, unlike IAM users, IAM roles do not have permanent credentials such as passwords or access keys associated with them. Instead, IAM roles provide temporary security credentials to whoever has the ability to assume that role.

You can use IAM roles to delegate access to users, applications, or services that don’t normally have access to your AWS resources. For example, you might want to grant users in your AWS account access to resources they don’t usually have, or grant users in one AWS account access to resources in another account. Or you might want to allow a mobile app to use AWS resources, but not want to embed AWS keys within the app (where they can be difficult to update and where users can potentially extract them). Sometimes you want to give AWS access to users who already have identities defined outside of AWS, such as in your corporate directory. Or, you might want to grant access to your account to third parties so that they can perform an audit on your resources. For these scenarios, you can delegate access to AWS resources using an IAM role.

To create an IAM role, you need to specify two things: the trusted entity and the permission policy. The trusted entity is the user, application, or service that is allowed to assume the role. The permission policy is the set of permissions that the role grants when it is assumed. You can also optionally specify a session policy that further restricts the permissions for a specific role session.

To assume an IAM role, you need to have permission to do so. You can use the AWS Management Console, the AWS CLI, the AWS SDKs, or the AWS APIs to assume a role. When you assume a role, you get a set of temporary security credentials that include an access key ID, a secret access key, and a security token. You can use these credentials to make API requests or access AWS resources that the role allows. The credentials are valid for a limited time period and you can specify when you create or assume the role.

To illustrate how IAM roles work, let’s see an example of creating and assigning IAM roles for different types of users.

How to Create and Assign IAM Roles for Different Types of Users

In this section, I’ll show you how to create and assign IAM roles for three types of users: DevOps-User, Test-User, and Admin. These users represent different roles in a DevOps team that need different levels of access to AWS resources.

  • DevOps-User: This user needs read-write access to EC2 instances and S3 buckets.
  • Test-User: This user needs read-only access to EC2 instances and S3 buckets.
  • Admin: This user needs full access to all AWS EC2 services and resources.

To create and assign these roles, we’ll use the following steps:

1. Open the AWS Management Console and go to the IAM service.

2. Click on the Roles tab.

3. Click on the Create role button.

4. Select the Select role type option and choose AWS Service.

5. Select the EC2 service and click on the Next: Permissions button.

6. Select the Attach existing policies directly option and choose the following policies:

  • For the DevOps-User role, choose the AmazonEC2FullAccess policy.
  • For the Test-User role, choose the AmazonEC2ReadOnlyAccess policy.
  • For the Admin role, choose the AdministratorAccess policy.

7. Click on the Next: Tags button.

8. Click on the Next: Review button.

9. Review the information for your new role and click on the Create role button.

Congratulations! You have successfully created IAM roles for different types of users.

Conclusion

In this blog post, I have explained two important concepts that you need to know when working with AWS: user data and IAM roles. User data is a way of passing custom configuration and commands to your EC2 instances when you launch them, while IAM roles are a way of granting permissions and access to your AWS resources. I have also shown you how to use these concepts in practice by launching an EC2 instance with Jenkins pre-installed using user data and creating and assigning IAM roles for different types of users.

I hope you found this blog post informative and engaging.

This is the end of the blog post for Day 39 of 90 Days of DevOps.

Thank you for reading and stay tuned for more posts in this series!

--

--

No responses yet