Update modules and organization files

Co-authored-by: Ezequiel Bellver <ebellver@itba.edu.ar>
This commit is contained in:
Santiago Lo Coco 2022-10-22 18:50:18 -03:00
parent 98c749f695
commit 53d8edd5bc
38 changed files with 617 additions and 246 deletions

3
.gitignore vendored
View File

@ -57,4 +57,5 @@ venv.bak/
.terraform/ .terraform/
.terraform.* .terraform.*
terraform.tfstate* terraform.tfstate*
.terraform* .terraform*
.fleet

View File

@ -0,0 +1,61 @@
# ---------------------------------------------------------------------------
# Amazon API Gateway
# ---------------------------------------------------------------------------
resource "aws_api_gateway_rest_api" "this" {
name = var.name
description = var.description
tags = var.tags
}
resource "aws_api_gateway_resource" "this" {
path_part = "resource"
parent_id = aws_api_gateway_rest_api.this.root_resource_id
rest_api_id = aws_api_gateway_rest_api.this.id
}
resource "aws_api_gateway_method" "this" {
rest_api_id = aws_api_gateway_rest_api.this.id
resource_id = aws_api_gateway_resource.this.id
http_method = "ANY"
authorization = "NONE"
}
resource "aws_api_gateway_integration" "this" {
rest_api_id = aws_api_gateway_rest_api.this.id
resource_id = aws_api_gateway_resource.this.id
http_method = aws_api_gateway_method.this.http_method
integration_http_method = "ANY"
type = "AWS_PROXY"
uri = var.lambda_function_arn
}
resource "aws_api_gateway_deployment" "this" {
rest_api_id = aws_api_gateway_rest_api.this.id
triggers = {
redeployment = sha1(jsonencode([
aws_api_gateway_resource.this.id,
aws_api_gateway_method.this.id,
aws_api_gateway_integration.this.id,
]))
}
lifecycle {
create_before_destroy = true
}
}
resource "aws_api_gateway_stage" "this" {
deployment_id = aws_api_gateway_deployment.this.id
rest_api_id = aws_api_gateway_rest_api.this.id
stage_name = "production"
}
resource "aws_lambda_permission" "this" {
statement_id = "AllowExecutionFromAPIGateway"
action = "lambda:InvokeFunction"
function_name = var.lambda_function_name
principal = "apigateway.amazonaws.com"
source_arn = "${var.lambda_source_arn}:${aws_api_gateway_rest_api.this.id}/*/${aws_api_gateway_method.this.http_method}${aws_api_gateway_resource.this.path}"
}

View File

@ -0,0 +1,19 @@
# --------------------------------------------------------------------
# Amazon API Gateway outputs
# --------------------------------------------------------------------
output "api_endpoint" {
value = aws_api_gateway_stage.this.invoke_url
}
output "api_rest_id" {
value = aws_api_gateway_resource.this.rest_api_id
}
output "api_resource_path" {
value = aws_api_gateway_resource.this.path
}
output "api_http_method" {
value = aws_api_gateway_method.this.http_method
}

View File

@ -0,0 +1,35 @@
# ------------------------------------------------------------------------
# Amazon API Gateway variables
# ------------------------------------------------------------------------
variable "name" {
description = "The name of the API."
type = string
default = ""
}
variable "description" {
description = "The description of the API."
type = string
default = null
}
variable "tags" {
description = "A mapping of tags to assign to API gateway resources."
type = map(string)
default = {}
}
variable "lambda_function_arn" {
description = "The ARN of the Lambda function."
type = string
}
variable "lambda_source_arn" {
type = string
}
variable "lambda_function_name" {
description = "Name of the lambda function"
type = string
}

View File

@ -0,0 +1,10 @@
terraform {
required_version = ">= 1.0.6"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 4.10.0"
}
}
}

View File

