如何解决此“错误归档目录:无法归档丢失的目录”

时间:2019-07-16 09:28:49

标签: terraform

在我的项目开始时,有两个Terraform模块:basereusable_module

base / main.tf

# Provide abstraction to define a lambda function
terraform {
  required_version = "0.11.7"
}

variable "env" {}
variable "role" {}
variable "function_name" {
  default = ""
}
variable "lambda_filename" {}
variable "script_env_vars" {
  type = "map"
}

data "archive_file" "package_zip" {
  type = "zip"
  # There is a bug in Terraform which does not allow '..' in source_dir, thus we use path.root:
  # https://github.com/terraform-providers/terraform-provider-archive/issues/5
  source_dir = "${path.root}/scripts/"  # Path from top level module.
  # The output path has to be relative. Otherwise the buildkite will always show a diff.
  output_path = "./.terraform/${var.env}-${var.lambda_filename}.zip"
}

resource "aws_lambda_function" "lambda" {
  function_name = "${var.function_name}"
  description = "Simple function"
  role = "${var.role}"

  runtime = "python3.6"
  timeout = 300  // seconds. Max hard limit is 5 min.

  filename = "${data.archive_file.package_zip.output_path}"
  // The handler is always the file name + function name "handler".
  handler = "${var.lambda_filename}.handler"
  source_code_hash = "${data.archive_file.package_zip.output_base64sha256}"

  // Environment variables for the script.
  environment {
    variables = "${var.script_env_vars}"
  }
}

reusable_module / main.tf

variable "env" {}
variable "region" {}
variable "function_name" {}

provider "aws" {
  region = "${var.region}"
}

resource "aws_iam_role" "mylambda_role" {
  name = "${var.env}-mylambda-role"

  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}
EOF
}

locals {
    default_function_name = "${var.env}-mylambda"
    final_function_name = "${var.function_name != "" ? var.function_name : local.default_function_name}"
}

module "mylambda" {
    source = "../base"
    lambda_filename = "mylambda"
    function_name = "${local.final_function_name}"
    env = "${var.env}"
    role = "${aws_iam_role.mylambda_role.arn}"
    script_env_vars = {
      DUMMY = "123"
    }
}

模块mylambda使用base/main.tf创建一个lambda函数。

reusable_module下,有一个scripts目录,所有Python脚本都存放在该目录中。

现在,我想通过为不同的团队重用并实例化此reusable_module/main.tf来扩展我的项目。

team_template / main.tf

variable "env" {}
variable "region" {}
variable "team" {}


module "team_template" {
  source = "../reusable_module"
  env = "${var.env}"
  region = "${var.region}"
  function_name = "${var.team}-essential-function"
}

# More resources specific to team_template

team-sales / main.tf

用于为每个团队创建lambda

variable "env" {}
variable "region" {}

module "realdeal" {
  source = "../team_template"
  env = "${var.env}"
  region = "${var.region}"
  team = "sales"
}
# More stuff tailored for each teams

当我在团队销售中运行terraform plan -var-file=dev.tfvars时,出现以下错误:

  

data.archive_file.package_zip:刷新状态...

     

错误:错误刷新状态:发生1个错误:

     
      
  • module.realdeal.module.team_template.module.mylambda.data.archive_file.package_zip:   发生1个错误:

  •   
  • module.realdeal.module.team_template.module.mylambda.data.archive_file.package_zip:   data.archive_file.package_zip:归档目录错误:无法   存档缺少目录:   / Users / antkong / Documents / Personal / wd / StackoverflowCode / terraform / lambda / team / scripts /

  •   

问题是data.archive_file.package_zipteam_template/scripts中寻找脚本。

但是在这种情况下,team_template中实际上没有python代码。我只是想继续使用reusable_module/script中的python代码。

必须保持文件分离。 (康威定律等)

我该怎么办?

2 个答案:

答案 0 :(得分:1)

您可以考虑将base和reusable_module合并到一个模块,并使用path.module变量获取模块路径,因为terraform默认解析相对于当前工作目录的路径。

所以在您的情况下:

source_dir = "${path.module}/scripts/" # Path from top level module.

编辑:

如果代码无法合并,则可以将path.module作为变量从reusable_module传递给base,然后使用变量代替path.root

答案 1 :(得分:1)

也许不适用于你的问题,但当我遇到同样的错误时适用于我的。

如果您错误地将 source_dir 用于 source_file 而不是 archive_file,您会得到同样的错误。

例如改变这个:

data "archive_file" "source" {
  type         = "zip"
  source_dir   = "${path.module}/lambda_function.py"
  output_path  = "${path.module}/function.zip"
}

为此:

data "archive_file" "source" {
  type         = "zip"
  source_file  = "${path.module}/lambda_function.py"
  output_path  = "${path.module}/function.zip"
}