<p>The solution is to specify an <code>assume_role</code> statement:</p>

<pre><code>provider "aws" {
  profile = "default"
  assume_role {
    role_arn = "arn:aws:iam::[ACCOUNT_ID]:role/terraform-test-role"
  }
}
</code></pre>

CC BY-SA 4.0
2020-04-23T14:39:17.450Z
I'm already using assume_role so I guess there's some additional detail I'm missing.
Nic
CC BY-SA 4.0
2020-04-22T10:56:05.320Z
2020-04-22T10:56:05.320Z
Subhash
<p>I was looking into a similar use case and found this github issue in the terraform public repo:
<a href="https://github.com/terraform-providers/terraform-provider-aws/issues/629" rel="nofollow noreferrer">https://github.com/terraform-providers/terraform-provider-aws/issues/629</a></p>

<p>As quoted in that issue:
"Indeed it does seem like the Terraform AWS provider would need to do something special to make this work. As I noted in my other comment, we don't consider Terraform to be an interactive tool in general and so introducing extra interactive input in the apply phase is not ideal."</p>

<p><a href="https://github.com/terraform-providers/terraform-provider-aws/issues/629#issuecomment-408937315" rel="nofollow noreferrer">https://github.com/terraform-providers/terraform-provider-aws/issues/629#issuecomment-408937315</a></p>

CC BY-SA 4.0
2020-05-10T05:39:00.227Z
2020-05-10T05:39:00.227Z
mr-brody
<p>The error message here is telling you that you are not allowed to enable MFADelete without having an authenticated token with mfa. Meaning the executing principal must have logged in with MFA.</p>
<p>essentially the API call on the cli would be something like this</p>
<pre><code>aws --profile my_profile s3api put-bucket-versioning --bucket bucket-name --versioning configuration 'MFADelete=Enabled,Status=Enabled' --mfa 'arn:aws:iam::&lt;account-id&gt;:mfa/root-account-mfa-device &lt;mfacode&gt;
</code></pre>
<p>Note that only the root account MFA can do this (the bucket owner) not a standard user. <a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/Versioning.html#MultiFactorAuthenticationDelete" rel="nofollow noreferrer">As detailed here</a></p>
<p>A simple terraform config assuming its executing under the credentials the previous profile specified would be:</p>
<pre><code>resource &quot;aws_s3_bucket&quot; &quot;bucket&quot; {
  bucket = &quot;some_test_bucket&quot;
  acl    = &quot;private&quot;
  
  versioning {
    enabled = true 
    mfa_delete = true
  }
}
</code></pre>
<p>Now so far so good, however, it should be noted that <code>mfa_delete = true</code> cannot toggle that setting, it is there to reflect the enabling of that in the state file only <a href="https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket#mfa_delete" rel="nofollow noreferrer">as mentioned in the docs</a></p>
<p>The correct way to set the mfa_delete to enabled is via the API yourself. As mentioned above as the provider cannot change it but has the state there to ensure its not going to change the state after it is set on a subsequent run (out of band terraform changes to enable with the API).</p>
<p>This answer assumes AWS provider v2.65.0 or higher</p>

CC BY-SA 4.0
2021-06-21T09:15:11.320Z
2021-06-23T15:02:23.880Z
2021-06-23T15:02:23.880Z
krystan honour
<p>Assuming that </p>

<ul>
<li>your IAM user can generate an mfa session token via <code>GetSessionToken</code>, and </li>
<li>you have a way of getting this token and applying it in your <strong>~/.aws/credentials</strong> file (this can be done using helper scripts, like <a href="https://github.com/broamski/aws-mfa" rel="nofollow noreferrer">https://github.com/broamski/aws-mfa</a>) </li>
</ul>

<p>you don't need to specify anything special in the terraform configuration. You just need to make sure your aws cli profile is configured correctly as described above AND there is a valid token when you run terraform.</p>

CC BY-SA 4.0
2020-05-14T09:17:01.267Z
2020-05-14T09:17:01.267Z
dimisjim
<p>I used the AWS cli to do <code>sts assume-role</code> and then used <code>jq</code> to decompose the response and stored the values in environment variables, which <code>terraform</code> then uses. <a href="https://registry.terraform.io/providers/hashicorp/aws/latest/docs#environment-variables" rel="nofollow noreferrer">https://registry.terraform.io/providers/hashicorp/aws/latest/docs#environment-variables</a></p>
<p>My setup:</p>
<ol>
<li>A user</li>
<li>A profile in <code>~/.aws/credentials</code> which has my access/secret</li>
<li>A role which can only use used by the user and requires MFA</li>
</ol>
<pre><code>    session_token=$(aws sts assume-role \
        --profile ${profile} \
        --role-arn &quot;${role_arn}&quot; \
        --role-session-name &quot;${session_name}&quot; \
        --serial-number &quot;${mfa_serial}&quot; \
        --duration-seconds $session_duration \
        --token-code &quot;${token_code}&quot; \
        --query Credentials)

    export AWS_REGION=${region}
    export AWS_ACCESS_KEY_ID=&quot;$(echo $session_token | jq -r .AccessKeyId)&quot;
    export AWS_SECRET_ACCESS_KEY=&quot;$(echo $session_token | jq -r .SecretAccessKey)&quot;

    terraform plan
</code></pre>

CC BY-SA 4.0
2023-05-30T10:57:42.593Z
2023-05-30T15:02:14.213Z
2023-05-30T15:02:14.213Z
Chris Kemp
<p>I'm using Terraform with the <a href="https://github.com/terraform-providers/terraform-provider-aws" rel="noreferrer">terraform-provider-aws</a> provider to manage my AWS infrastructure. I'm trying to enable <code>mfa_delete</code> on an S3 bucket, but when I try to apply the change I get this error:</p>

<pre><code>1 error occurred:
        * aws_s3_bucket.logs: 1 error occurred:
        * aws_s3_bucket.logs: Error putting S3 versioning: AccessDenied: Mfa Authentication must be used for this request
        status code: 403, request id: &lt;redacted&gt;, host id: &lt;redacted&gt;
</code></pre>

<p>How can I run Terraform in a mode that uses multi-factor authentication? My IAM account has a Virtual MFA device attached, but that MFA isn't used when I'm terraforming because terraform uses the API Access Key associated with my account.</p>

<amazon-web-services><terraform><authentication>
How do I run Terraform with AWS MFA?
Nic
# How do I run Terraform with AWS MFA?

(Asked by: username_0 on 2020-04-16)

I'm using Terraform with the terraform-provider-aws provider to manage my AWS infrastructure. I'm trying to enable mfa_delete on an S3 bucket, but when I try to apply the change I get this error:
1 error occurred:
        * aws_s3_bucket.logs: 1 error occurred:
        * aws_s3_bucket.logs: Error putting S3 versioning: AccessDenied: Mfa Authentication must be used for this request
        status code: 403, request id: , host id: 

How can I run Terraform in a mode that uses multi-factor authentication? My IAM account has a Virtual MFA device attached, but that MFA isn't used when I'm terraforming because terraform uses the API Access Key associated with my account.

**Tags:** amazon-web-services, terraform, authentication


---

## 5 answers

### Answer by username_1 on 2020-04-22. Score: 4

The solution is to specify an assume_role statement:
provider "aws" {
  profile = "default"
  assume_role {
    role_arn = "arn:aws:iam::[ACCOUNT_ID]:role/terraform-test-role"
  }
}

> **Comments:**
> **username_0**: I'm already using assume_role so I guess there's some additional detail I'm missing.  

---

### Answer by username_2 on 2020-05-10. Score: 1

I was looking into a similar use case and found this github issue in the terraform public repo:
<https://github.com/terraform-providers/terraform-provider-aws/issues/629>

As quoted in that issue:
"Indeed it does seem like the Terraform AWS provider would need to do something special to make this work. As I noted in my other comment, we don't consider Terraform to be an interactive tool in general and so introducing extra interactive input in the apply phase is not ideal."

<https://github.com/terraform-providers/terraform-provider-aws/issues/629#issuecomment-408937315>


---

### Answer by username_3 on 2021-06-21. Score: 1

The error message here is telling you that you are not allowed to enable MFADelete without having an authenticated token with mfa. Meaning the executing principal must have logged in with MFA.
essentially the API call on the cli would be something like this
aws --profile my_profile s3api put-bucket-versioning --bucket bucket-name --versioning configuration 'MFADelete=Enabled,Status=Enabled' --mfa 'arn:aws:iam:::mfa/root-account-mfa-device 

Note that only the root account MFA can do this (the bucket owner) not a standard user. As detailed here
A simple terraform config assuming its executing under the credentials the previous profile specified would be:
resource "aws_s3_bucket" "bucket" {
  bucket = "some_test_bucket"
  acl    = "private"
  
  versioning {
    enabled = true 
    mfa_delete = true
  }
}

Now so far so good, however, it should be noted that mfa_delete = true cannot toggle that setting, it is there to reflect the enabling of that in the state file only as mentioned in the docs
The correct way to set the mfa_delete to enabled is via the API yourself. As mentioned above as the provider cannot change it but has the state there to ensure its not going to change the state after it is set on a subsequent run (out of band terraform changes to enable with the API).
This answer assumes AWS provider v2.65.0 or higher


---

### Answer by username_5 on 2023-05-30. Score: 1

I used the AWS cli to do sts assume-role and then used jq to decompose the response and stored the values in environment variables, which terraform then uses. https://registry.terraform.io/providers/hashicorp/aws/latest/docs#environment-variables
My setup:

A user
A profile in ~/.aws/credentials which has my access/secret
A role which can only use used by the user and requires MFA

    session_token=$(aws sts assume-role \
        --profile ${profile} \
        --role-arn "${role_arn}" \
        --role-session-name "${session_name}" \
        --serial-number "${mfa_serial}" \
        --duration-seconds $session_duration \
        --token-code "${token_code}" \
        --query Credentials)

    export AWS_REGION=${region}
    export AWS_ACCESS_KEY_ID="$(echo $session_token | jq -r .AccessKeyId)"
    export AWS_SECRET_ACCESS_KEY="$(echo $session_token | jq -r .SecretAccessKey)"

    terraform plan


---

### Answer by username_4 on 2020-05-14. Score: 0

Assuming that

* your IAM user can generate an mfa session token via `GetSessionToken`, and
* you have a way of getting this token and applying it in your **~/.aws/credentials** file (this can be done using helper scripts, like <https://github.com/broamski/aws-mfa>)

you don't need to specify anything special in the terraform configuration. You just need to make sure your aws cli profile is configured correctly as described above AND there is a valid token when you run terraform.


---

