Skip to content

Commit e2422ee

Browse files
committed
feat(builder): add npm and python
1 parent 343eba0 commit e2422ee

File tree

6 files changed

+198
-8
lines changed

6 files changed

+198
-8
lines changed

archive.tf

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
resource "random_uuid" "id" {}
2+
3+
data "null_data_source" "dist" {
4+
inputs = {
5+
path = abspath("${path.module}/dist/${random_uuid.id.result}")
6+
}
7+
}
8+
9+
data "null_data_source" "archive" {
10+
inputs = {
11+
path = "${data.null_data_source.dist.outputs.path}.zip"
12+
}
13+
}
14+
15+
resource "null_resource" "build" {
16+
triggers = {
17+
run = timestamp()
18+
}
19+
20+
provisioner "local-exec" {
21+
command = "${path.module}/build.sh"
22+
environment = {
23+
DIST_DIR = data.null_data_source.dist.outputs.path
24+
SOURCE_DIR = var.source_dir
25+
SOURCE_TYPE = var.source_type
26+
PACKAGE_FILE = var.package_file
27+
}
28+
}
29+
}
30+
31+
data "archive_file" "layer" {
32+
type = "zip"
33+
source_dir = data.null_data_source.dist.outputs.path
34+
output_path = data.null_data_source.archive.outputs.path
35+
36+
depends_on = [
37+
null_resource.build
38+
]
39+
}

build.sh

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#!/usr/bin/env bash
2+
3+
set -e
4+
set -o pipefail
5+
set -o xtrace
6+
7+
parse_environment_variables() {
8+
DIST_DIR="${DIST_DIR:?'DIST_DIR variable missing.'}"
9+
}
10+
11+
clean() {
12+
rm -rf "$DIST_DIR"
13+
}
14+
15+
install_dependencies() {
16+
case $PACKAGE_FILE in
17+
18+
*package.json)
19+
install_npm_dependencies
20+
;;
21+
22+
*requirements.txt)
23+
install_pip_dependencies
24+
;;
25+
26+
*Pipfile)
27+
install_pipenv_dependencies
28+
;;
29+
30+
*)
31+
build_from_source_dir
32+
;;
33+
esac
34+
}
35+
36+
install_npm_dependencies() {
37+
local dist_dir="$DIST_DIR/nodejs"
38+
local dist_package_file="$dist_dir/package.json"
39+
mkdir -p "$dist_dir"
40+
41+
cp "$PACKAGE_FILE" "$dist_package_file"
42+
npm install --production --prefix "$dist_dir/"
43+
}
44+
45+
install_pipenv_dependencies() {
46+
local dist_dir="$DIST_DIR/python"
47+
local dist_requirements_file="$dist_dir/requirement.txt"
48+
mkdir -p "$dist_dir"
49+
50+
pipenv lock --requirements >"$dist_requirements_file"
51+
pip install --target "$dist_dir" --requirement="$dist_requirements_file"
52+
}
53+
54+
install_pip_dependencies() {
55+
local dist_dir="$DIST_DIR/python"
56+
mkdir -p "$dist_dir"
57+
58+
pip install --target "$dist_dir" --requirement="$PACKAGE_FILE"
59+
}
60+
61+
build_from_source_dir() {
62+
SOURCE_DIR="${SOURCE_DIR:?'SOURCE_DIR variable missing.'}"
63+
SOURCE_TYPE="${SOURCE_TYPE:?'SOURCE_TYPE variable missing.'}"
64+
65+
local dist_dir="$DIST_DIR/${SOURCE_TYPE}"
66+
mkdir -p "$dist_dir"
67+
68+
pushd "${SOURCE_DIR}" >/dev/null || exit
69+
# shellcheck disable=SC2086
70+
rsync -Ravz ${RSYNC_PATTERN} --exclude="*" --exclude="*.*" "." "$dist_dir"
71+
popd >/dev/null || exit
72+
}
73+
74+
parse_environment_variables
75+
clean
76+
install_dependencies

main.tf

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1-
resource "null_resource" "default" {
2-
1+
resource "aws_lambda_layer_version" "main" {
2+
filename = data.archive_file.layer.output_path
3+
layer_name = var.layer_name
4+
source_code_hash = data.archive_file.layer.output_base64sha256
5+
compatible_runtimes = var.compatible_runtimes
36
}

output.tf

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,24 @@
1+
output "arn" {
2+
value = aws_lambda_layer_version.main.arn
3+
description = "The Amazon Resource Name (ARN) of the Lambda layer with version."
4+
}
15

6+
output "layer_arn" {
7+
value = aws_lambda_layer_version.main.layer_arn
8+
description = "The Amazon Resource Name (ARN) of the Lambda layer without version."
9+
}
10+
11+
output "version" {
12+
value = aws_lambda_layer_version.main.layer_arn
13+
description = "The Lamba layer version."
14+
}
15+
16+
output "created_date" {
17+
value = aws_lambda_layer_version.main.created_date
18+
description = "The date the layer was created."
19+
}
20+
21+
output "source_code_size" {
22+
value = aws_lambda_layer_version.main.source_code_size
23+
description = "The size in bytes of the layer .zip file."
24+
}

tests/main.tf

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ terraform {
44
backend "local" {}
55
}
66

7-
module "module" {
8-
source = "../"
7+
provider "aws" {
8+
region = "eu-central-1"
9+
}
10+
11+
module "layer" {
12+
source = "../"
13+
layer_name = "dependencies"
14+
package_file = "Pipfile"
915
}

variables.tf

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,48 @@
1-
variable "enabled" {
2-
type = bool
3-
description = "(Optional) Set whether to enable the module. Defaults to true."
4-
default = true
1+
variable "compatible_runtimes" {
2+
type = list(string)
3+
description = "(Optional) A list of Runtimes this layer is compatible with. Up to 5 runtimes can be specified."
4+
5+
default = null
6+
}
7+
8+
variable "layer_name" {
9+
type = string
10+
description = "(Required) A unique name for the Lambda Layer."
11+
}
12+
13+
variable "description" {
14+
type = string
15+
description = "(Optional) Description of what the Lambda layer does."
16+
17+
default = null
18+
}
19+
20+
variable "package_file" {
21+
type = string
22+
description = "(Optional) The location of the package manager config file. Can be one of (package.json, requirements.txt, Pipfile)"
23+
24+
default = null
25+
}
26+
27+
variable "source_dir" {
28+
type = string
29+
description = "(Optional) The location of the Lamvda layer source code. Requires source_type to be defined."
30+
31+
default = null
32+
}
33+
34+
variable "source_type" {
35+
type = string
36+
description = "(Optional) The location of the Lambda layer source type. Can be one of (nodejs, python)"
37+
38+
default = null
39+
}
40+
41+
variable "rsync_pattern" {
42+
type = list(string)
43+
description = "(Optional) A list of rsync pattern to include or exclude files and directories."
44+
45+
default = [
46+
"--include=*"
47+
]
548
}

0 commit comments

Comments
 (0)