---
# System prepended metadata

title: Deploy S3 bucket with Terraform
tags: [ECV]

---

# Check which IAM role is used for creating S3 bucket
## Introduce

This task is an extension work for the article [credential priority](/nIarDsLUSyKjH1E3F0cNQQ). In this task, we will create an IAM role with higher permission and attach it to the environment we want to execute terraform files. For checking the target information, it is important to create CloudTrail and a bucket as the destination. The log files we need will be sent to the bucket.

Also, we'll explain some problems which might associate with this topic.

![image](https://hackmd.io/_uploads/HkB6t6FFR.png)


## Steps
1. Create IAM role manually
2. Edit IAM role's trust policy
3. Create S3 bucket with Terraform
4. Validate that S3 is created with new IAM role by Cloudtrail

### 1. Create IAM role manually
#### Create IAM role
![image](https://hackmd.io/_uploads/Byzt7TuKR.png)

**1-1. Choose permissions**
**1-2. Create**
**1-3. Attach a new IAM role**
**1-4. Restart the instance (stop then start)**

### 2. Edit IAM role's trust policy

For using Terraform to build S3 bucket, we need not only IAM role with enough permissions but also trust relationship. The propose of "trust relationship" allows EC2 to assume its role. We can set it up by follwing steps.

**2-1. Go to the IAM role page.**
**2-2. Find the role which will be used in Terraform file.**
**2-3. Choose "Trust relationships" below the Summary.**
**2-4. Click "edit trust policy".**
**2-5. Add the role used by EC2 after the label "AWS".** 
```json=
/* 
    E.g. Policy A for EC2 env, policy B used in Terraform file.
    Then you should attach policy A into policy B like this:
*/
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "ec2.amazonaws.com",
                "AWS": "arn:aws:iam::1234567890:role/A"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
```
After step 1, we know that role A has permission to assume other roles (due to admin access). Then by doing step 2, an EC2 instance with the role A could assume any other role, including "B". 



### 3. Create S3 bucket with Terraform
Create a S3 bucket for CLoudTrail.
### 4. Validate that S3 is created with new IAM role by Cloudtrail
**4-1. Create Trail**
![image](https://hackmd.io/_uploads/rJ_GL6OKA.png)
![image](https://hackmd.io/_uploads/BkjoLaOtR.png)
![image](https://hackmd.io/_uploads/H1tDwp_YA.png)

**4-2. Create a new S3 bucket with terraform**

To check whether the new IAM role is used for creating bucket, a new bucket should be created after CloudTrail deployed. We use Terraform for creating bucket.

Run the following code in EC2 environment.
```tf=
provider "aws" {
  region = "us-west-2"

  assume_role {
    role_arn     = "arn:aws:iam::123456789:role/arn:aws:iam::123456789:role/B"
  }
}

resource "aws_s3_bucket" "example_bucket" {
  bucket = "new-bucket"

  tags = {
    Name        = "My bucket"
    Environment = "Dev"
  }
}
```

**4-3. Go to CloudTrail**
**4-4. Download the file**
**4-5. Search the key word and get information**
Search the key word "CreateBucket" for finding target log. Then you will find that S3 bucket was created by IAM role B.

## Problem
The following problem is usual for people who are new to cloud (including me). 

```
│ Error: Cannot assume IAM Role
│
│   with provider["registry.terraform.io/hashicorp/aws"],
│   on main.tf line 1, in provider "aws":
│    1: provider "aws" {
│
│ IAM Role (arn:aws:iam::123456789:role/arn:aws:iam::123456789:role/B) cannot be assumed.
│
│ There are a number of possible causes of this - the most common are:
│   * The credentials used in order to assume the role are invalid
│   * The credentials do not have appropriate permission to assume the role
│   * The role ARN is not valid
│
│ Error: operation error STS: AssumeRole, https response error StatusCode: 403, RequestID: 92421367-f94b-4114-b0c6-1cd3dc36c8f4, api error
│ AccessDenied: User: arn:aws:sts::123456789:assumed-role/A/i-12345678abc is not authorized to perform: sts:AssumeRole
│ on resource: arn:aws:iam::123456789:role/arn:aws:iam::123456789:role/B
│
╵
```

After many tries, I found the reason then write this article. This problem would be caused by execution without setting trust policy correctly. However, why the IAM role with enough permissions still not work when execution? WHy we still need trust relationship? Let's introduce the difference between roles and trust relationship. 

1) The permissions the role has: what it can do
2) The trust relationship: who can assume the role

Therefore, the key reason for making this task succeed is that:
1. The assuming entity must have permission to assume the role. (gives the role permission to call `sts:AssumeRole` on any role)
2. The role being assumed must trust the assuming entity.

## summarize
The learning point of this task is to get familiar with AWS credential and IAM role's usage.

To summarize, having permission to perform `sts:AssumeRole` doesn't automatically mean a role can assume any other role. The target role must also trust the assuming entity. This two-way verification is a crucial security feature in AWS IAM.
 