> For the complete documentation index, see [llms.txt](https://docs.saml.to/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.saml.to/configuration/service-providers/aws-federated-roles/assuming-roles/terraform.md).

# Terraform

## Introduction

The SAML.to [Command Line Interface](https://github.com/saml-to/cli) can be used for authentication to AWS and can be used with the `terraform` CLI or any tool that supports Terraform (such as `terragrunt`).

This document will detail how to use SAML.to to authenticate to AWS to run Terraform commands with Tokenless Authentication.

## Create a Terraform Runner Role

Create a `terraform-runner` role (or whatever name you prefer) that has a [Trust Relationship to SAML.to](/configuration/service-providers/aws-federated-roles/adding-roles.md).

<details>

<summary>Example: Role Permissions for Terraform + S3 State Storage</summary>

If the Terraform Configuration uses S3 State storage, such as:

```
terraform {
  backend "s3" {
    bucket = "mybucket"
    key    = "path/to/my/key"
    region = "us-east-1"
  }
}
```

The role needs permission to the S3 Bucket:

```
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:ListBucket",
      "Resource": "arn:aws:s3:::mybucket"
    },
    {
      "Effect": "Allow",
      "Action": ["s3:GetObject", "s3:PutObject", "s3:DeleteObject"],
      "Resource": "arn:aws:s3:::mybucket/path/to/my/key"
    }
  ]
}
```

</details>

In `saml-to.yml`, grant access to GitHub Users to assume `terraform-runner`:

```
      - name: arn:aws::YOUR_ACCOUNT_ID:role/terraform-runner
        ...
        users:
          github:
            - SOME_GITHUB_USERNAME
            - ANOTHER_GITHUB_USERNAME
```

Ensure the role is functional:

```
$(saml-to assume terraform-runner)
aws sts get-caller-identity
```

And run `terraform init` to ensure you have access to the State File.

{% hint style="info" %}
If the Role in AWS has Read/Write permissions to the AWS account, such as `AdministratorAccess`, at this point, you can run `terraform plan` and `terraform apply` with the `terraform-runner` identity.

If you want to make a second role in the same or another account, see [A Terraform Applier Role](#optional-a-terraform-applier-role).
{% endhint %}

## Optional: A Terraform Applier Role

Create a second role in whatever AWS account you'd like, `terraform-applier` (or whatever you want to call it) that grants `terraform-runner` the ability to assume it:

<details>

<summary>Trust Relationship</summary>

```
{
  "Version": "2012-10-17",
    "Statement": [{
        "Effect": "Allow",
        "Principal": {
          "AWS": "arn:aws:iam::YOUR_ACCOUNT_ID:role/terraform-runner"
        },
        "Action": "sts:AssumeRole"
    }]
}
```

</details>

{% hint style="success" %}
It's **not necessary** to declare `terraform-applier` in the `saml-to.yml`. Role Assumption in Terraform uses STS Role Assumption internally and relies on IAM trust relationships!
{% endhint %}

Configure role assumption in Terraform:

```
terraform {
  ... uses the System Terminal Role for terraform init ...
}

provider "aws" {
  profile = "terraform-runner"
  region  = "us-east-1"
  assume_role {
    role_arn = "arn:aws:iam::THE_ACCOUNT_ID:role/terraform-applier"
  }
}

resource "aws_..." {
  ... Terraform transparently assumes terraform-applier, then creates the resource ...
}
```

Save the temporary credentials to `~/.aws/credentials` using the `--save` flag on the [SAML.to CLI](https://github.com/saml-to/cli):

```
saml-to assume terraform-runner --save
```

And run Terraform commands:

```
terraform init
terraform plan
terraform apply 
```

## Questions/Comments/Issues?

[Contact us](https://saml.to/contact)!