@ -0,0 +1,66 @@
# ---------------------------------------------------------------------------
# Amazon Cloudfront
# ---------------------------------------------------------------------------
resource "aws_cloudfront_distribution" "this" {
web_acl_id = var.web_acl_id
tags = var.tags
enabled = var.enabled
default_root_object = var.default_root_object
dynamic "origin" {
for_each = var.origin
content {
domain_name = origin.value.domain_name
origin_id = lookup(origin.value, "origin_id", origin.key)
origin_path = lookup(origin.value, "origin_path", "")
dynamic "custom_origin_config" {
for_each = length(lookup(origin.value, "custom_origin_config", "")) == 0 ? [] : [lookup(origin.value, "custom_origin_config", "")]
content {
http_port = custom_origin_config.value.http_port
https_port = custom_origin_config.value.https_port
origin_protocol_policy = custom_origin_config.value.origin_protocol_policy
origin_ssl_protocols = custom_origin_config.value.origin_ssl_protocols
}
}
}
}
dynamic "default_cache_behavior" {
for_each = [var.default_cache_behavior]
iterator = i
content {
target_origin_id = i.value["target_origin_id"]
viewer_protocol_policy = i.value["viewer_protocol_policy"]
allowed_methods = lookup(i.value, "allowed_methods", ["GET", "HEAD", "OPTIONS"])
cached_methods = lookup(i.value, "cached_methods", ["GET", "HEAD"])
min_ttl = lookup(i.value, "min_ttl", null)
default_ttl = lookup(i.value, "default_ttl", null)
max_ttl = lookup(i.value, "max_ttl", null)
forwarded_values {
query_string = false
cookies {
forward = "none"
}
}
}
}
restrictions {
geo_restriction {
restriction_type = "none"
}
}
viewer_certificate {
cloudfront_default_certificate = true
}
}

View File

@ -0,0 +1,39 @@
# ---------------------------------------------------------------------------
# Amazon Cloudfront variables
# ---------------------------------------------------------------------------
variable "web_acl_id" {
description = "Id or ARN of the AWS WAF web ACL that is associated with the distribution."
type = string
default = null
}
variable "tags" {
description = "A map of tags to assign to the resource."
type = map(string)
default = null
}
variable "origin" {
description = "One or more origins for this distribution."
type = any
default = null
}
variable "default_root_object" {
description = "The object that you want CloudFront to return (for example, index.html) when an end user requests the root URL."
type = string
default = null
}
variable "default_cache_behavior" {
description = "The default cache behavior for this distribution"
type = any
default = null
}
variable "enabled" {
description = "Whether the distribution is enabled to accept end user requests for content."
type = bool
default = true
}

View File

@ -0,0 +1,27 @@
# ---------------------------------------------------------------------------
# Amazon DynamoDB
# ---------------------------------------------------------------------------
resource "aws_dynamodb_table" "this" {
name = var.name
read_capacity = var.read_capacity
write_capacity = var.write_capacity
billing_mode = var.billing_mode
# attribute {
# name = var.hash_key
# type = "S"
# }
dynamic "attribute" {
for_each = var.attributes
content {
name = attribute.value.name
type = attribute.value.type
}
}
hash_key = var.hash_key
tags = var.tags
}

View File

@ -0,0 +1,3 @@
# --------------------------------------------------------------------
# DynamoDB outputs
# --------------------------------------------------------------------

View File

@ -0,0 +1,51 @@
# ---------------------------------------------------------------------------
# Amazon DynamoDB variables
# ---------------------------------------------------------------------------
variable "name" {
description = "Name of the DynamoDB table."
type = string
default = null
}
variable "hash_key" {
description = "The attribute to use as the hash (partition) key."
type = string
default = null
}
variable "range_key" {
description = "The attribute to use as the range (sort) key."
type = string
default = null
}
variable "billing_mode" {
description = "Controls how you are billed for read/write throughput and how you manage capacity."
type = string
default = "PROVISIONED"
}
variable "write_capacity" {
description = "The number of write units for this table."
type = number
default = 20
}
variable "read_capacity" {
description = "The number of read units for this table."
type = number
default = 20
}
variable "attributes" {
description = "List of nested attribute definitions (used for hash and range key)."
type = list(map(string))
default = []
}
variable "tags" {
description = "A map of tags to add to all resources"
type = map(string)
default = {}
}

