EC2 with IAM Role: CloudFormation Sample Template

Creating an EC2 Instance with an IAM Role is easy when you do it via the AWS Console but doing this with CloudFormation is not as direct. You will need an Instance Profile to connect an EC2 with an IAM Role.

TL;DR: See the CloudFormation Template below.

CloudFormation Template

Description: RadishLogic.com EC2 with IAM Role CloudFormation Sample Template

Parameters:
  Name:
    Type: String
    Default: RadishLogic

  EC2ImageId:
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-ebs
  
  SubnetId:
    Type: AWS::EC2::Subnet::Id
    Description: Subnet ID where the EC2 Instance will be launched.

Resources:
  Ec2SsmIamRole:
    Type: AWS::IAM::Role
    Properties: 
      AssumeRolePolicyDocument: 
        Statement:
          - Effect: Allow
            Principal:
              Service: [ec2.amazonaws.com]
            Action: ['sts:AssumeRole']
      Path: /
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM

  Ec2SsmInstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties: 
      Path: /
      Roles: [!Ref Ec2SsmIamRole]

  EC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: t2.micro
      ImageId: !Ref EC2ImageId
      IamInstanceProfile: !Ref Ec2SsmInstanceProfile
      SubnetId: !Ref SubnetId
      Tags:
        - Key: Name
          Value: !Sub "${Name}-EC2Instance"

CloudFormation Template Notes

EC2ImageId parameter is set to use the Amazon Linux 2 AMI in N. Virginia (us-east-1). You will need to change this if you are launching on a different region.

There really is no key pair on the instance. There is also no Security Group. The intention of this post is to show that the IAM Role is working on the EC2 Instance. I chose the AmazonEC2RoleforSSM IAM Policy so that we will be able to connect to the instance without a Key Pair and a Security Group. See Testing section below.

The cloudformation template above assumes that you have a default VPC in your AWS Account, if not you will need to specify the SubnetId property under the AWS::EC2::Instance resource.


What is an Instance Profile?

An instance profile is a container for an IAM role that you can use to pass role information to an EC2 instance when the instance starts.
- from AWS Docs

The instance profile is like a middle man to associate the IAM Role with the EC2 Instance.

We do not see the step of creating the Instance Profile whenever we associate the IAM Role to the EC2 Instance via the AWS management console. AWS automatically creates the Instance Profile whenever you create an IAM Role for the EC2 service.

The list of IAM Role whenever you are selecting for the EC2 Instance is actually the list of names of the Instance Profile.

The AWS Documentation or the docs for CloudFormation Instance Profiles, the roles part is a list, but you can only attach one IAME Role to an Instance Profile.

I find the IAM Role list weird since you can only attach one IAM Role. There is a thread in reddit speculating on why there is a need for the Instance Profile.


Testing

Once you have launched the CloudFormation Template above, see below to test if the IAM Role is working.

On the EC2 AWS Console, select the launched EC2 Instance. Click Connect.

Select Session Manager, then click Connect.

A new tab will launch, where you can execute Linux Commands.


I wrote this as I always end up looking for how to connect an IAM Role to an EC2 Instance in CloudFormation since I always forget the existence of the Instance Profile.

I hope this helped you understand the relationship of the EC2 instance with an IAM Role and finish your CloudFormation Template.

If there are any issues you encounter or anything you want to say about the above let me know on the comments below.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.