You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Terraform跨区域部署存储在us-east-1 S3桶的Lambda代码?

Absolutely, you can deploy Lambda code from a single-region S3 bucket across regions using Terraform—you just need to work around S3's regional endpoint restriction that’s causing that PermanentRedirect error. Here are two reliable approaches:

This method automatically syncs your Lambda code from the us-east-1 bucket to a dedicated us-west-2 bucket. Lambda can then pull the code from a same-region bucket, which eliminates the redirect issue entirely. It’s ideal for ongoing deployments since it keeps your code in sync automatically.

First, set up two AWS providers (one for each region) in your Terraform config, then configure replication:

# Configure AWS providers for both regions
provider "aws" {
  alias  = "us_east_1"
  region = "us-east-1"
}

provider "aws" {
  alias  = "us_west_2"
  region = "us-west-2"
}

# Source bucket (pre-existing in us-east-1)
data "aws_s3_bucket" "lambda_source" {
  provider = aws.us_east_1
  bucket   = "your-precreated-us-east-1-bucket"
}

# Target bucket in us-west-2 for replicated code
resource "aws_s3_bucket" "lambda_target" {
  provider = aws.us_west_2
  bucket   = "your-lambda-code-us-west-2"

  versioning {
    enabled = true # Required for CRR
  }
}

# IAM role for S3 replication
resource "aws_iam_role" "s3_replication_role" {
  name = "lambda-code-replication-role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Principal = {
          Service = "s3.amazonaws.com"
        }
      }
    ]
  })
}

# Policy to grant replication permissions
resource "aws_iam_role_policy" "s3_replication_policy" {
  name = "lambda-code-replication-policy"
  role = aws_iam_role.s3_replication_role.id

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = ["s3:GetObjectVersionForReplication", "s3:GetObjectVersionAcl"]
        Effect   = "Allow"
        Resource = "${data.aws_s3_bucket.lambda_source.arn}/path/to/your/lambda.zip"
      },
      {
        Action = ["s3:ReplicateObject", "s3:ReplicateTags"]
        Effect   = "Allow"
        Resource = "${aws_s3_bucket.lambda_target.arn}/path/to/your/lambda.zip"
      }
    ]
  })
}

# Enable replication from source to target bucket
resource "aws_s3_bucket_replication_configuration" "lambda_code_replication" {
  provider = aws.us_east_1
  bucket   = data.aws_s3_bucket.lambda_source.name
  role     = aws_iam_role.s3_replication_role.arn

  rule {
    id     = "replicate-lambda-code"
    status = "Enabled"

    destination {
      bucket        = aws_s3_bucket.lambda_target.arn
      storage_class = "STANDARD"
    }

    filter {
      prefix = "path/to/your/" # Match the prefix where your Lambda code lives
    }
  }
}

# Deploy Lambda in us-west-2 using the replicated bucket
resource "aws_lambda_function" "cross_region_lambda" {
  provider = aws.us_west_2
  function_name = "my-cross-region-function"
  s3_bucket     = aws_s3_bucket.lambda_target.name
  s3_key        = "path/to/your/lambda.zip"
  handler       = "index.handler"
  runtime       = "nodejs18.x" # Adjust to your runtime
  role          = aws_iam_role.lambda_exec_role.arn # Create this role separately with Lambda permissions
}

Approach 2: Copy Code to Target Region Bucket During Deployment

If you don’t want permanent replication, you can copy the Lambda code from the us-east-1 bucket to a temporary us-west-2 bucket as part of your Terraform workflow. This works well for one-off deployments.

We’ll use a null_resource with the AWS CLI to handle the cross-region copy:

# Configure dual-region providers (same as Approach 1)
provider "aws" {
  alias  = "us_east_1"
  region = "us-east-1"
}

provider "aws" {
  alias  = "us_west_2"
  region = "us-west-2"
}

# Temporary bucket in us-west-2
resource "aws_s3_bucket" "temp_lambda_bucket" {
  provider = aws.us_west_2
  bucket   = "temp-lambda-code-us-west-2"
}

# Fetch metadata from the source S3 object to trigger updates when code changes
data "aws_s3_object" "lambda_source_code" {
  provider = aws.us_east_1
  bucket   = "your-precreated-us-east-1-bucket"
  key      = "path/to/your/lambda.zip"
}

# Copy code from us-east-1 to us-west-2 using AWS CLI
resource "null_resource" "copy_lambda_code" {
  triggers = {
    source_etag = data.aws_s3_object.lambda_source_code.etag # Re-run if code changes
  }

  provisioner "local-exec" {
    command = "aws s3 cp s3://${data.aws_s3_object.lambda_source_code.bucket}/${data.aws_s3_object.lambda_source_code.key} s3://${aws_s3_bucket.temp_lambda_bucket.name}/lambda.zip --region us-west-2"
  }
}

# Deploy Lambda using the temporary bucket
resource "aws_lambda_function" "cross_region_lambda" {
  provider = aws.us_west_2
  function_name = "my-cross-region-function"
  s3_bucket     = aws_s3_bucket.temp_lambda_bucket.name
  s3_key        = "lambda.zip"
  handler       = "index.handler"
  runtime       = "nodejs18.x"
  role          = aws_iam_role.lambda_exec_role.arn

  depends_on = [null_resource.copy_lambda_code] # Wait for copy to finish
}

Why You Saw That Error

When you tried to point the us-west-2 Lambda directly to the us-east-1 S3 bucket, Lambda used the us-west-2 S3 endpoint (s3.us-west-2.amazonaws.com) to fetch the code. S3 responded with a redirect because the bucket lives in a different region, but Lambda’s API doesn’t follow redirects—hence the InvalidParameterValueException.

内容的提问来源于stack exchange,提问作者Todd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:44:06