Skip to content

Commit

Permalink
first draft
Browse files Browse the repository at this point in the history
  • Loading branch information
tkjwa committed Jun 13, 2023
1 parent 51e0b1b commit 582d544
Show file tree
Hide file tree
Showing 14 changed files with 712 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.idea
.terraform
terraform.*
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# terraform-aws-beanstalk-worker

This module allows to deploy a WebServer environment in Elastic Beanstalk
63 changes: 63 additions & 0 deletions alb-logs-bucket.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
resource "aws_s3_bucket" "alb_logs_bucket" {
count = var.alb_logs ? 1 : 0

bucket = "${var.beanstalk_env_name}-alb-logs"
force_destroy = var.production ? false : true
}

resource "aws_s3_bucket_server_side_encryption_configuration" "alb_logs_bucket_encryption" {
count = var.alb_logs ? 1 : 0

bucket = aws_s3_bucket.alb_logs_bucket[0].id
expected_bucket_owner = local.account_id
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}

resource "aws_s3_bucket_public_access_block" "alb_logs_bucket_pab" {
count = var.alb_logs ? 1 : 0

bucket = aws_s3_bucket.alb_logs_bucket[0].id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}

resource "aws_s3_bucket_policy" "alb_logs_bucket_policy" {
count = var.alb_logs ? 1 : 0

bucket = aws_s3_bucket.alb_logs_bucket[0].id
policy = data.aws_iam_policy_document.alb_logs_bucket_policy[0].json
}

# see https://docs.aws.amazon.com/elasticloadbalancing/latest/application/enable-access-logging.html#attach-bucket-policy
data "aws_iam_policy_document" "alb_logs_bucket_policy" {
count = var.alb_logs ? 1 : 0

statement {
sid = "ALBAllowWriteLogs"
principals {
identifiers = [data.aws_elb_service_account.current.arn]
type = "AWS"
}
actions = ["s3:PutObject"]
resources = ["${aws_s3_bucket.alb_logs_bucket[0].arn}/AWSLogs/${local.account_id}/*"]
}
}

# Versioning should not be needed as ALB will never update or overwrite files
# but it allows to ensure that the log files have not been altered
resource "aws_s3_bucket_versioning" "alb_logs_bucket_versioning" {
count = var.alb_logs ? 1 : 0

bucket = aws_s3_bucket.alb_logs_bucket[0].id
expected_bucket_owner = local.account_id

versioning_configuration {
status = "Enabled"
}
}
31 changes: 31 additions & 0 deletions certificate.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
resource "aws_acm_certificate" "certificate" {
domain_name = "${var.domain.sub}.${var.domain.main}"
subject_alternative_names = [for domain in var.certificate_additional_domains: "${domain.sub}.${domain.main}"]
validation_method = "DNS"

lifecycle {
create_before_destroy = true
}
}

resource "aws_route53_record" "certificate_validation_records" {
for_each = {
for dvo in aws_acm_certificate.certificate.domain_validation_options : dvo.domain_name => {
name = dvo.resource_record_name
record = dvo.resource_record_value
type = dvo.resource_record_type
}
}

name = each.value.name
records = [each.value.record]
type = each.value.type
zone_id = data.aws_route53_zone.zones[each.key].id
ttl = 60
allow_overwrite = true
}

resource "aws_acm_certificate_validation" "certificate_validation" {
certificate_arn = aws_acm_certificate.certificate.arn
validation_record_fqdns = [for record in aws_route53_record.certificate_validation_records : record.fqdn]
}
40 changes: 40 additions & 0 deletions data.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
data "aws_route53_zone" "zones" {
for_each = {
for domain in concat([var.domain], var.certificate_additional_domains) : "${domain.sub}.${domain.main}" => {
name: domain.main
}
}

name = each.value.name
}

data "aws_subnets" "public" {
filter {
name = "vpc-id"
values = [var.vpc_id]
}

tags = {
visibility = "public"
}
}

data "aws_subnets" "private_apps" {
filter {
name = "vpc-id"
values = [var.vpc_id]
}

tags = {
visibility = "private"
target = "apps"
}
}

data "aws_region" "current" {}

data "aws_caller_identity" "current" {}

data "aws_elastic_beanstalk_hosted_zone" "current" {}

