Create IAM User

In this article we will use boto3 SDK for Python to create a IAM user that can be used to provision a server on EC2.

Prerequisites

You have:

  • Installed Python 3.12.0 and boto3 SDK version 1.34.78
  • Created IAM awsadmin user with administrator privileges using the AWS console
  • Downloaded the secret keys for the awsadmin
  • Set the environment variables for AWS secret keys that belongs to the awsadmin

Code

The aws-dev IAM user will be created with full EC2 permissions and Secrets Manager. The PEM file is stored in the Secrets Manager during the provisioning of EC2 instance by Terraform. EC2 permissions allows you to create and launch EC2 instances on your AWS account.

If you prefer to use the AWS console, you can follow the instructions on creating IAM Dev User. You can skip the instructions in this article.

If you prefer code instead of using the AWS console, you can run this code to create a IAM user that can be used to provision a server on EC2.

iam.py
import boto3
import json

# Initialize the IAM client
iam = boto3.client('iam')

# Specify the username
user_name = 'aws-dev'

# Create a new IAM user for development
try:
    response = iam.create_user(UserName=user_name)
    user_arn = response['User']['Arn']
    print(f"User {user_name} created successfully with ARN: {user_arn}")
except iam.exceptions.EntityAlreadyExistsException:
    print(f"User {user_name} already exists.")
    # Fetch the user's ARN if already exists and is needed for subsequent operations
    user_arn = iam.get_user(UserName=user_name)['User']['Arn']
except Exception as e:
    print(f"Error creating user {user_name}: {e}")
    exit()  # Exit if user creation fails to prevent further execution

# Attach the EC2FullAccess managed policy to the user
ec2_full_access_policy_arn = 'arn:aws:iam::aws:policy/AmazonEC2FullAccess'
try:
    iam.attach_user_policy(
        UserName=user_name,
        PolicyArn=ec2_full_access_policy_arn
    )
    print(f"EC2 Full Access policy attached to user {user_name}.")
except Exception as e:
    print(f"Error attaching EC2 Full Access policy to user {user_name}: {e}")

# Define and attach the inline policy for Secrets Manager
secrets_manager_policy = {
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "secretsmanager:CreateSecret",
                "secretsmanager:DescribeSecret",
                "secretsmanager:GetSecretValue",
                "secretsmanager:ListSecretVersionIds",
                "secretsmanager:ListSecrets",
                "secretsmanager:GetResourcePolicy",
                "secretsmanager:DeleteSecret",
                "secretsmanager:PutSecretValue"
            ],
            "Resource": "*"
        }
    ]
}
try:
    iam.put_user_policy(
        UserName=user_name,
        PolicyName='SecretsManagerPolicy',
        PolicyDocument=json.dumps(secrets_manager_policy)
    )
    print(f"Secrets Manager policy attached to user {user_name}.")
except Exception as e:
    print(f"Error attaching Secrets Manager policy to user {user_name}: {e}")

# Create access keys for the user
try:
    keys_response = iam.create_access_key(UserName=user_name)
    access_key_id = keys_response['AccessKey']['AccessKeyId']
    secret_access_key = keys_response['AccessKey']['SecretAccessKey']
    print(f"access_key_id: {access_key_id}")
    print(f"secret_access_key: {secret_access_key}")
except Exception as e:
    print(f"Error creating access key for user {user_name}: {e}")

Run this code.

Verify

You can verify that the user is created by going to the IAM dashboard in the AWS console. Click on the aws-dev user and check the permissions are correct.

Secret Keys

Copy the access keys printed in the terminal and set the environment variables:

.bashrc
export AWS_ACCESS_KEY_ID=copy-the-output-for-access_key_id
export AWS_SECRET_ACCESS_KEY=copy-the-output-for-secret_access_key
export AWS_DEFAULT_REGION=us-west-2

The next step is to use the aws-dev user and the corresponding secrets keys for using Packer and Terraform. If the default image fits your needs, you don’t need to create a custom image using Packer. You can skip to the next step, running Terraform script.