Answers: <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>
  
Answers: CC BY-SA 4.0
Answers: 2020-04-23T14:39:17.450Z
Answers: I'm already using assume_role so I guess there's some additional detail I'm missing.
Answers: Nic
Answers: CC BY-SA 4.0
Answers: 2020-04-22T10:56:05.320Z
Answers: 2020-04-22T10:56:05.320Z
Answers: Subhash
Answers: <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>
  
Answers: CC BY-SA 4.0
Answers: 2020-05-10T05:39:00.227Z
Answers: 2020-05-10T05:39:00.227Z
Answers: mr-brody
Answers: <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>
  
Answers: CC BY-SA 4.0
Answers: 2021-06-21T09:15:11.320Z
Answers: 2021-06-23T15:02:23.880Z
Answers: 2021-06-23T15:02:23.880Z
Answers: krystan honour
Answers: <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>
  
Answers: CC BY-SA 4.0
Answers: 2020-05-14T09:17:01.267Z
Answers: 2020-05-14T09:17:01.267Z
Answers: dimisjim
Answers: <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>
  
Answers: CC BY-SA 4.0
Answers: 2023-05-30T10:57:42.593Z
Answers: 2023-05-30T15:02:14.213Z
Answers: 2023-05-30T15:02:14.213Z
Answers: Chris Kemp
Body: <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>
  
Tags: <amazon-web-services><terraform><authentication>
Title: How do I run Terraform with AWS MFA?
UserDisplayName: Nic
ThreadText: # 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](https://github.com/terraform-providers/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: <redacted>, host id: <redacted>
  
  ```
  
  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::<account-id>:mfa/root-account-mfa-device <mfacode>
  
  ```
  
  Note that only the root account MFA can do this (the bucket owner) not a standard user. [As detailed here](https://docs.aws.amazon.com/AmazonS3/latest/userguide/Versioning.html#MultiFactorAuthenticationDelete)
  
  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](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket#mfa_delete)
  
  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:
  
  1. A user
  2. A profile in `~/.aws/credentials` which has my access/secret
  3. 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.
  
  
  ---
  
  