AWS Instance Role and Instance Profile

 In this blog, let us try to understand what are Instance Profile and Instance Roles in AWS.

An Instance profile is an identifier for an Amazon EC2 instance while an Instance Role defines what can the user (in this case the Amazon EC2 which assumes this role) accomplish. In some way, think of the Instance Profile as the designation – Architect, which the Instance Role defines the roles and responsibilities of the person who holds that designation.

You may now be wondering, Why is this understanding and the distinction between these two important. The answer lies in how AWS services create these; or expects us to create these.

  • If you have always used the AWS console to create the Instance Role, then there is a chance you may not know what an Instance Profile is, as the console automatically creates the Instance Profile too and gives it the same name as the name you used for the Instance Role. Now when you use the console to create and launch the Amazon EC2 attaching the role you created, the profile (which was automatically created) gets attached too.
  • However, If you are using the AWS CLI or CloudFormation or Terraform, then you need to create the Instance Role and Instance Profile separately. This also means you can have the Instance Profiles and Roles with different names and when you launch the Amazon EC2, you need to use the correct Instance Profile and Roles names.

 Let us now look at a Terraform snippet to –

  • Create a policy for Amazon S3 and Amazon RDS.
  • Create an Instance Role and attach the policy to the Instance Role
  • Create an Instance Profile
  • Finally, attach the Role and the Profile to an Amazon EC2


Step 1 – Lets create an IAM policy which will give access to Amazon S3 and Amazon RDS. Lets also add permissions to Secrets Manager which will help us store and retrieve the DB credentials. Lets call this Policy as s3-and-rds-policy.

// Create a policy for Amazon S3 and Amazon RDS
 
data “aws_iam_policy_document” “s3-and-rds-policy” {
        statement {
            sid = “S3fullaccess”
            actions = [
                   “s3:*”,
                   “s3-object-lambda:*”
                   ]
            effect = “Allow”
            resources = [“*”]
         }
 
        statement {
            sid = “SecretsManagerDbCredentialsAccess"
                    effect = “Allow”
            actions = [
                 "secretsmanager:GetSecretValue",
                 "secretsmanager:PutResourcePolicy",
                         "secretsmanager:PutSecretValue",
                         "secretsmanager:DeleteSecret",
                        "secretsmanager:DescribeSecret",
                        "secretsmanager:TagResource"
                     ] 
            resources = ["arn:aws:secretsmanager:*:*:secret:rds-db-credentials/*"]
    }
 
        statement {
            sid = “RDSDataServiceAccess”
            effect = “Allow”
            actions = [
              "dbqms:CreateFavoriteQuery",
                      "dbqms:DescribeFavoriteQueries",
                      "dbqms:UpdateFavoriteQuery",
                      "dbqms:DeleteFavoriteQueries",
                      "dbqms:GetQueryString",
                      "dbqms:CreateQueryHistory",
                      "dbqms:DescribeQueryHistory",
                      "dbqms:UpdateQueryHistory",
                      "dbqms:DeleteQueryHistory",
                      "rds-data:ExecuteSql",
                      "rds-data:ExecuteStatement",
                      "rds-data:BatchExecuteStatement",
                      "rds-data:BeginTransaction",
                      "rds-data:CommitTransaction",
                      "rds-data:RollbackTransaction",
                      "secretsmanager:CreateSecret",
                      "secretsmanager:ListSecrets",
                      "secretsmanager:GetRandomPassword",
                      "tag:GetResources"     
              ]
            resources = [“*”]
         }
}

 

Step 2 – Let us next create an IAM Role. I will name the role as MyAppExecutionRole.

// Create an Instance Role - MyAppExecutionRole 
resource “aws_iam_role” “MyAppExecutionRole” {
  name = “MyAppExecutionRole”
assume_role_policy = <<EOF
{
       "Version": "2012-10-17",
        “Statement”: [
{
    “Action” : “sts:AssumeRole”, 
    “Principal”: {
“Service” : “ec2.amazonaws.com”
    },
                 “Effect” : “Allow”,
   “Sid” : “”
              }
        ]
}
EOF
      tags = {
“Name” = “MyAppExecutionRole”
“Unit” = “MyUnit”
       }
}

Step 3 - Now that we have an IAM Policy and an IAM Role, lets attach the Policy to the Role. This way the Role will inherit the permissions that have been defined in the IAM Policy.  

// Attach the policy to the Role
resource “aws_iam_policy” “s3-rds-policy-to-attach” {
  name = “s3-and-rds-policy” 
policy = data.aws_iam_policy_document.s3-and-rds-policy.json
}
resource “aws_iam_role_policy_attachment” “MyApp-role” {
  role = aws_iam_role.MyAppExecutionRole.name
policy_arn = aws_iam_policy.s3-rds-policy-to-attach.arn
}


Step 4 – Since we are creating the IAM Role using Terraform, we have to create an IAM Profile as well manually. As I mentioned earlier, if we had used the console, the IAM Profile would have been automatically created with the same name as the IAM Role.

Let’s name our Profile with a name which is different from the Role and attach the Role and the Profile.

// Create an Instance Profile. 
resource “aws_iam_instance_profile” “MyUniqueNameProfile” {
  name = “MyUniqueNameProfile” 
role = aws_iam_role.MyAppExecutionRole.name
lifecycle {
     create_before_destroy = true
             }
}

 

Step 5 – Finally, lets create an Amazon EC2 and attach the profile to the EC2.

// Create an Amazon EC2. Attach the Profile which has the Role attached

resource “aws_instance” “MyEc2InstanceName” {
  instance_type = "m5.large"
iam_instance_profile = aws_iam_instance_profile.MyUniqueNameProfile.name
}


Hope this helps.


~Narendra V Joshi

Comments

  1. Distinction of role and profile well articulated specifically for those who create terraform scripts this will be helpful

    ReplyDelete

Post a Comment