View File

@ -0,0 +1,10 @@
terraform {
required_version = ">= 1.0.6"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 4.10.0"
}
}
}

View File

@ -3,23 +3,18 @@
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
resource "aws_lambda_function" "this" { resource "aws_lambda_function" "this" {
filename = var.package
filename = var.lambda_info.filename function_name = var.function_name
function_name = var.lambda_info.function_name role = var.iam_role
role = var.iam_role_arn handler = var.handler
handler = var.lambda_info.handler
runtime = var.runtime runtime = var.runtime
tags = var.tags
tags = { dynamic "vpc_config" {
name = "lambda${var.lambda_info.function_name}" for_each = var.vpc_subnet_ids != null && var.vpc_security_group_ids != null ? [true] : []
content {
security_group_ids = var.vpc_security_group_ids
subnet_ids = var.vpc_subnet_ids
}
} }
} }
resource "aws_lambda_permission" "this" {
statement_id = "AllowExecutionFromAPIGateway"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.this.function_name
principal = "apigateway.amazonaws.com"
source_arn = "${var.apigw_execution_arn}/*/${var.lambda_info.method}${var.lambda_info.path}"
}

View File

@ -1,9 +1,13 @@
output "invoke_arn" { # --------------------------------------------------------------------
description = "The lambda function's invoke ARN" # Lambda outputs
# --------------------------------------------------------------------
output "lambda_function_arn" {
description = "The ARN of the Lambda Function"
value = aws_lambda_function.this.invoke_arn value = aws_lambda_function.this.invoke_arn
} }
output "function_name" { output "lambda_function_name" {
description = "The lambda function's name" description = "The name of the Lambda Function"
value = aws_lambda_function.this.function_name value = aws_lambda_function.this.function_name
} }

View File

@ -2,43 +2,57 @@
# Amazon Lambda variables # Amazon Lambda variables
# ------------------------------------------------------------------------ # ------------------------------------------------------------------------
variable "account_id" { variable "package" {
description = "The absolute path to an existing zip-file to use."
type = string type = string
description = "The current Accound ID" default = null
} }
variable "local_path" {
variable "function_name" {
description = "A unique name for your Lambda Function."
type = string type = string
description = "Local path" default = ""
} }
variable "lambda_info" { variable "handler" {
type = map(string) description = "Lambda Function entrypoint in your code."
description = "Contains all necesary lambda info"
}
variable "apigw_execution_arn" {
type = string type = string
description = "API GW execution ARN" default = ""
}
variable "subnet_ids" {
type = list(any)
description = "The list of subnets created"
}
variable "sg_ids" {
type = list(any)
description = "The list of subnets created"
} }
variable "runtime" { variable "runtime" {
description = "Lambda Function runtime."
type = string type = string
description = "Lambda function runtime language" default = ""
default = "python3.12"
} }
variable "iam_role_arn" { variable "iam_role" {
description = "IAM role ARN attached to the Lambda Function."
type = string type = string
description = "IAM role arn" default = ""
}
variable "tags" {
description = "A mapping of tags to assign to API gateway resources."
type = map(string)
default = {}
}
variable "source_arn" {
description = "Lambda source ARN."
type = string
default = ""
}
variable "vpc_subnet_ids" {
description = "List of subnet ids when Lambda Function should run in the VPC."
type = list(string)
default = null
}
variable "vpc_security_group_ids" {
description = "List of security group ids when Lambda Function should run in the VPC."
type = list(string)
default = null
} }

View File

@ -3,15 +3,14 @@
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
data "aws_iam_policy_document" "this" { data "aws_iam_policy_document" "this" {
statement {
statement { sid = "PublicReadGetObject"
sid = "PublicReadGetObject" effect = "Allow"
effect = "Allow" actions = ["s3:GetObject"]
actions = ["s3:GetObject"] principals {
principals { type = "AWS"
type = "AWS" identifiers = ["*"]
identifiers = ["*"]
}
resources = ["${aws_s3_bucket.this.arn}/*"]
} }
} resources = ["${aws_s3_bucket.this.arn}/*"]
}
}

View File

@ -4,44 +4,44 @@
# 1 - S3 bucket # 1 - S3 bucket
resource "aws_s3_bucket" "this" { resource "aws_s3_bucket" "this" {
bucket = var.bucket_name bucket = var.bucket_name
object_lock_enabled = false object_lock_enabled = false
} }
# 2 -Bucket policy # 2 -Bucket policy
resource "aws_s3_bucket_policy" "this" { resource "aws_s3_bucket_policy" "this" {
count = var.objects != {} ? 1 : 0 count = var.objects != {} ? 1 : 0
bucket = aws_s3_bucket.this.id bucket = aws_s3_bucket.this.id
policy = data.aws_iam_policy_document.this.json policy = data.aws_iam_policy_document.this.json
} }
# 3 -Website configuration # 3 -Website configuration
resource "aws_s3_bucket_website_configuration" "this" { resource "aws_s3_bucket_website_configuration" "this" {
bucket = aws_s3_bucket.this.id bucket = aws_s3_bucket.this.id
index_document { index_document {
suffix = "index.html" suffix = "index.html"
} }
error_document { error_document {
key = "error.html" key = "error.html"
} }
} }
# 4 - Access Control List # 4 - Access Control List
resource "aws_s3_bucket_acl" "this" { resource "aws_s3_bucket_acl" "this" {
bucket = aws_s3_bucket.this.id bucket = aws_s3_bucket.this.id
acl = var.bucket_acl acl = var.bucket_acl
} }
# 5 - Upload objects # 5 - Upload objects
resource "aws_s3_object" "this" { resource "aws_s3_object" "this" {
for_each = try(var.objects, {}) #{ for object, key in var.objects: object => key if try(var.objects, {}) != {} } for_each = try(var.objects, {}) #{ for object, key in var.objects: object => key if try(var.objects, {}) != {} }
bucket = aws_s3_bucket.this.id bucket = aws_s3_bucket.this.id
key = try(each.value.rendered, replace(each.value.filename, "html/", "")) # remote path key = try(each.value.rendered, replace(each.value.filename, "html/", "")) # remote path
source = try(each.value.rendered, format("../../resources/%s", each.value.filename)) # where is the file located source = try(each.value.rendered, format("./../resources/%s", each.value.filename)) # where is the file located
content_type = each.value.content_type content_type = each.value.content_type
storage_class = try(each.value.tier, "STANDARD") storage_class = try(each.value.tier, "STANDARD")
} }

View File

@ -3,16 +3,16 @@
# -------------------------------------------------------------------- # --------------------------------------------------------------------
output "id" { output "id" {
description = "The bucket domain name. Will be of format bucketname.s3.amazonaws.com" description = "The bucket domain name. Will be of format bucketname.s3.amazonaws.com."
value = aws_s3_bucket.this.id value = aws_s3_bucket.this.id
} }
output "arn" { output "arn" {
description = "The ARN of the bucket. Will be of format arn:aws:s3:::bucketname" description = "The ARN of the bucket. Will be of format arn:aws:s3:::bucketname."
value = aws_s3_bucket.this.arn value = aws_s3_bucket.this.arn
} }
output "website_endpoint" { output "website_endpoint" {
description = "The website endpoint, if the bucket is configured with a website. If not, this will be an empty string" description = "The website endpoint, if the bucket is configured with a website. If not, this will be an empty string."
value = aws_s3_bucket.this.website_endpoint value = aws_s3_bucket.this.website_endpoint
} }