data "aws_elb_service_account" "current" {}
11 changes: 11 additions & 0 deletions dns.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
resource "aws_route53_record" "main_domain" {
name = "${var.domain.sub}.${var.domain.main}"
type = "A"
zone_id = data.aws_route53_zone.zones["${var.domain.sub}.${var.domain.main}"].id

alias {
evaluate_target_health = false
name = aws_elastic_beanstalk_environment.beanstalk_env.cname
zone_id = data.aws_elastic_beanstalk_hosted_zone.current.id
}
}
130 changes: 130 additions & 0 deletions environment.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
module "beanstalk" {
source = "jwa-lab/beanstalk/aws"
version = "0.1.1"

beanstalk_env_name = var.beanstalk_env_name
beanstalk_app_name = var.beanstalk_app_name

tier = "WebServer"
solution_stack_name = var.solution_stack_name
vpc_id = var.vpc_id

production = var.production
ha = var.ha

description = "WebServer environment for ${var.beanstalk_app_name}"

profile_permissions_boundary_arn = var.profile_permissions_boundary_arn
instance_type = var.instance_type

beanstalk_settings = [
{
namespace = "aws:autoscaling:asg"
name = "MaxSize"
value = var.production ? 20 : 2
},
{
namespace = "aws:autoscaling:asg"
name = "MinSize"
value = var.ha ? 2 : 1
},
{
namespace = "aws:autoscaling:updatepolicy:rollingupdate"
name = "RollingUpdateType"
value = "Health"
},
{
namespace = "aws:ec2:instances"
name = "InstanceTypes"
value = var.instance_type != null ? var.instance_type : (var.production ? "t4g.small" : "t4g.micro")
},
{
namespace = "aws:elasticbeanstalk:environment"
name = "EnvironmentType"
value = "LoadBalanced"
},
{
namespace = "aws:elasticbeanstalk:environment"
name = "LoadBalancerType"
value = "application"
},
{
namespace = "aws:elasticbeanstalk:environment:process:default"
name = "DeregistrationDelay"
value = 10
},
{
namespace = "aws:elasticbeanstalk:environment:process:default"
name = "HealthCheckInterval"
value = 30
},
{
namespace = "aws:elasticbeanstalk:environment:process:default"
name = "HealthCheckPath"
value = var.health_check_path
},
{
namespace = "aws:elasticbeanstalk:environment:process:default"
name = "HealthCheckTimeout"
value = 2
},
{
namespace = "aws:elbv2:listener:443"
name = "Protocol"
value = "HTTPS"
},
{
namespace = "aws:elbv2:listener:443"
name = "SSLCertificateArns"
value = aws_acm_certificate.certificate.arn
},
{
namespace = "aws:elbv2:loadbalancer"
name = "IdleTimeout"
value = 10
},
{
namespace = "aws:elbv2:loadbalancer"
name = "ManagedSecurityGroup"
value = aws_security_group.load_balancer_security_group.id
},
{
namespace = "aws:elbv2:loadbalancer"
name = "SecurityGroups"
value = aws_security_group.load_balancer_security_group.id
}
]

beanstalk_env_vars = var.webserver_env_vars
}

resource "aws_elastic_beanstalk_environment" "beanstalk_env" {
name = var.beanstalk_env_name
application = var.beanstalk_app_name
cname_prefix = var.beanstalk_env_name
description = "WebServer environment for ${var.beanstalk_app_name}"
tier = "WebServer"
solution_stack_name = var.solution_stack_name

dynamic "setting" {
for_each = local.beanstalk_settings

content {
namespace = setting.value["namespace"]
name = setting.value["name"]
value = setting.value["value"]
resource = ""
}
}

dynamic "setting" {
for_each = var.webserver_env_vars

content {
namespace = "aws:elasticbeanstalk:application:environment"
name = setting.value["name"]
value = setting.value["value"]
resource = ""
}
}
}
15 changes: 15 additions & 0 deletions instance-profile.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#resource "aws_iam_role_policy" "platform_api_cloudwatch_logs_policy" {
# name = "cloudwatch-logs-streaming"
# role = module.beanstalk.instance_role.id
#
# policy = jsonencode({
# Version = "2012-10-17"
# Statement = [
# {
# Action = ["logs:CreateLogGroup"]
# Effect = "Allow"
# Resource = "arn:aws:logs:*:*:log-group:/aws/elasticbeanstalk*"
# }
# ]
# })
#}
7 changes: 7 additions & 0 deletions locals.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
locals {
account_id = data.aws_caller_identity.current.account_id
region = data.aws_region.current.name

elb_subnets_ids = data.aws_subnets.public.ids
app_subnets_ids = data.aws_subnets.private_apps.ids
}
10 changes: 10 additions & 0 deletions main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
terraform {
required_version = "~> 1.0"

required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 4.2"
}
}
}
11 changes: 11 additions & 0 deletions outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
output "instances_security_group_id" {
value = aws_security_group.beanstalk_instances_security_group.id
}

output "instance_role" {
value = module.beanstalk.instance_role
}

output "load_balancer_arn" {
value = module.beanstalk.beanstalk_env.load_balancers[0]
}
Loading

0 comments on commit 582d544

Please sign in to comment.