尝试将s3用于Terraform后端时,如何解决错误加载状态:AccessDenied:访问被拒绝状态代码:403?

时间:2020-05-17 12:37:43

标签: terraform terraform-provider-aws

我的简单Terraform文件是:

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表。

  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密钥和机密

我在做什么错? 感谢您的帮助!

5 个答案:

答案 0 :(得分:7)

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

  1. 删除 .terraform 目录
  2. 将 access_key 和 secret_key 放在后端块下。像下面给出的代码
  3. 运行 terraform init
  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>"
  }
}

错误应该消失了。

答案 1 :(得分:1)

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

答案 2 :(得分:0)

无法在同一terraform项目中创建计划用作远程状态存储的S3存储桶。您将不得不创建另一个terraform项目,在其中配置状态存储区(+锁定表),或者只是手动创建存储区。

有关更详细的答案,请阅读this

答案 3 :(得分:0)

我用Google搜索了arround,但没有任何帮助。希望这能解决您的问题。我的情况是:我正在将状态从本地迁移到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
tera 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
  }
}

答案 4 :(得分:0)

为了更好的安全性,您可以像这样使用 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
  }
}