Skip to content

Commit

Permalink
feat: add support for directory type artifacts
Browse files Browse the repository at this point in the history
  • Loading branch information
sgtoj committed Jul 12, 2023
1 parent 595e68a commit d704977
Show file tree
Hide file tree
Showing 20 changed files with 162 additions and 8 deletions.
3 changes: 3 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
"features": {
"ghcr.io/devcontainers/features/docker-in-docker:2.0.1": {},
},
"containerEnv": {
"TF_PLUGIN_CACHE_DIR": "/workspaces/terraform-docker-artifact-packager/tmp/.terraform.d/"
},
"customizations": {
"vscode": {
"settings": {
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ for more details on these variables.
| `docker_build_args` | Additional arguments to pass to Docker during the build process. | `map(string)` | `{}` | no |
| `artifact_dst_directory` | The destination directory on the host machine to which the artifact will be copied. | `string` | "" | no |
| `artifact_src_path` | The path in the Docker container from which to copy the artifact. | `string` | n/a | yes |
| `artifact_src_type` | "The type of artifact to copy. Accepts 'zip' or 'directory'." | `string` | `zip` | no |
| `force_rebuild_id` | A unique identifier that, when changed, will force the Docker image to be rebuilt. | `string` | "" | no |
| `os_compatibility` | The operating system of Terrafrom environment. Accepts 'unix' or 'windows'. | `string` | `unix` | no |

Expand Down
3 changes: 0 additions & 3 deletions example/aws-lambda-fn/provider.tf

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
# Terraform Docker Artifact Packager - AWS Lambda Example
# Terraform Module Example

## AWS Lambda Function

This is an example of using the Terraform Docker Artifact Package module to
package a TypeScript app into a Docker image, extract the compiled JavaScript
file, and use it as the source code for an AWS Lambda function.

## Prerequisites
### Prerequisites

- Terraform installed on your local machine
- Docker installed on your local machine
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module "packager" {
source = "../"
source = "../../"

artifact_src_path = "/tmp/package.zip"
docker_build_context = "${path.module}/fixures/echo-app"
Expand Down
7 changes: 7 additions & 0 deletions examples/aws-lambda-fn/provider.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
provider "aws" {
region = "us-east-1"
}

provider "docker" {
host = "unix:///var/run/docker.sock"
}
10 changes: 10 additions & 0 deletions examples/aws-lambda-fn/version.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
}
docker = {
source = "kreuzwerker/docker"
}
}
}
24 changes: 24 additions & 0 deletions examples/aws-s3-bucket/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Terraform Module Example

## AWS S3 Bucket

This example demonstrates how to use the Artifact Builder Terraform module to
build and deploy a simple static website to AWS S3.

In this example, we have a simple static website composed of HTML files. We use
the Artifact Builder module with `artifact_src_type` set to "directory" to
package the entire website directory as the artifact. This artifact is then
deployed to an AWS S3 bucket, which is configured to host a static website.

This example is intended to show the flexibility of the Artifact Builder module
in handling different artifact types, including whole directories. It also shows
how to integrate the module with other Terraform resources to create a complete
deployment workflow.

### Prerequisites

- Terraform installed on your local machine
- Docker installed on your local machine
- AWS account with the necessary permissions to create Lambda functions and
IAM roles
- AWS CLI installed and configured with your AWS account
16 changes: 16 additions & 0 deletions examples/aws-s3-bucket/fixtures/website/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FROM node:18 as build

WORKDIR /opt/app

COPY . .

# additional build steps here (e.g. npm install)

# ------------------------------------------------------------------ package ---

FROM alpine:latest as package

COPY --from=build /opt/app/assets/ /opt/app/dist/

RUN apk add zip \
&& cd /opt/app/dist
13 changes: 13 additions & 0 deletions examples/aws-s3-bucket/fixtures/website/assets/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>

<head>
<title>My Static Website</title>
</head>

<body>
<h1>Welcome to my static website!</h1>
<p>This is a simple static website hosted on AWS S3 and deployed using a Terraform module.</p>
</body>

</html>
47 changes: 47 additions & 0 deletions examples/aws-s3-bucket/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
locals {
mime_types = {
".html" = "text/html"
".css" = "text/css"
".js" = "application/javascript"
".json" = "application/json"
".png" = "image/png"
".jpg" = "image/jpeg"
".gif" = "image/gif"
".svg" = "image/svg+xml"
}
}

module "artifact_builder" {
source = "../../"

docker_build_context = "${path.module}/fixtures/website"
docker_build_target = "package"
artifact_src_type = "directory"
artifact_src_path = "/opt/app/dist/"
artifact_dst_directory = "${path.module}/dist"
}

resource "random_string" "website_bucket_random_suffix" {
length = 6
special = false
upper = false
}

resource "aws_s3_bucket" "website_bucket" {
bucket = "example-tf-docker-artifact-packager-${random_string.website_bucket_random_suffix.result}"
acl = "public-read"

website {
index_document = "index.html"
}
}

resource "aws_s3_bucket_object" "website_files" {
for_each = fileset(module.artifact_builder.artifact_dst_directory, "**/*")

bucket = aws_s3_bucket.website_bucket.bucket
key = each.value
source = "${module.artifact_builder.artifact_dst_directory}/${each.value}"
content_type = lookup(local.mime_types, regex("\\.[^.]+$", each.value), "binary/octet-stream")
acl = "public-read"
}
8 changes: 8 additions & 0 deletions examples/aws-s3-bucket/provider.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# provider "aws" {
# region = "us-east-1"
# }

provider "docker" {

host = "unix:///var/run/docker.sock"
}
10 changes: 10 additions & 0 deletions examples/aws-s3-bucket/version.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
}
docker = {
source = "kreuzwerker/docker"
}
}
}
9 changes: 7 additions & 2 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,14 @@ locals {

artifact_id = try(random_string.this[0].id, "unknown")
artifact_dst_dir = var.artifact_dst_directory == "" ? "${path.module}/dist" : var.artifact_dst_directory
artifact_dst_path = abspath("${local.artifact_dst_dir}/${module.artifact_label.id}-${local.artifact_id}.zip")
artifact_dst_path = abspath("${local.artifact_dst_dir}/${module.artifact_label.id}-${local.artifact_id}${local.artifact_type_dst_suffix_map[var.artifact_src_type]}")
artifact_src_path = var.artifact_src_path

artifact_type_dst_suffix_map = {
zip = ".zip"
directory = "/"
}

os_script_map = {
windows = <<-EOT
$ARTIFACT_DST_DIR=[System.IO.Path]::GetDirectoryName('$ARTIFACT_DST_PATH')
Expand All @@ -31,7 +36,7 @@ module "artifact_label" {
source = "cloudposse/label/null"
version = "0.25.0"

name = var.name == "" ? "artifact" : var.name
name = coalesce(module.this.name, var.name, "artifact")
label_order = ["name", "attributes"]
context = module.this.context
}
Expand Down
11 changes: 11 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@ variable "artifact_src_path" {
description = "The path in the Docker container from which to copy the artifact."
}

variable "artifact_src_type" {
type = string
description = "The type of artifact to copy. Accepts 'zip' or 'directory'."
default = "zip"

validation {
condition = var.artifact_src_type == "zip" || var.artifact_src_type == "directory"
error_message = "The `artifact_src_type` variable must be set to either 'zip' or 'directory'."
}
}

variable "artifact_dst_directory" {
type = string
description = "The destination directory on the host machine to which the artifact will be copied."
Expand Down

0 comments on commit d704977

Please sign in to comment.