AWS IAM Roles with AWS CloudFormation

AWS IAM Roles with AWS CloudFormation

ยท

6 min read

Amazon Web Services Identity and Access Management, AWS IAM, provides a robust framework for controlling access to AWS services and resources. Managing permissions and access control in cloud environments is critical for ensuring the security and integrity of your environment and applications.

AWS CloudFormation is a great way to manage and automate your AWS infrastructure by provisioning templates written in JSON or YAML. With CloudFormation, you can define your infrastructure as code and deploy it consistently across multiple environments and accounts.

What is an IAM Role?

Let's briefly understand what IAM roles are in the context of AWS.

AWS IAM consists of several key components that provide robust access control and security management within the AWS environment. The main components of AWS IAM are:

  1. Users: Users are the entities representing individual people within your organization who interact with AWS services. Each user has a unique set of security credentials, including an access key and a secret access key, which are used to authenticate and authorize API requests.

  2. Groups: Groups are collections of IAM users. Organizing users into groups allows you to manage and assign permissions to multiple users simultaneously. All users automatically inherit permissions granted to a group.

  3. Roles: IAM roles define a set of permissions and access policies that AWS resources or IAM users can assume. Roles are often used to delegate access to AWS services or cross-account access. By assuming a role, an entity can temporarily receive specific permissions and carry out authorized actions on behalf of another entity.

  4. Policies: IAM policies are JSON documents that define permissions and access control rules. They can be attached to users, groups, or roles. Policies explain what actions are allowed or denied on specific resources or services and provide fine-grained control over who can perform what actions.

Main components of Amazon Web Services (AWS) Identity and Access Management: IAM Users, IAM Groups, IAM Roles and IAM Policies.

An IAM role is a secure way to grant permissions to entities in AWS, such as IAM users, AWS services, or external identities, without needing long-term access keys.

IAM Roles define a set of permissions, which can be assumed by trusted entities, allowing them to perform actions on AWS resources.

IAM roles often grant AWS services permissions or establish trust relationships with external entities, such as identity providers or cross-account access.

List of entities that AWS IAM can grant permissions: Users, Services and External Accounts.

Creating IAM Roles with AWS CloudFormation

AWS CloudFormation provides a declarative way to define and provision infrastructure resources. To create an IAM role with CloudFormation, you need to define a resource of the type AWS::IAM::Role.

In this example, we define a role named AppDevRole with a policy that allows EC2 instances to assume this role. The role also has a policy that grants permission to read objects from an S3 bucket resource AppDevBucket.

AWSTemplateFormatVersion: 2010-09-09

Resources:
  AppDevBucket:
    Type: AWS::S3::Bucket

  AppDevRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - ec2.amazonaws.com
            Action:
              - sts:AssumeRole
      Policies:
        - PolicyName: AppDevRolePolicy
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - s3:GetObject
                Resource: !Sub arn:aws:s3:::${AppDevBucket}/*

The AssumeRolePolicyDocument specifies the trust policy that is associated with this role. Trust policies define which entities can assume the role.

In this case, we allow the EC2 service to assume the IAM Role by specifying ec2.amazonaws.com as the principal in the Service field. You can associate only one trust policy with a role.

The Policies section defines the inline policy document embedded in the role. In our example, we create a policy named AppDevRolePolicy that grants permission to perform the s3:GetObject action on objects in the app-dev-bucket S3 bucket.

When you embed an inline policy in a role, the inline policy is used as part of the role's access permissions policy. The role's trust policy is created at the same time as the role.

A complete list of properties can be found in the CloudFormation documentation for the AWS::IAM::Role resource type.

Using IAM Roles with CloudFormation Resources

Once you have created an IAM role, you can use it with other AWS resources in your CloudFormation templates.

Let's consider an example where we create an EC2 instance and associate the previously created IAM role with it:

AWSTemplateFormatVersion: 2010-09-09

Resources:
  # ...
  AppDevEC2InstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Roles:
        - !Ref AppDevRole

  AppDevSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: AppDev Security Group
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 0.0.0.0/0

  AppDevEC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: t3.small
      ImageId: ami-06b09bfacae1453cb
      IamInstanceProfile: !Ref AppDevEC2InstanceProfile
      SecurityGroups:
        - !Ref AppDevSecurityGroup

Outputs:
  AppDevBucketName:
    Value: !Ref AppDevBucket
    Description: Name of the AppDev S3 Bucket
  AppDevEC2InstanceIp:
    Value: !GetAtt AppDevEC2Instance.PublicIp
    Description: Public IP address of the AppDev EC2 Instance

In this example, we define components to create an EC2 instance resource named AppDevEC2Instance.

We specify the AppDevEC2InstanceProfile to allow the EC2 instance to have specific permissions assigned to it through an IAM role. We reference the AppDevRole IAM role we created earlier.

This ensures that the EC2 instance assumes the specified IAM role, inheriting its permissions and policies. By associating IAM roles with resources, you can enforce the principle of least privilege, granting only the necessary permissions to perform specific actions.

We are using the CloudFormation intrinsic function !Ref to return the resource value reference.

The AppDevSecurityGroup is an Amazon EC2 security group. It acts as a virtual firewall for the EC2 instance, controlling inbound and outbound traffic. This example template allows incoming SSH traffic on port 22 from any IP address (0.0.0.0/0).

Updating IAM Roles permissions

For every AWS service, you can specify what actions are allowed, which resources those actions can be applied to, and any additional conditions that need to be met in IAM policies.

The AWS documentation page Service Authorization Reference contains the actions, resources, and condition keys for AWS services.

Let's update our IAM Role permission to allow our application to put objects in the S3 bucket. Looking at the Amazon S3 actions table, we can use s3:PutObject to enable our application to send files to S3:

AWSTemplateFormatVersion: 2010-09-09

Resources:
  # ...
  AppDevRole:
    # ...
      Policies:
        - PolicyName: AppDevRolePolicy
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - s3:GetObject
                  - s3:PutObject # <--- New Action!
                Resource: !Sub arn:aws:s3:::${AppDevBucket}/*

Conclusion

AWS CloudFormation simplifies the creation, usage, and management of IAM Roles, providing a streamlined approach to managing access control and permissions for your AWS resources.

CloudFormation enables you to manage IAM roles over time through stack updates. If you need to modify the permissions or policies of an IAM role, you can update the CloudFormation template, and CloudFormation will handle the necessary updates during stack update operations.

By utilizing CloudFormation and IAM Roles together, you can enhance the security and governance of your AWS infrastructure. The declarative nature of CloudFormation allows for consistent and reproducible deployments, while IAM Roles enforce the least privileged access, granting only the necessary permissions for your resources.

To learn more about the IAM Role and IAM Policies relationship, check out our guide AWS IAM Policies: A Practical Approach.

Are you interested in more?

Head over to our bi-weekly newsletter or check out the following blog posts

ย