Skip to content

Commit

Permalink
Merge pull request #2 from Flaconi/plt-699
Browse files Browse the repository at this point in the history
PLT-699 - Init module
  • Loading branch information
Engerim authored Nov 10, 2023
2 parents dc2d638 + d9397c3 commit 9c7e364
Show file tree
Hide file tree
Showing 9 changed files with 305 additions and 17 deletions.
2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -1 +1 @@
* @Flaconi/devops
* @Flaconi/devops @Flaconi/platform
4 changes: 2 additions & 2 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
# Setup repository
# ------------------------------------------------------------
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 0

Expand All @@ -59,4 +59,4 @@ jobs:
git diff --quiet || { echo "Build Changes"; git diff; git status; false; }
env:
TARGET: ${{ matrix.target }}
RETRIES: 20
RETRIES: 1
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
# Checkout repository
# ------------------------------------------------------------
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 0

Expand All @@ -47,4 +47,4 @@ jobs:
}
retry make test
env:
RETRIES: 20
RETRIES: 1
83 changes: 71 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
# terraform-module-template
Template for Terraform modules

<!-- Uncomment and replace with your module name
[![lint](https://github.com/flaconi/<MODULENAME>/workflows/lint/badge.svg)](https://github.com/flaconi/<MODULENAME>/actions?query=workflow%3Alint)
[![test](https://github.com/flaconi/<MODULENAME>/workflows/test/badge.svg)](https://github.com/flaconi/<MODULENAME>/actions?query=workflow%3Atest)
[![Tag](https://img.shields.io/github/tag/flaconi/<MODULENAME>.svg)](https://github.com/flaconi/<MODULENAME>/releases)
-->
# terraform-commercetools-custom-applications
Module to setup cloudfront, s3 and ssm for custom applications

[![lint](https://github.com/flaconi/terraform-commercetools-custom-applications/workflows/lint/badge.svg)](https://github.com/flaconi/terraform-commercetools-custom-applications/actions?query=workflow%3Alint)
[![test](https://github.com/flaconi/terraform-commercetools-custom-applications/workflows/test/badge.svg)](https://github.com/flaconi/terraform-commercetools-custom-applications/actions?query=workflow%3Atest)
[![Tag](https://img.shields.io/github/tag/flaconi/terraform-commercetools-custom-applications.svg)](https://github.com/flaconi/terraform-commercetools-custom-applications/releases)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)

<!-- TFDOCS_HEADER_START -->
Expand All @@ -16,7 +14,9 @@ Template for Terraform modules
<!-- TFDOCS_PROVIDER_START -->
## Providers

No providers.
| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 5 |

<!-- TFDOCS_PROVIDER_END -->

Expand All @@ -26,24 +26,83 @@ No providers.
| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | ~> 1.3 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5 |

<!-- TFDOCS_REQUIREMENTS_END -->

<!-- TFDOCS_INPUTS_START -->
## Required Inputs

No required inputs.
The following input variables are required:

### <a name="input_app_name"></a> [app\_name](#input\_app\_name)

Description: application name

Type: `string`

### <a name="input_bucket_name"></a> [bucket\_name](#input\_bucket\_name)

Description: name of the bucket to used to upload the custom application

Type: `string`

### <a name="input_cdn_logging_bucket_name"></a> [cdn\_logging\_bucket\_name](#input\_cdn\_logging\_bucket\_name)

Description: bucket where the cloudfront logs will be send to

Type: `string`

### <a name="input_ssm_name_prefix"></a> [ssm\_name\_prefix](#input\_ssm\_name\_prefix)

Description: prefix for the ssm path for each custom application

Type: `string`

### <a name="input_aws_account_id"></a> [aws\_account\_id](#input\_aws\_account\_id)

Description: aws account id used to build access policy for the cdn to s3

Type: `string`

### <a name="input_applications"></a> [applications](#input\_applications)

Description: map of custom applications to be setup

Type:

```hcl
map(object({
tags = optional(map(string), {})
application_id = string
additional_ssm_parameters = optional(list(object({
name = string
type = optional(string, "SecureString") # String, StringList or SecureString
value = string
})), [])
}))
```

## Optional Inputs

No optional inputs.
The following input variables are optional (have default values):

### <a name="input_tags"></a> [tags](#input\_tags)

Description: Map of custom tags for the provisioned resources

Type: `map(string)`

Default: `{}`

<!-- TFDOCS_INPUTS_END -->

<!-- TFDOCS_OUTPUTS_START -->
## Outputs

No outputs.
| Name | Description |
|------|-------------|
| <a name="output_s3_bucket_arn"></a> [s3\_bucket\_arn](#output\_s3\_bucket\_arn) | The ARN of the bucket. Will be of format arn:aws:s3:::bucketname. |

<!-- TFDOCS_OUTPUTS_END -->

Expand Down
165 changes: 165 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
resource "aws_cloudfront_function" "rewrite_sub_folder_index" {
name = "${var.app_name}-rewrite-sub-folder-index"
runtime = "cloudfront-js-1.0"
comment = "Rewrites each request to the subfolder index.html"
publish = true
code = templatefile("rewrite_subfolder.js.tftpl",
{
applications = jsonencode(keys(var.applications))
}
)
}

module "ssm" {
source = "github.com/Flaconi/terraform-aws-ssm-store?ref=v1.1.0"

for_each = var.applications

tags = merge(each.value.tags, { Project = each.key })

kms_alias = "alias/aws/ssm"

name_prefix = "${var.ssm_name_prefix}/${each.key}/"
parameters = concat([
{
name = "cloudfront_domain_name"
value = module.cdn.cloudfront_distribution_domain_name
},
{
name = "bucket_name"
value = module.s3.s3_bucket_id
},
{
name = "application_id"
value = each.value.application_id
},
], each.value.additional_ssm_parameters)

}

module "cdn" {

create_distribution = length(var.applications) > 0
source = "github.com/terraform-aws-modules/terraform-aws-cloudfront?ref=v3.2.1"
enabled = true
is_ipv6_enabled = true
default_root_object = "index.html"
price_class = "PriceClass_100"

tags = var.tags

create_origin_access_control = true
origin_access_control = {
"${var.app_name}-origin-access-control" = {
description = "Origin access control for s3 bucket ${module.s3.s3_bucket_id}"
origin_type = "s3"
signing_behavior = "always"
signing_protocol = "sigv4"
}
}

origin = {
ctCustomerAppBucket = {
domain_name = module.s3.s3_bucket_bucket_regional_domain_name
origin_access_control = "${var.app_name}-origin-access-control"
}
}

logging_config = {
bucket = var.cdn_logging_bucket_name
prefix = var.app_name
}

geo_restriction = {
restriction_type = "none"
locations = []
}
ordered_cache_behavior = []

default_cache_behavior = {
allowed_methods = ["GET", "HEAD", "OPTIONS"]
cached_methods = ["GET", "HEAD"]
compress = true
query_string = true
target_origin_id = "ctCustomerAppBucket"
query_string_cache_keys = []
cookies_forward = "none"
headers = [
"Access-Control-Request-Headers",
"Access-Control-Request-Method",
"Origin"
]
viewer_protocol_policy = "redirect-to-https"
min_ttl = 0
default_ttl = 3600
max_ttl = 86400

function_association = {
viewer-request = {
function_arn = aws_cloudfront_function.rewrite_sub_folder_index.arn
}
}
}

custom_error_response = [
{
error_caching_min_ttl = 300
error_code = 404
response_code = 200
response_page_path = "/index.html"
},
{
error_caching_min_ttl = 300
error_code = 403
response_code = 200
response_page_path = "/index.html"
}]

viewer_certificate = {
cloudfront_default_certificate = true
minimum_protocol_version = "TLSv1"
}
}

module "s3" {
source = "github.com/terraform-aws-modules/terraform-aws-s3-bucket?ref=v3.15.1"

create_bucket = length(var.applications) > 0
bucket = var.bucket_name
tags = var.tags

acl = "private"
attach_public_policy = false

control_object_ownership = true
object_ownership = "ObjectWriter"
}

resource "aws_s3_bucket_policy" "cloudfront" {
bucket = module.s3.s3_bucket_id
policy = data.aws_iam_policy_document.cloudfront.json
}

data "aws_iam_policy_document" "cloudfront" {
statement {
sid = "AllowCloudFrontServicePrincipalReadOnly"
principals {
type = "Service"
identifiers = ["cloudfront.amazonaws.com"]
}

actions = [
"s3:GetObject",
]

resources = [
"${module.s3.s3_bucket_arn}/*",
]

condition {
test = "StringEquals"
values = ["arn:aws:cloudfront::${var.aws_account_id}:distribution/${module.cdn.cloudfront_distribution_id}"]
variable = "AWS:SourceArn"
}
}
}
4 changes: 4 additions & 0 deletions outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
output "s3_bucket_arn" {
description = "The ARN of the bucket. Will be of format arn:aws:s3:::bucketname."
value = module.s3.s3_bucket_arn
}
11 changes: 11 additions & 0 deletions rewrite_subfolder.js.tftpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
function handler(event) {
var request = event.request;
var uri = request.uri;
var app = ${applications}.find(app => uri.includes(`/$${app}/flaconi-`));

if (app !== undefined) {
request.uri = `/$${app}/index.html`;
}

return request;
}
43 changes: 43 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
variable "app_name" {
description = "application name"
type = string
}

variable "bucket_name" {
description = "name of the bucket to used to upload the custom application"
type = string
}

variable "cdn_logging_bucket_name" {
description = "bucket where the cloudfront logs will be send to"
type = string
}

variable "ssm_name_prefix" {
description = "prefix for the ssm path for each custom application"
type = string
}

variable "tags" {
description = "Map of custom tags for the provisioned resources"
type = map(string)
default = {}
}

variable "aws_account_id" {
description = "aws account id used to build access policy for the cdn to s3"
type = string
}

variable "applications" {
description = "map of custom applications to be setup"
type = map(object({
tags = optional(map(string), {})
application_id = string
additional_ssm_parameters = optional(list(object({
name = string
type = optional(string, "SecureString") # String, StringList or SecureString
value = string
})), [])
}))
}
6 changes: 6 additions & 0 deletions versions.tf
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
terraform {
required_version = "~> 1.3"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5"
}
}
}

0 comments on commit 9c7e364

Please sign in to comment.