簡體   English   中英

無法使用 localstack dynamoDB 鎖定 terraform state:UnrecognizedClientException

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

我一直在嘗試創建一個本地開發環境來使用 terraform 和在 docker 上運行的 localstack ( https://github.com/localstack/localstack )。

我已經能夠創建一個 S3 存儲桶來存儲 terraform state,但我還想將 DynamoDB 模擬為鎖。

配置是:

本地堆棧 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"

第一個 terraform:

用作初始引導程序,為 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"
  }
}

第二個 terraform:

創建資源並將 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"
}

每當我應用第二個 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.

任何人都曾經嘗試過這個或會知道是什么原因造成的?

這可能是因為您嘗試使用真正的 DynamoDB ,而不是使用localstack 要使用 localstack,您必須添加

dynamodb_endpoint           = "http://localhost:4566"

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM