# 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)!


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.saml.to/configuration/service-providers/aws-federated-roles/assuming-roles/terraform.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