View File

@ -21,6 +21,6 @@ variable "block_public_access" {
variable "bucket_acl" { variable "bucket_acl" {
type = string type = string
default = "private" default = "private"
description = "The canned ACL to apply. Valid values are private, public-read, public-read-write, aws-exec-read, authenticated-read, and log-delivery-write. Defaults to private. For more information about these settings, see the AWS S3 documentation: https://docs.aws.amazon.com/AmazonS3/latest/userguide/acl-overview.html#canned-acl" description = "The canned ACL to apply. Valid values are private, public-read, public-read-write, aws-exec-read, authenticated-read, and log-delivery-write. Defaults to private. For more information about these settings, see the AWS S3 documentation: https://docs.aws.amazon.com/AmazonS3/latest/userguide/acl-overview.html#canned-acl"
} }

View File

@ -1,10 +1,10 @@
terraform { terraform {
required_version = ">= 1.0.6" required_version = ">= 1.0.6"
required_providers { required_providers {
aws = { aws = {
source = "hashicorp/aws" source = "hashicorp/aws"
version = ">= 4.10.0" version = ">= 4.10.0"
}
} }
} }
}

View File

@ -0,0 +1,19 @@
# ------------------------------------------------------------------------------
# Amazon Simple Queue Service
# ------------------------------------------------------------------------------
resource "aws_sqs_queue" "terraform_queue" {
name = "terraform-example-queue"
delay_seconds = 90
max_message_size = 2048
message_retention_seconds = 86400
receive_wait_time_seconds = 10
redrive_policy = jsonencode({
deadLetterTargetArn = aws_sqs_queue.terraform_queue_deadletter.arn
maxReceiveCount = 4
})
tags = {
Environment = "production"
}
}

View File

@ -0,0 +1,21 @@
module "apigw" {
source = "../modules/apigw"
providers = {
aws = aws.aws
}
depends_on = [
module.lambda
]
name = "AWSAPIGateway-g3"
description = "..."
lambda_function_arn = module.lambda["lambda"].lambda_function_arn
lambda_function_name = "lambda"
lambda_source_arn = "arn:aws:execute-api:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}"
tags = {
name = "Api Gateway"
}
}

View File

@ -1,65 +0,0 @@
# ---------------------------------------------------------------------------
# Amazon API Gateway
# ---------------------------------------------------------------------------
resource "aws_api_gateway_rest_api" "this" {
provider = aws.aws
name = "AWSAPIGateway-${local.bucket_name}"
description = "This lab was created by the Cloud Computing team"
}
resource "aws_api_gateway_resource" "this" {
provider = aws.aws
path_part = "resource"
parent_id = aws_api_gateway_rest_api.this.root_resource_id
rest_api_id = aws_api_gateway_rest_api.this.id
}
resource "aws_api_gateway_method" "this" {
provider = aws.aws
rest_api_id = aws_api_gateway_rest_api.this.id
resource_id = aws_api_gateway_resource.this.id
http_method = "GET"
authorization = "NONE"
}
resource "aws_api_gateway_integration" "this" {
provider = aws.aws
rest_api_id = aws_api_gateway_rest_api.this.id
resource_id = aws_api_gateway_resource.this.id
http_method = aws_api_gateway_method.this.http_method
integration_http_method = "POST"
type = "AWS_PROXY"
uri = aws_lambda_function.this.invoke_arn
}
resource "aws_api_gateway_deployment" "this" {
provider = aws.aws
rest_api_id = aws_api_gateway_rest_api.this.id
triggers = {
redeployment = sha1(jsonencode([
# aws_api_gateway_rest_api.this.body,
aws_api_gateway_resource.this.id,
aws_api_gateway_method.this.id,
aws_api_gateway_integration.this.id,
]))
}
lifecycle {
create_before_destroy = true
}
}
resource "aws_api_gateway_stage" "this" {
provider = aws.aws
deployment_id = aws_api_gateway_deployment.this.id
rest_api_id = aws_api_gateway_rest_api.this.id
stage_name = "production"
}

View File

@ -1,25 +0,0 @@
# ---------------------------------------------------------------------------
# AWS Lambda resources
# ---------------------------------------------------------------------------
# Lambda
resource "aws_lambda_permission" "apigw_lambda" {
provider = aws.aws
statement_id = "AllowExecutionFromAPIGateway"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.this.function_name
principal = "apigateway.amazonaws.com"
source_arn = "arn:aws:execute-api:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:${aws_api_gateway_rest_api.this.id}/*/${aws_api_gateway_method.this.http_method}${aws_api_gateway_resource.this.path}"
}
resource "aws_lambda_function" "this" {
provider = aws.aws
filename = "${local.path}/lambda/lambda.zip"
function_name = "AWSLambdaHandler-${replace(local.bucket_name, "-", "")}"
role = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/LabRole"
handler = "lambda_handler.main"
runtime = "python3.9"
}

View File

@ -1,3 +0,0 @@
output "api_endpoint" {
value = aws_api_gateway_stage.this.invoke_url
}

View File

@ -1,32 +0,0 @@
# ---------------------------------------------------------------------------
# Amazon S3 resources
# ---------------------------------------------------------------------------
module "s3" {
for_each = local.s3
source = "../../modules/s3"
providers = {
aws = aws.aws
}
bucket_name = each.value.bucket_name
objects = try(each.value.objects, {})
}
resource "aws_s3_object" "this" {
provider = aws.aws
bucket = module.s3["website"].id
key = "index.html"
content = data.template_file.userdata.rendered
content_type = "text/html"
storage_class = "STANDARD"
}
# Another way to use it, is to directly pass the following arguments to the resource
# templatefile("../../resources/html/index.html",
# {
# ENDPOINT = aws_api_gateway_rest_api.this.arn
# })

View File

@ -0,0 +1,53 @@
module "cloudfront" {
source = "../modules/cloudfront"
depends_on = [module.s3, module.apigw]
providers = {
aws = aws.aws
}
enabled = true
origin = {
api-gateway = {
domain_name = replace(replace(module.apigw.api_endpoint, "https://", ""), "/", "")
custom_origin_config = {
http_port = 80
https_port = 443
origin_protocol_policy = "match-viewer"
origin_ssl_protocols = ["TLSv1", "TLSv1.1", "TLSv1.2"]
}
}
s3 = {
domain_name = module.s3["website"].website_endpoint
custom_origin_config = {
http_port = 80
https_port = 443
origin_protocol_policy = "match-viewer"
origin_ssl_protocols = ["TLSv1.2"]
}
}
}
default_cache_behavior = {
target_origin_id = "s3"
viewer_protocol_policy = "allow-all"
allowed_methods = ["DELETE", "GET", "HEAD", "POST", "PUT"]
cached_methods = ["GET", "HEAD"]
min_ttl = 0
default_ttl = 3600
max_ttl = 86400
forwarded_values = {
query_string = false
cookies = {
forward = "none"
}
}
}
}

View File

@ -13,6 +13,6 @@ data "aws_caller_identity" "current" {
data "template_file" "userdata" { data "template_file" "userdata" {
template = file("${path.module}/html/index.html") template = file("${path.module}/html/index.html")
vars = { vars = {
ENDPOINT = "${aws_api_gateway_stage.this.invoke_url}" ENDPOINT = "${module.apigw.api_endpoint}"
} }
} }

View File

@ -0,0 +1,24 @@
module "dynamodb" {
source = "../modules/dynamodb"
providers = {
aws = aws.aws
}
name = "AWSDynamoDB-g3"
billing_mode = "PROVISIONED"
read_capacity = 20
write_capacity = 20
hash_key = "id"
attributes = [
{
name = "id"
type = "N"
}
]
tags = {
name = "DynamoDB-stock"
}
}

View File

@ -0,0 +1,21 @@
module "lambda" {
for_each = local.lambdas
source = "../modules/lambda"
providers = {
aws = aws.aws
}
depends_on = [
module.vpc
]
function_name = each.value.function_name
handler = each.value.handler
runtime = each.value.runtime
package = each.value.package
iam_role = each.value.role
vpc_subnet_ids = module.vpc.private_subnets
vpc_security_group_ids = [module.vpc.default_security_group_id]
}

View File

@ -1,13 +1,11 @@
locals { locals {
bucket_name = "b123123123123-itba-cloud-computing-personal" bucket_name = "b123123123123-itba-cloud-computing-g3-test"
path = "../../resources" path = "../resources"
s3 = { s3 = {
# 1 - Website
website = { website = {
bucket_name = local.bucket_name bucket_name = local.bucket_name
path = "../../resources" path = "../resources"
objects = { objects = {
error = { error = {
@ -25,9 +23,18 @@ locals {
} }
} }
# 2 - WWW Website
www-website = { www-website = {
bucket_name = "www.${local.bucket_name}" bucket_name = "www.${local.bucket_name}"
} }
} }
lambdas = {
lambda = {
package = "${local.path}/lambda/lambda.zip"
function_name = "AWSLambdaHandler-${replace(local.bucket_name, "-", "")}"
role = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/LabRole"
handler = "lambda_handler.main"
runtime = "python3.9"
}
}
} }

View File

@ -0,0 +1,21 @@
module "s3" {
for_each = local.s3
source = "./../modules/s3"
providers = {
aws = aws.aws
}
bucket_name = each.value.bucket_name
objects = try(each.value.objects, {})
}
resource "aws_s3_object" "this" {
provider = aws.aws
bucket = module.s3["website"].id
key = "index.html"
content = data.template_file.userdata.rendered
content_type = "text/html"
storage_class = "STANDARD"
}

View File

@ -0,0 +1,10 @@
terraform {
required_version = ">= 1.0.6"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 4.10.0"
}
}
}

View File

@ -19,7 +19,7 @@
locals { locals {
name = "ex-${replace(basename(path.cwd), "_", "-")}" name = "ex-${replace(basename(path.cwd), "_", "-")}"
region = "eu-west-1" region = "us-east-1"
tags = { tags = {
Example = local.name Example = local.name
@ -59,15 +59,6 @@ module "vpc" {
enable_nat_gateway = true enable_nat_gateway = true
single_nat_gateway = true single_nat_gateway = true
# enable_vpn_gateway = false
# enable_dhcp_options = false
# enable_flow_log = true
# create_flow_log_cloudwatch_log_group = true
# create_flow_log_cloudwatch_iam_role = true
# flow_log_max_aggregation_interval = 60
tags = local.tags tags = local.tags
} }
@ -90,11 +81,6 @@ module "vpc_endpoints" {
private_dns_enabled = true private_dns_enabled = true
subnet_ids = module.vpc.private_subnets subnet_ids = module.vpc.private_subnets
}, },
ses = {
service = "ses"
subnet_ids = ["subnet-12345678", "subnet-87654321"]
tags = { Name = "ses-vpc-endpoint" }
},
} }
tags = merge(local.tags, { tags = merge(local.tags, {
@ -103,11 +89,11 @@ module "vpc_endpoints" {
}) })
} }
module "vpc_endpoints_nocreate" { # module "vpc_endpoints_nocreate" {
source = "../../modules/vpc-endpoints" # source = "terraform-aws-modules/vpc/aws//modules/vpc"
create = false # create = false
} # }
################################################################################ ################################################################################
# Supporting Resources # Supporting Resources