如何解决 Error loading state: AccessDenied: Access Denied status code: 403 当尝试将 s3 用于 terraform 后端时?

How to solve Error loading state: AccessDenied: Access Denied status code: 403 when trying to use s3 for terraform backend?

我的简单地形文件是:

provider "aws" {
  region = "region"
  access_key = "key" 
  secret_key = "secret_key"
}

terraform {
  backend "s3" {
    # Replace this with your bucket name!
    bucket         = "great-name-terraform-state-2"
    key            = "global/s3/terraform.tfstate"
    region         = "eu-central-1"
    # Replace this with your DynamoDB table name!
    dynamodb_table = "great-name-locks-2"
    encrypt        = true
  }
}

resource "aws_s3_bucket" "terraform_state" {
  bucket = "great-name-terraform-state-2"
  # Enable versioning so we can see the full revision history of our
  # state files
  versioning {
    enabled = true
  }
  server_side_encryption_configuration {
    rule {
      apply_server_side_encryption_by_default {
        sse_algorithm = "AES256"
      }
    }
  }
}

resource "aws_dynamodb_table" "terraform_locks" {
  name         = "great-name-locks-2"
  billing_mode = "PAY_PER_REQUEST"
  hash_key     = "LockID"
  attribute {
    name = "LockID"
    type = "S"
    }
}

我想做的就是将我的后端从本地替换为存储在 S3。 我正在执行以下操作:

  1. terraform init(当 terrafrom{} 块是注释时)

  2. terrafrom apply - 我可以在我的 AWS 中看到已创建存储桶和 Dynmpo table。

  3. 现在我取消评论 terrafrom 块并再次 terraform init 我收到以下错误:

Error loading state:
    AccessDenied: Access Denied
        status code: 403, request id: xxx, host id: xxxx

我的 IAM 具有 管理员权限 我正在使用 Terraform v0.12.24 可以看出,我直接在文件中写入我的 AWS 密钥和秘密

我做错了什么?

感谢任何帮助!

无法在同一 Terraform 项目中创建您计划用作远程状态存储的 S3 存储桶。您将必须创建另一个 Terraform 项目,在其中配置您的状态桶(+ 锁表)或仅手动创建桶。

更详细的答案请阅读this

我用谷歌搜索了一下,但没有任何帮助。希望这能解决您的问题。我的案例:我正在将状态从本地迁移到 AWS S3 存储桶。

  1. 注释掉地​​形范围
provider "aws" {
  region = "region"
  access_key = "key" 
  secret_key = "secret_key"
}

#terraform {
#  backend "s3" {
#    # Replace this with your bucket name!
#    bucket         = "great-name-terraform-state-2"
#    key            = "global/s3/terraform.tfstate"
#    region         = "eu-central-1"
#    # Replace this with your DynamoDB table name!
#    dynamodb_table = "great-name-locks-2"
#    encrypt        = true
#  }
#}

resource "aws_s3_bucket" "terraform_state" {
  bucket = "great-name-terraform-state-2"
  # Enable versioning so we can see the full revision history of our
  # state files
  versioning {
    enabled = true
  }
  server_side_encryption_configuration {
    rule {
      apply_server_side_encryption_by_default {
        sse_algorithm = "AES256"
      }
    }
  }
}

resource "aws_dynamodb_table" "terraform_locks" {
  name         = "great-name-locks-2"
  billing_mode = "PAY_PER_REQUEST"
  hash_key     = "LockID"
  attribute {
    name = "LockID"
    type = "S"
    }
}
  1. 运行
terraform init
terraform plan -out test.tfplan
terraform apply "test.tfplan"

创建资源(S3 存储桶和 DynamoDb)

  1. 然后取消注释地形范围,运行
AWS_PROFILE=REPLACE_IT_WITH_YOUR  TF_LOG=DEBUG   terraform init

如果出现错误,只需搜索 X-Amz-Bucket-Region:

-----------------------------------------------------
2020/08/14 15:54:38 [DEBUG] [aws-sdk-go] DEBUG: Response s3/ListObjects Details:
---[ RESPONSE ]--------------------------------------
HTTP/1.1 403 Forbidden
Connection: close
Transfer-Encoding: chunked
Content-Type: application/xml
Date: Fri, 14 Aug 2020 08:54:37 GMT
Server: AmazonS3
X-Amz-Bucket-Region: eu-central-1
X-Amz-Id-2: REMOVED
X-Amz-Request-Id: REMOVED

复制X-Amz-Bucket-Region的值,我的是eu-central-1.

  1. 将您在 terraform 后端配置中的 region 更改为相应的值。
terraform {
  backend "s3" {
    # Replace this with your bucket name!
    bucket         = "great-name-terraform-state-2"
    key            = "global/s3/terraform.tfstate"
    region         = "eu-central-1"
    # Replace this with your DynamoDB table name!
    dynamodb_table = "great-name-locks-2"
    encrypt        = true
  }
}

我也遇到了同样的问题。然后我从我的本地系统中手动删除状态文件。你可以在 .terraform/ 目录下找到 terraform.tfstate 文件,然后再次 运行 init。如果您在 aws cli 中配置了多个配置文件。在 aws 提供程序配置下不提及配置文件将使 terraform 使用默认配置文件。

我以前遇到过这个。 以下是帮助您克服该错误的步骤-

  1. 删除 .terraform 目录
  2. 将 access_key 和 secret_key 放在后端块下。就像下面给出的代码
  3. 运行 地形初始化
  backend "s3" {
    bucket = "great-name-terraform-state-2"
    key    = "global/s3/terraform.tfstate"
    region = "eu-central-1"
    access_key = "<access-key>"
    secret_key = "<secret-key>"
  }
}

错误应该消失了。

为了更好的安全性,您可以使用 shared_credentials_fileprofile 像这样;

provider "aws" {
  region = "region"
  shared_credentials_file = "$HOME/.aws/credentials # default
  profile = "default" # you may change to desired profile
}

terraform {
  backend "s3" {
    profile = "default" # change to desired profile
    # Replace this with your bucket name!
    bucket         = "great-name-terraform-state-2"
    key            = "global/s3/terraform.tfstate"
    region         = "eu-central-1"
    # Replace this with your DynamoDB table name!
    dynamodb_table = "great-name-locks-2"
    encrypt        = true
  }
}

我在 运行 terraform apply 之后遇到了同样的问题; terraform init 工作正常。 None 这里的建议有效,但将我的 shell 从 zsh 切换到 bash 解决了它。

这件事发生在我身上,问题是我试图创建一个名称已经存在的存储桶!

我知道 运行 terraform init 我的凭据在为他们的 Terraform 后端共享同一个 S3 存储桶的其他项目上没有问题。

对我有用的:

rm -rf .terraform/