From f0ac895cd2752af0a53bd6cf014728ddb773ffa5 Mon Sep 17 00:00:00 2001 From: Benjamin Clark Date: Tue, 17 Sep 2024 18:17:46 +0100 Subject: [PATCH 1/3] Initial module creation --- .terraform-version | 1 + README.md | 51 +++++++++++++++++++++++++++++++++++++++++++++- aws_s3_object.tf | 26 +++++++++++++++++++++++ main.tf | 9 ++++++++ variables.tf | 46 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 .terraform-version create mode 100644 aws_s3_object.tf create mode 100644 main.tf create mode 100644 variables.tf diff --git a/.terraform-version b/.terraform-version new file mode 100644 index 0000000..8e03717 --- /dev/null +++ b/.terraform-version @@ -0,0 +1 @@ +1.5.1 \ No newline at end of file diff --git a/README.md b/README.md index 87f3d4c..f839c38 100644 --- a/README.md +++ b/README.md @@ -42,11 +42,60 @@ The below documentation is intended to assist users in utilising the module, the the module itself, and the [examples](#examples) section which has examples of how to utilise the module. +## Requirements +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | ~> 1.5.0 | +| [aws](#requirement\_aws) | >= 5.61.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | 5.67.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_s3_object.uploaded_files](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_object) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [application\_name](#input\_application\_name) | Name of the application utilising resource. | `string` | n/a | yes | +| [environment](#input\_environment) | Which environment this is being instantiated in. | `string` | n/a | yes | +| [raw\_s3\_files](#input\_raw\_s3\_files) | Data structure
---------------
A list of dictionaries, where each dictionary has the following attributes:

REQUIRED
---------
- name: : Friendly name used through Terraform for instantiation and cross-referencing of resources,
only relates to resource naming within the module.
- source\_folder : Which folder under "application" where the {source\_file} lives.
- source\_file : The path under {source\_folder} corresponding to the file to upload.
- destination\_key : Key in S3 bucket to upload to.
- destination\_bucket : The S3 bucket to upload the {source\_file} to.

OPTIONAL
---------
- template\_input : A dictionary of variable input for the template file needed for instantiation (leave blank if no template required) |
list(
object({
name = string,
source_folder = string,
source_file = string,
destination_key = string,
destination_bucket = string,
template_input = optional(map(string), {})
})
)
| n/a | yes | + +## Outputs + +No outputs. ## Data structure - +``` +Data structure +--------------- +A list of dictionaries, where each dictionary has the following attributes: + +REQUIRED +--------- +- name: : Friendly name used through Terraform for instantiation and cross-referencing of resources, + only relates to resource naming within the module. +- source_folder : Which folder under "application" where the {source_file} lives. +- source_file : The path under {source_folder} corresponding to the file to upload. +- destination_key : Key in S3 bucket to upload to. +- destination_bucket : The S3 bucket to upload the {source_file} to. +OPTIONAL +--------- +- template_input : A dictionary of variable input for the template file needed for instantiation (leave blank if no template required) +``` ## Examples See `examples` folder for an example setup. diff --git a/aws_s3_object.tf b/aws_s3_object.tf new file mode 100644 index 0000000..4d96a29 --- /dev/null +++ b/aws_s3_object.tf @@ -0,0 +1,26 @@ +/* + All of the S3 files are templated, the difference is without input vars we simply get the content verbatim - + this allows flexibility, as we can handle both templated and non-templated input with the same resource(s). +*/ + +locals { + actual_s3_files = flatten([ + for file in var.raw_s3_files : { + name : file.name, + destination_bucket : file.destination_bucket, + destination_key : file.destination_key, + content : templatefile("${file.source_folder}/${file.source_file}", try(file.template_input, {})) + path : "${file.source_folder}/${file.source_file}" + } + ]) +} + +resource "aws_s3_object" "uploaded_files" { + for_each = { for file in local.actual_s3_files : file.name => file } + + bucket = each.value["destination_bucket"] + key = each.value["destination_key"] + content = each.value["content"] + + etag = filemd5(each.value["path"]) +} \ No newline at end of file diff --git a/main.tf b/main.tf new file mode 100644 index 0000000..f022823 --- /dev/null +++ b/main.tf @@ -0,0 +1,9 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.61.0" + } + } + required_version = "~> 1.5.0" +} \ No newline at end of file diff --git a/variables.tf b/variables.tf new file mode 100644 index 0000000..be6028b --- /dev/null +++ b/variables.tf @@ -0,0 +1,46 @@ +# Input variable definitions +variable "environment" { + description = "Which environment this is being instantiated in." + type = string + validation { + condition = contains(["dev", "test", "prod"], var.environment) + error_message = "Must be either dev, test or prod" + } +} + +variable "application_name" { + description = "Name of the application utilising resource." + type = string +} + +variable "raw_s3_files" { + description = < Date: Tue, 17 Sep 2024 18:33:17 +0100 Subject: [PATCH 2/3] Add examples --- .github/workflows/commit-to-pr.yaml | 6 +++--- README.md | 4 ++-- examples/s3_files/.terraform-version | 1 + examples/s3_files/files/plain.json | 4 ++++ examples/s3_files/files/templated.json | 9 ++++++++ examples/s3_files/locals.tf | 29 ++++++++++++++++++++++++++ examples/s3_files/main.tf | 22 +++++++++++++++++++ examples/s3_files/variables.tf | 15 +++++++++++++ variables.tf | 2 +- 9 files changed, 86 insertions(+), 6 deletions(-) create mode 100644 examples/s3_files/.terraform-version create mode 100644 examples/s3_files/files/plain.json create mode 100644 examples/s3_files/files/templated.json create mode 100644 examples/s3_files/locals.tf create mode 100644 examples/s3_files/main.tf create mode 100644 examples/s3_files/variables.tf diff --git a/.github/workflows/commit-to-pr.yaml b/.github/workflows/commit-to-pr.yaml index 2bd9dc0..fe40065 100644 --- a/.github/workflows/commit-to-pr.yaml +++ b/.github/workflows/commit-to-pr.yaml @@ -20,7 +20,7 @@ jobs: validation: strategy: matrix: - folder: ["add", "folders", "here"] + folder: ["./", "./examples/s3_files"] name: Terraform validate for ${{ matrix.folder }} runs-on: ubuntu-20.04 steps: @@ -41,7 +41,7 @@ jobs: linting: strategy: matrix: - folder: ["add", "folders", "here"] + folder: ["./", "./examples/s3_files"] name: Terraform lint for ${{ matrix.folder }} runs-on: ubuntu-20.04 steps: @@ -59,7 +59,7 @@ jobs: plan: strategy: matrix: - folder: ["add", "folders", "here"] + folder: ["./examples/s3_files"] name: Terraform plan for ${{ matrix.folder }} runs-on: ubuntu-20.04 needs: [validation, linting] diff --git a/README.md b/README.md index f839c38..835c176 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ No modules. |------|-------------|------|---------|:--------:| | [application\_name](#input\_application\_name) | Name of the application utilising resource. | `string` | n/a | yes | | [environment](#input\_environment) | Which environment this is being instantiated in. | `string` | n/a | yes | -| [raw\_s3\_files](#input\_raw\_s3\_files) | Data structure
---------------
A list of dictionaries, where each dictionary has the following attributes:

REQUIRED
---------
- name: : Friendly name used through Terraform for instantiation and cross-referencing of resources,
only relates to resource naming within the module.
- source\_folder : Which folder under "application" where the {source\_file} lives.
- source\_file : The path under {source\_folder} corresponding to the file to upload.
- destination\_key : Key in S3 bucket to upload to.
- destination\_bucket : The S3 bucket to upload the {source\_file} to.

OPTIONAL
---------
- template\_input : A dictionary of variable input for the template file needed for instantiation (leave blank if no template required) |
list(
object({
name = string,
source_folder = string,
source_file = string,
destination_key = string,
destination_bucket = string,
template_input = optional(map(string), {})
})
)
| n/a | yes | +| [raw\_s3\_files](#input\_raw\_s3\_files) | Data structure
---------------
A list of dictionaries, where each dictionary has the following attributes:

REQUIRED
---------
- name: : Friendly name used through Terraform for instantiation and cross-referencing of resources,
only relates to resource naming within the module.
- source\_folder : Which folder where the {source\_file} lives.
- source\_file : The path under {source\_folder} corresponding to the file to upload.
- destination\_key : Key in S3 bucket to upload to.
- destination\_bucket : The S3 bucket to upload the {source\_file} to.

OPTIONAL
---------
- template\_input : A dictionary of variable input for the template file needed for instantiation (leave blank if no template required) |
list(
object({
name = string,
source_folder = string,
source_file = string,
destination_key = string,
destination_bucket = string,
template_input = optional(map(string), {})
})
)
| n/a | yes | ## Outputs @@ -88,7 +88,7 @@ REQUIRED --------- - name: : Friendly name used through Terraform for instantiation and cross-referencing of resources, only relates to resource naming within the module. -- source_folder : Which folder under "application" where the {source_file} lives. +- source_folder : Which folder where the {source_file} lives. - source_file : The path under {source_folder} corresponding to the file to upload. - destination_key : Key in S3 bucket to upload to. - destination_bucket : The S3 bucket to upload the {source_file} to. diff --git a/examples/s3_files/.terraform-version b/examples/s3_files/.terraform-version new file mode 100644 index 0000000..8e03717 --- /dev/null +++ b/examples/s3_files/.terraform-version @@ -0,0 +1 @@ +1.5.1 \ No newline at end of file diff --git a/examples/s3_files/files/plain.json b/examples/s3_files/files/plain.json new file mode 100644 index 0000000..ad5c767 --- /dev/null +++ b/examples/s3_files/files/plain.json @@ -0,0 +1,4 @@ +{ + "name": "plain.json", + "description": "I'm a plain file with static content." +} \ No newline at end of file diff --git a/examples/s3_files/files/templated.json b/examples/s3_files/files/templated.json new file mode 100644 index 0000000..3577a94 --- /dev/null +++ b/examples/s3_files/files/templated.json @@ -0,0 +1,9 @@ +{ + "name": "templated.json", + "description": "I'm a file that uses terraform templating syntax to dynamically do things.", + "examples": { + "string": ${string_input}, + "number": ${number_input}, + "list": ${list_input} + } +} \ No newline at end of file diff --git a/examples/s3_files/locals.tf b/examples/s3_files/locals.tf new file mode 100644 index 0000000..a1e24d6 --- /dev/null +++ b/examples/s3_files/locals.tf @@ -0,0 +1,29 @@ +locals { + raw_s3_files = [ + { + name : "plain", + source_folder : "${path.module}/files/", + source_file : "plain.json", + destination_bucket : "asset-bucket", + destination_key : "plain-file.json" + }, + { + name : "templated", + source_folder : "${path.module}/files/", + source_file : "templated.json", + template_input : { + string_input : "Hello World!", + number_input : "42", + list_input : jsonencode([ + "All work and no play makes Jack a dull boy.", + "All work and no play makes Jack a dull boy.", + "All work and no play makes Jack a dull boy.", + "All work and no play makes Jack a dull boy.", + "All work and no play makes Jack a dull boy." + ]) + }, + destination_bucket : "asset-bucket", + destination_key : "templated-file.json" + } + ] +} \ No newline at end of file diff --git a/examples/s3_files/main.tf b/examples/s3_files/main.tf new file mode 100644 index 0000000..c8d012a --- /dev/null +++ b/examples/s3_files/main.tf @@ -0,0 +1,22 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.61.0" + } + } + required_version = "~> 1.5.0" +} + +provider "aws" { + region = "eu-west-2" +} + +module "s3_files" { + source = "github.com/sudoblark/sudoblark.terraform.module.aws.s3_files?ref=1.0.0" + + application_name = var.application_name + environment = var.environment + raw_s3_files = local.raw_s3_files + +} \ No newline at end of file diff --git a/examples/s3_files/variables.tf b/examples/s3_files/variables.tf new file mode 100644 index 0000000..9ccf4b8 --- /dev/null +++ b/examples/s3_files/variables.tf @@ -0,0 +1,15 @@ +variable "environment" { + description = "Which environment this is being instantiated in." + type = string + validation { + condition = contains(["dev", "test", "prod"], var.environment) + error_message = "Must be either dev, test or prod" + } + default = "prod" +} + +variable "application_name" { + description = "Name of the application utilising the resource resource." + type = string + default = "demo-app" +} \ No newline at end of file diff --git a/variables.tf b/variables.tf index be6028b..39f0941 100644 --- a/variables.tf +++ b/variables.tf @@ -24,7 +24,7 @@ REQUIRED --------- - name: : Friendly name used through Terraform for instantiation and cross-referencing of resources, only relates to resource naming within the module. -- source_folder : Which folder under "application" where the {source_file} lives. +- source_folder : Which folder where the {source_file} lives. - source_file : The path under {source_folder} corresponding to the file to upload. - destination_key : Key in S3 bucket to upload to. - destination_bucket : The S3 bucket to upload the {source_file} to. From 9b9de7e895b690d4aa6819fb687796c0fa69b137 Mon Sep 17 00:00:00 2001 From: Benjamin Clark Date: Tue, 17 Sep 2024 19:12:18 +0100 Subject: [PATCH 3/3] Fix linter errors --- README.md | 2 -- examples/s3_files/main.tf | 7 ++----- examples/s3_files/variables.tf | 15 --------------- variables.tf | 15 --------------- 4 files changed, 2 insertions(+), 37 deletions(-) delete mode 100644 examples/s3_files/variables.tf diff --git a/README.md b/README.md index 835c176..8d186d1 100644 --- a/README.md +++ b/README.md @@ -69,8 +69,6 @@ No modules. | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [application\_name](#input\_application\_name) | Name of the application utilising resource. | `string` | n/a | yes | -| [environment](#input\_environment) | Which environment this is being instantiated in. | `string` | n/a | yes | | [raw\_s3\_files](#input\_raw\_s3\_files) | Data structure
---------------
A list of dictionaries, where each dictionary has the following attributes:

REQUIRED
---------
- name: : Friendly name used through Terraform for instantiation and cross-referencing of resources,
only relates to resource naming within the module.
- source\_folder : Which folder where the {source\_file} lives.
- source\_file : The path under {source\_folder} corresponding to the file to upload.
- destination\_key : Key in S3 bucket to upload to.
- destination\_bucket : The S3 bucket to upload the {source\_file} to.

OPTIONAL
---------
- template\_input : A dictionary of variable input for the template file needed for instantiation (leave blank if no template required) |
list(
object({
name = string,
source_folder = string,
source_file = string,
destination_key = string,
destination_bucket = string,
template_input = optional(map(string), {})
})
)
| n/a | yes | ## Outputs diff --git a/examples/s3_files/main.tf b/examples/s3_files/main.tf index c8d012a..2568a5d 100644 --- a/examples/s3_files/main.tf +++ b/examples/s3_files/main.tf @@ -13,10 +13,7 @@ provider "aws" { } module "s3_files" { - source = "github.com/sudoblark/sudoblark.terraform.module.aws.s3_files?ref=1.0.0" - - application_name = var.application_name - environment = var.environment - raw_s3_files = local.raw_s3_files + source = "github.com/sudoblark/sudoblark.terraform.module.aws.s3_files?ref=1.0.0" + raw_s3_files = local.raw_s3_files } \ No newline at end of file diff --git a/examples/s3_files/variables.tf b/examples/s3_files/variables.tf deleted file mode 100644 index 9ccf4b8..0000000 --- a/examples/s3_files/variables.tf +++ /dev/null @@ -1,15 +0,0 @@ -variable "environment" { - description = "Which environment this is being instantiated in." - type = string - validation { - condition = contains(["dev", "test", "prod"], var.environment) - error_message = "Must be either dev, test or prod" - } - default = "prod" -} - -variable "application_name" { - description = "Name of the application utilising the resource resource." - type = string - default = "demo-app" -} \ No newline at end of file diff --git a/variables.tf b/variables.tf index 39f0941..fee3620 100644 --- a/variables.tf +++ b/variables.tf @@ -1,18 +1,3 @@ -# Input variable definitions -variable "environment" { - description = "Which environment this is being instantiated in." - type = string - validation { - condition = contains(["dev", "test", "prod"], var.environment) - error_message = "Must be either dev, test or prod" - } -} - -variable "application_name" { - description = "Name of the application utilising resource." - type = string -} - variable "raw_s3_files" { description = <