diff --git a/application.tf b/application.tf new file mode 100644 index 0000000..b64b789 --- /dev/null +++ b/application.tf @@ -0,0 +1,123 @@ +# ECS cluster, service and load balancer for running the application + +resource "aws_ecs_cluster" "cluster" { + name = "testapp" +} + +resource "aws_ecs_cluster_capacity_providers" "capacity_providers" { + cluster_name = aws_ecs_cluster.cluster.name +} + +resource "aws_lb" "testapp" { + name = aws_ecs_cluster.cluster.name + internal = false + load_balancer_type = "application" + security_groups = [ aws_security_group.testapp.id ] + subnets = var.subnets +} + +resource "aws_lb_listener" "testapp" { + load_balancer_arn = aws_lb.testapp.arn + port = "80" + protocol = "HTTP" + + default_action { + type = "forward" + target_group_arn = aws_lb_target_group.testapp.arn + } +} + +resource "aws_lb_target_group" "testapp" { + name = "testapp" + port = 80 + protocol = "HTTP" + target_type = "ip" + vpc_id = aws_security_group.testapp.vpc_id + + health_check { + matcher = "200" + path = "/" + port = 80 + } +} + +resource "aws_ecs_task_definition" "testapp" { + family = "testapp" + + requires_compatibilities = ["FARGATE"] + cpu = 1024 + memory = 2048 + + network_mode = "awsvpc" + + container_definitions = jsonencode([ + { + name = "testapp" + + # this is a sample http container that responds on port 80 + image = "yeasy/simple-web:latest" + essential = true + portMappings = [ + { + containerPort = 80 + hostPort = 80 + } + ] + environment = [ + { name = "HTTPPORT", value = "80" }, + { name = "MEM_MX", value = "2048m" }, + { name = "DB_DEFAULT_URL", value = "jdbc:postgresql://${aws_db_instance.database.endpoint}/testapp" }, + { name = "DB_DEFAULT_USER", value = "testapp" }, + { name = "DB_DEFAULT_PASSWORD", value = "xw3489sf" }, + { name = "S3_BUCKET", value = aws_s3_bucket.bucket.bucket } + ] + } + ]) +} + +resource "aws_ecs_service" "testapp" { + name = "testapp" + cluster = aws_ecs_cluster.cluster.name + task_definition = "${aws_ecs_task_definition.testapp.id}:${aws_ecs_task_definition.testapp.revision}" + + health_check_grace_period_seconds = 30 + desired_count = 1 + + load_balancer { + target_group_arn = aws_lb_target_group.testapp.arn + container_name = "testapp" + container_port = 80 + } + + capacity_provider_strategy { + capacity_provider = "FARGATE" + weight = 1 + } + + network_configuration { + subnets = aws_lb.testapp.subnets + security_groups = aws_lb.testapp.security_groups + assign_public_ip = true + } + +} + +resource "aws_security_group" "testapp" { + name = "testapp" + description = "Security group for testapp" + vpc_id = var.vpc_id + + ingress { + from_port = 80 + to_port = 80 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } +} diff --git a/cdn.tf b/cdn.tf new file mode 100644 index 0000000..92660f1 --- /dev/null +++ b/cdn.tf @@ -0,0 +1,44 @@ +# Cloudfront CDN serving the load balancer from the ECS service + +resource "aws_cloudfront_distribution" "cloudfront" { + + comment = "testapp" + enabled = true + http_version = "http2" + + default_cache_behavior { + target_origin_id = aws_lb.testapp.dns_name + allowed_methods = [ "DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT" ] + cached_methods = [ "GET", "HEAD" ] + viewer_protocol_policy = "redirect-to-https" + + forwarded_values { + query_string = true + cookies { + forward = "all" + } + } + } + + origin { + domain_name = aws_lb.testapp.dns_name + origin_id = aws_lb.testapp.dns_name + custom_origin_config { + http_port = 80 + https_port = 443 + origin_protocol_policy = "http-only" + origin_ssl_protocols = [ "TLSv1", "TLSv1.1", "TLSv1.2" ] + } + } + + restrictions { + geo_restriction { + restriction_type = "none" + } + } + + viewer_certificate { + cloudfront_default_certificate = true + } + +} diff --git a/database.tf b/database.tf new file mode 100644 index 0000000..1fbe70e --- /dev/null +++ b/database.tf @@ -0,0 +1,20 @@ + +# Postgres Database for the app +resource "aws_db_instance" "database" { + + db_name = "testappdb" + identifier = "testapp-db" + + instance_class = "db.t3.micro" + engine = "postgres" + engine_version = "15.2" + + multi_az = false + allocated_storage = 10 # gibibytes + + username = "root" + password = "xw3489sf" + + apply_immediately = true + skip_final_snapshot = true +} \ No newline at end of file diff --git a/provider.tf b/provider.tf new file mode 100644 index 0000000..f5b72ba --- /dev/null +++ b/provider.tf @@ -0,0 +1,6 @@ +provider "aws" { + region = "eu-west-1" +} + +variable "vpc_id" { type = string } +variable "subnets" { type = list(string) } diff --git a/storage.tf b/storage.tf new file mode 100644 index 0000000..b9c482f --- /dev/null +++ b/storage.tf @@ -0,0 +1,5 @@ + +# Storage bucket for the app +resource "aws_s3_bucket" "bucket" { + bucket = "testapp-files" +}