在我的项目开始时,有两个Terraform模块:base
和reusable_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_zip
在team_template/scripts
中寻找脚本。
但是在这种情况下,team_template
中实际上没有python代码。我只是想继续使用reusable_module/script
中的python代码。
必须保持文件分离。 (康威定律等)
我该怎么办?
答案 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"
}