AWS IAM Roles with Terraform

An IAM role is an AWS identity with permission policies that determine what the identity can and cannot do in AWS.

TL;DR

  • The principal is WHO will be able to access a resource.
  • The policy is WHAT the principals associated with the role will be able to do.
  • The role links the principals thanks to the assume_role_policy with the inline policy argument.
  • The attachement links the role to a managed policies instead of the inline policy.

Terraform resources and AWS API

Policy

aws_iam_policy | aws create policy API
There are 3 types of policies.

  • Inline : The policy is defined directly in the object that needs it.
  • Managed : More flexible, can be reused with several roles. Need to be attached with an object.
  • AWS Managed : Same advantages as the managed ones but can’t be modified.

Here is a link that helps to choose between them.

Role

aws_iam_role | aws create role API

This is to define the IAM role resource that will link the principals and the policy.
If we are using managed policy we will need to link this role to the managed policy with an attachment resource. In case of using inline policy, the inline policy is declared in the Terraform resource role. With AWS API, it needs another API call to set the inline policy in the role.

assume_role_policy
This is a mandatory argument used in aws_iam_role and aws_iam_role_policy to indicate WHO can temporarily assume the role that we are defining. It’s also referred as trust policy.
explanation 1, explanation 2

Attachments

Attach a managed policy to a group, user or role

Possibilities of policy attachment

From the less flexible to the most flexible:

  • 1 resource: aws_iam_role with inline_policy argument
  • 2 resources: aws_iam_role + aws_iam_role_policy (conflict with aws_iam_role / inline_policy)
  • 3 resources: aws_iam_role + aws_iam_policy + aws_iam_role_policy_attachment

Terraform specific resources

Datasource

aws_iam_policy_document. This is an optional datasource which is Terraform specific. The policy defined in HCL format is translated to JSON when associated with the inline policy attribute of the role. The advantages of using this Policy in HCL format are:

  • Being able to overwrite, append, or update policies with this resource by using the source_json and override_json arguments.
  • Terraform error checking automatically formats your policy document into correct JSON when you run your apply.
  • Data sources make it easier to reuse policies throughout your environment.

It can be used in the below resources.

  • aws_iam_policy / policy argument
  • aws_iam_role_policy / policy argument
  • aws_iam_role_policy / assume_role_policy argument
  • aws_iam_role / assume_role_policy argument

Inline policy resources

Provide an IAM user/role/group with an inline policy. The aim is to reduce the number of Terraform resources to give access to a role/user/group. You can directly use them instead of creating a role/user/group, the policy and the attachement to link both (2 vs 3 resources). There is an overlap between the aws_iam_role_policy and the aws_iam_role / inline_policy argument. There are incompatible.

Attachment

There are lots of overlap, incompatibility and conflict with this resource.

conflict with aws_iam_user_policy_attachment, aws_iam_group_policy_attachment, aws_iam_role_policy_attachment

Bonus :)

As a bonus here are the quotas for IAM and STS

Related