amazon-web-services - 无法使用 localstack dynamoDB 锁定 terraform 状态 : UnrecognizedClientException

标签 amazon-web-services amazon-dynamodb terraform terraform-provider-aws localstack

我一直在尝试创建一个本地开发环境,以使用在 docker 上运行的 localstack (https://github.com/localstack/localstack) 来使用 terraform。

我已经能够创建一个 S3 存储桶来存储 terraform 状态,但我还想将 DynamoDB 模拟为锁。

配置为:

localstack docker-compose.yml:

version: "3.2"
services:
  localstack:
    image: localstack/localstack:latest
    container_name: localstack
    ports:
      - "4563-4599:4563-4599"
      - "8080:8080"
    environment:
      - DATA_DIR=/tmp/localstack/data
      - DEBUG=1
    volumes:
      - "./.localstack:/tmp/localstack"
      - "/var/run/docker.sock:/var/run/docker.sock"

第一个地形:

用作初始 Bootstrap 来为 tfstate 锁创建 s3 tfstate 存储和 DynamoDB 表。

provider "aws" {
  region                      = "us-east-1"
  access_key                  = "foo"
  secret_key                  = "bar"
  skip_credentials_validation = true
  skip_requesting_account_id  = true
  skip_metadata_api_check     = true
  s3_force_path_style         = true
  endpoints {
    apigateway     = "http://localhost:4566"
    cloudformation = "http://localhost:4566"
    cloudwatch     = "http://localhost:4566"
    dynamodb       = "http://localhost:4566"
    es             = "http://localhost:4566"
    firehose       = "http://localhost:4566"
    iam            = "http://localhost:4566"
    kinesis        = "http://localhost:4566"
    lambda         = "http://localhost:4566"
    route53        = "http://localhost:4566"
    redshift       = "http://localhost:4566"
    s3             = "http://localhost:4566"
    secretsmanager = "http://localhost:4566"
    ses            = "http://localhost:4566"
    sns            = "http://localhost:4566"
    sqs            = "http://localhost:4566"
    ssm            = "http://localhost:4566"
    stepfunctions  = "http://localhost:4566"
    sts            = "http://localhost:4566"
  }
}

resource "aws_s3_bucket" "terraform_state" {
  bucket = "terraform-state"
  acl    = "private"

  versioning {
    enabled = true
  }

  server_side_encryption_configuration {
    rule {
      apply_server_side_encryption_by_default {
        sse_algorithm = "AES256"
      }
    }
  }

  lifecycle {
    prevent_destroy = true
  }
}

resource "aws_s3_bucket_public_access_block" "terraform_state_access" {
  bucket = aws_s3_bucket.terraform_state.id

  block_public_acls       = true
  ignore_public_acls      = true
  block_public_policy     = true
  restrict_public_buckets = true
}

resource "aws_dynamodb_table" "terraform_state_lock" {
  name           = "terraformlock"
  read_capacity  = 5
  write_capacity = 5
  billing_mode   = "PAY_PER_REQUEST"
  hash_key       = "LockID"

  attribute {
    name = "LockID"
    type = "S"
  }
}

第二个地形:

创建资源并将状态存储在 s3 中并使用 DynamoDB 创建锁。

terraform {
  backend "s3" {
    bucket                      = "terraform-state"
    key                         = "main/terraform.tfstate"
    region                      = "us-east-1"
    endpoint                    = "http://localhost:4566"
    skip_credentials_validation = true
    skip_metadata_api_check     = true
    force_path_style            = true
    dynamodb_table              = "terraformlock"
    encrypt                     = true
  }
}

provider "aws" {
  region                      = "us-east-1"
  access_key                  = "foo"
  secret_key                  = "bar"
  skip_credentials_validation = true
  skip_requesting_account_id  = true
  skip_metadata_api_check     = true
  s3_force_path_style         = true
  endpoints {
    apigateway     = "http://localhost:4566"
    cloudformation = "http://localhost:4566"
    cloudwatch     = "http://localhost:4566"
    dynamodb       = "http://localhost:4566"
    es             = "http://localhost:4566"
    ec2            = "http://localhost:4566"
    firehose       = "http://localhost:4566"
    iam            = "http://localhost:4566"
    kinesis        = "http://localhost:4566"
    lambda         = "http://localhost:4566"
    route53        = "http://localhost:4566"
    redshift       = "http://localhost:4566"
    s3             = "http://localhost:4566"
    secretsmanager = "http://localhost:4566"
    ses            = "http://localhost:4566"
    sns            = "http://localhost:4566"
    sqs            = "http://localhost:4566"
    ssm            = "http://localhost:4566"
    stepfunctions  = "http://localhost:4566"
    sts            = "http://localhost:4566"
  }
}

resource "aws_sqs_queue" "test" {
  name = "test"
  tags = {
    "Environment" = "dev"
  }
}

resource "aws_sns_topic" "test" {
  name         = "test"
  display_name = "test"
}

每当我应用第二个地形时,我都会收到此错误:

❯ terraform apply
Acquiring state lock. This may take a few moments...

Error: Error locking state: Error acquiring the state lock: 2 errors occurred:
        * UnrecognizedClientException: The security token included in the request is invalid.
        status code: 400, request id: UEGJV0SQ614NIEDRB93IAF0JQ7VV4KQNSO5AEMVJF66Q9ASUAAJG
        * UnrecognizedClientException: The security token included in the request is invalid.
        status code: 400, request id: U1IRF6CHGK7RM4SQEGVCSU699RVV4KQNSO5AEMVJF66Q9ASUAAJG



Terraform acquires a state lock to protect the state from being written
by multiple users at the same time. Please resolve the issue above and try
again. For most commands, you can disable locking with the "-lock=false"
flag, but this is not recommended.

有人曾经尝试过这个或者知道是什么原因造成的吗?

最佳答案

发生这种情况可能是因为您尝试使用真正的 DynamoDB,而不是来自 localstack。要使用localstack,您必须添加

dynamodb_endpoint           = "http://localhost:4566"

到您的backend.S3配置。更新后端设置后,您必须使用terraform init重新初始化您的TF。

关于amazon-web-services - 无法使用 localstack dynamoDB 锁定 terraform 状态 : UnrecognizedClientException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65873494/

相关文章:

java - ElasticBeanstalk Java, Spring Activity 配置文件

linux - boto 中的用户数据脚本没有被执行

amazon-dynamodb - 使用Boto3使用哈希键和范围键查询DynamoDB

azure - 是否可以与应用程序网关分开配置后端地址池

amazon-web-services - 云信息 : parameterize the name of a parameter?

mysql - AWS RDS 错误 : IAM Database Authentication is not supported for this configuration

algorithm - 如何解决 K8s pod 之间的竞争条件

java - 将 DynamoDB 与 Spring Boot 结合使用时出现错误请求 (404)

azure - 将 SSL 证书附加到 Terraform 中的 Azure 应用程序网关

terraform - 使用 for_each 表达式时在 terraform 中出现不受支持的属性错误