简体   繁体   English

无法使用 localstack dynamoDB 锁定 terraform state:UnrecognizedClientException

[英]Can't use localstack dynamoDB to lock terraform state: UnrecognizedClientException

I've been trying to create a local development environment to play with terraform with localstack ( https://github.com/localstack/localstack ) running on docker.我一直在尝试创建一个本地开发环境来使用 terraform 和在 docker 上运行的 localstack ( https://github.com/localstack/localstack )。

I was already able to create a S3 bucket to store the terraform state, but I also wanted to simulate the DynamoDB as lock.我已经能够创建一个 S3 存储桶来存储 terraform state,但我还想将 DynamoDB 模拟为锁。

The configuration is:配置是:

localstack docker-compose.yml:本地堆栈 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"

First terraform:第一个 terraform:

Used as initial bootstrap to create s3 tfstate storage and DynamoDB table for tfstate lock.用作初始引导程序,为 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"
  }
}

Second terraform:第二个 terraform:

Creates resources and will store the state in s3 and use DynamoDB to create lock.创建资源并将 state 存储在 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"
}

Whenever I apply the second terraform, I get this error:每当我应用第二个 terraform 时,我都会收到此错误:

❯ 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.

Anyone have ever tried this or would have idea about what is causing it?任何人都曾经尝试过这个或会知道是什么原因造成的?

This probably happens because you are trying to use real DynamoDB , rather then from localstack .这可能是因为您尝试使用真正的 DynamoDB ,而不是使用localstack To use localstack, you have to add要使用 localstack,您必须添加

dynamodb_endpoint           = "http://localhost:4566"

to your backend.S3 configuration.到您的backend.S3配置。 Once you updated your backend setup, you will have to reinitialize your TF using terraform init .更新backend设置后,您必须使用terraform init重新初始化 TF。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM