2025-07-12 19:17:29 +00:00
|
|
|
# Application Infrastructure
|
|
|
|
# Provider configuration is in versions.tf
|
2025-07-12 08:51:48 +00:00
|
|
|
|
2025-07-12 18:19:18 +00:00
|
|
|
data "aws_availability_zones" "azs" {}
|
2025-07-12 08:51:48 +00:00
|
|
|
|
2025-07-12 18:19:18 +00:00
|
|
|
# VPC
|
|
|
|
resource "aws_vpc" "main" {
|
|
|
|
cidr_block = var.vpc_cidr
|
|
|
|
enable_dns_hostnames = true
|
|
|
|
enable_dns_support = true
|
2025-07-12 08:51:48 +00:00
|
|
|
|
|
|
|
tags = {
|
2025-07-12 18:19:18 +00:00
|
|
|
Name = "${var.cluster_name}-vpc"
|
2025-07-12 08:51:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-07-12 18:19:18 +00:00
|
|
|
# Internet Gateway
|
|
|
|
resource "aws_internet_gateway" "main" {
|
|
|
|
vpc_id = aws_vpc.main.id
|
|
|
|
|
2025-07-12 08:51:48 +00:00
|
|
|
tags = {
|
2025-07-12 18:19:18 +00:00
|
|
|
Name = "${var.cluster_name}-igw"
|
2025-07-12 08:51:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-07-12 18:19:18 +00:00
|
|
|
# Public Subnets
|
2025-07-12 08:51:48 +00:00
|
|
|
resource "aws_subnet" "public" {
|
|
|
|
count = length(split(",", var.public_subnets))
|
|
|
|
vpc_id = aws_vpc.main.id
|
|
|
|
cidr_block = element(split(",", var.public_subnets), count.index)
|
|
|
|
availability_zone = data.aws_availability_zones.azs.names[count.index]
|
|
|
|
map_public_ip_on_launch = true
|
2025-07-12 18:19:18 +00:00
|
|
|
|
2025-07-12 08:51:48 +00:00
|
|
|
tags = {
|
|
|
|
Name = "${var.cluster_name}-public-${count.index}"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-07-12 18:19:18 +00:00
|
|
|
# Route Table for public subnets
|
|
|
|
resource "aws_route_table" "public" {
|
|
|
|
vpc_id = aws_vpc.main.id
|
|
|
|
|
|
|
|
route {
|
|
|
|
cidr_block = "0.0.0.0/0"
|
|
|
|
gateway_id = aws_internet_gateway.main.id
|
|
|
|
}
|
|
|
|
|
|
|
|
tags = {
|
|
|
|
Name = "${var.cluster_name}-public-rt"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# Route Table Associations
|
|
|
|
resource "aws_route_table_association" "public" {
|
|
|
|
count = length(aws_subnet.public)
|
|
|
|
subnet_id = aws_subnet.public[count.index].id
|
|
|
|
route_table_id = aws_route_table.public.id
|
|
|
|
}
|
|
|
|
|
|
|
|
# Security Group
|
2025-07-12 08:51:48 +00:00
|
|
|
resource "aws_security_group" "ecs_sg" {
|
|
|
|
name = "${var.cluster_name}-sg"
|
|
|
|
description = "Allow SSH & HTTP to ECS"
|
|
|
|
vpc_id = aws_vpc.main.id
|
|
|
|
|
|
|
|
ingress {
|
2025-07-12 18:19:18 +00:00
|
|
|
description = "SSH from Jenkins"
|
2025-07-12 08:51:48 +00:00
|
|
|
from_port = 22
|
|
|
|
to_port = 22
|
|
|
|
protocol = "tcp"
|
|
|
|
cidr_blocks = [var.jenkins_ip_cidr]
|
|
|
|
}
|
|
|
|
|
|
|
|
ingress {
|
2025-07-12 18:19:18 +00:00
|
|
|
description = "HTTP from anywhere"
|
2025-07-12 08:51:48 +00:00
|
|
|
from_port = 8080
|
|
|
|
to_port = 8080
|
|
|
|
protocol = "tcp"
|
|
|
|
cidr_blocks = ["0.0.0.0/0"]
|
|
|
|
}
|
|
|
|
|
|
|
|
egress {
|
2025-07-12 18:19:18 +00:00
|
|
|
description = "All outbound traffic"
|
2025-07-12 08:51:48 +00:00
|
|
|
from_port = 0
|
|
|
|
to_port = 0
|
|
|
|
protocol = "-1"
|
|
|
|
cidr_blocks = ["0.0.0.0/0"]
|
|
|
|
}
|
|
|
|
|
|
|
|
tags = {
|
|
|
|
Name = "${var.cluster_name}-sg"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-07-12 19:17:29 +00:00
|
|
|
# Key Pair
|
2025-07-12 08:51:48 +00:00
|
|
|
resource "aws_key_pair" "deployer" {
|
|
|
|
key_name = var.key_pair_name
|
2025-07-12 18:19:18 +00:00
|
|
|
public_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDDFBAOogBj/GHKXQs6FLROGQfXkZe2uKbRron0We7ZOLgt6e1bI7U8IMe+DIH250CHSi4R5DBYFQF5Bk1TkS5cgMtPIAb87vRUGI3sLs29DQA/kllYiZlQi9ejxcEz2+TRWn10Q/Kltlb6ESNLnnnTsIUUxKUeY3MKFFd+V13FleSVLGYondwPWYwD/XJ6a3VwSTJ1wFKO+lpKknSjDl2ZOgYpWFALPH+EwMlRGVMrUXAB604zqR1XOzYXAAWnhmmC9IGgCzU/5JnEgFyhfZbR3kpEH8SmSXahvdFZERp+3j9d3ROjchqnf0Z0zZ7vzX+G+jvzT/jGOkzH9tx0/OqIO9f47OFF8iUfZgUtJU1QGbepdsmQqognhxfJQfMZbVtKUw7zt+mzJz3A0XcRp7IwVHaqJ2QW2dpXi4UbWtejtZqROg6byWq2FpvFGNIT3eiKTf+EpCoOec6YGSrRQlj73Ob0+FhmsyQ6e8KKncaRYx38PqtnWsI3UnLtdKmEJmDBPI0ipxJzmKJKtb0vtJPVYvFEpgiXSwnDX883rAUQrXR/EhOMmbMwk7JSes6/GXH9rWN10JHh1/i1LLpl+rg6VyktFgVBHzVw++y29QSfFixeTvFkkTS5kl//CpKd1GDQb9ZBH6SPgkgOjmASPUo+p5e/NiN/SIBSpYpMjOKs7Q== jacques@Xochiquetzal"
|
|
|
|
|
|
|
|
tags = {
|
|
|
|
Name = var.key_pair_name
|
|
|
|
}
|
2025-07-12 08:51:48 +00:00
|
|
|
}
|
|
|
|
|
2025-07-12 18:19:18 +00:00
|
|
|
# Get Amazon Linux 2 AMI (better for ECS)
|
|
|
|
data "aws_ami" "amazon_linux" {
|
2025-07-12 08:51:48 +00:00
|
|
|
most_recent = true
|
2025-07-12 18:19:18 +00:00
|
|
|
owners = ["amazon"]
|
|
|
|
|
2025-07-12 08:51:48 +00:00
|
|
|
filter {
|
|
|
|
name = "name"
|
2025-07-12 18:19:18 +00:00
|
|
|
values = ["amzn2-ami-ecs-hvm-*-x86_64-ebs"]
|
|
|
|
}
|
|
|
|
|
|
|
|
filter {
|
|
|
|
name = "virtualization-type"
|
|
|
|
values = ["hvm"]
|
2025-07-12 08:51:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-07-12 18:19:18 +00:00
|
|
|
# IAM Role for ECS Instance
|
|
|
|
resource "aws_iam_role" "ecs_instance_role" {
|
|
|
|
name = "${var.cluster_name}-ecs-instance-role"
|
|
|
|
|
|
|
|
assume_role_policy = jsonencode({
|
|
|
|
Version = "2012-10-17"
|
|
|
|
Statement = [
|
|
|
|
{
|
|
|
|
Action = "sts:AssumeRole"
|
|
|
|
Effect = "Allow"
|
|
|
|
Principal = {
|
|
|
|
Service = "ec2.amazonaws.com"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
|
|
|
})
|
|
|
|
|
|
|
|
tags = {
|
|
|
|
Name = "${var.cluster_name}-ecs-instance-role"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# IAM Role Policy Attachment
|
|
|
|
resource "aws_iam_role_policy_attachment" "ecs_instance_role_policy" {
|
|
|
|
role = aws_iam_role.ecs_instance_role.name
|
|
|
|
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role"
|
|
|
|
}
|
|
|
|
|
|
|
|
# IAM Instance Profile
|
|
|
|
resource "aws_iam_instance_profile" "ecs_instance_profile" {
|
|
|
|
name = "${var.cluster_name}-ecs-instance-profile"
|
|
|
|
role = aws_iam_role.ecs_instance_role.name
|
|
|
|
|
|
|
|
tags = {
|
|
|
|
Name = "${var.cluster_name}-ecs-instance-profile"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# ECS Cluster
|
2025-07-12 08:51:48 +00:00
|
|
|
resource "aws_ecs_cluster" "main" {
|
|
|
|
name = var.cluster_name
|
2025-07-12 18:19:18 +00:00
|
|
|
|
|
|
|
setting {
|
|
|
|
name = "containerInsights"
|
|
|
|
value = "enabled"
|
|
|
|
}
|
|
|
|
|
|
|
|
tags = {
|
|
|
|
Name = var.cluster_name
|
|
|
|
}
|
2025-07-12 08:51:48 +00:00
|
|
|
}
|
|
|
|
|
2025-07-12 18:19:18 +00:00
|
|
|
# User data script for ECS instance
|
|
|
|
locals {
|
|
|
|
user_data = base64encode(<<-EOF
|
|
|
|
#!/bin/bash
|
|
|
|
yum update -y
|
|
|
|
yum install -y ecs-init
|
|
|
|
echo ECS_CLUSTER=${var.cluster_name} >> /etc/ecs/ecs.config
|
|
|
|
service docker start
|
|
|
|
start ecs
|
|
|
|
EOF
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
# EC2 Instance for ECS
|
2025-07-12 08:51:48 +00:00
|
|
|
resource "aws_instance" "ecs_instance" {
|
2025-07-12 18:19:18 +00:00
|
|
|
ami = data.aws_ami.amazon_linux.id
|
2025-07-12 08:51:48 +00:00
|
|
|
instance_type = var.instance_type
|
|
|
|
subnet_id = aws_subnet.public[0].id
|
|
|
|
vpc_security_group_ids = [aws_security_group.ecs_sg.id]
|
|
|
|
key_name = aws_key_pair.deployer.key_name
|
2025-07-12 18:19:18 +00:00
|
|
|
iam_instance_profile = aws_iam_instance_profile.ecs_instance_profile.name
|
|
|
|
user_data_base64 = local.user_data
|
|
|
|
|
|
|
|
root_block_device {
|
|
|
|
volume_type = "gp3"
|
|
|
|
volume_size = 20
|
|
|
|
encrypted = true
|
|
|
|
}
|
2025-07-12 08:51:48 +00:00
|
|
|
|
|
|
|
tags = {
|
|
|
|
Name = "${var.cluster_name}-instance"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-07-12 19:17:29 +00:00
|
|
|
# ECS Service
|
2025-07-12 18:19:18 +00:00
|
|
|
resource "aws_ecs_service" "main" {
|
|
|
|
name = "${var.cluster_name}-service"
|
|
|
|
cluster = aws_ecs_cluster.main.id
|
|
|
|
desired_count = 1
|
|
|
|
launch_type = "EC2"
|
|
|
|
|
|
|
|
# This will be updated by your Jenkins pipeline
|
|
|
|
task_definition = "${var.cluster_name}:1"
|
|
|
|
|
|
|
|
depends_on = [aws_instance.ecs_instance]
|
|
|
|
|
|
|
|
lifecycle {
|
|
|
|
ignore_changes = [task_definition]
|
|
|
|
}
|
|
|
|
|
|
|
|
tags = {
|
|
|
|
Name = "${var.cluster_name}-service"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# CloudWatch Log Group for ECS
|
|
|
|
resource "aws_cloudwatch_log_group" "ecs_logs" {
|
|
|
|
name = "/ecs/${var.cluster_name}"
|
|
|
|
retention_in_days = 7
|
|
|
|
|
|
|
|
tags = {
|
|
|
|
Name = "${var.cluster_name}-logs"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# Outputs
|
2025-07-12 08:51:48 +00:00
|
|
|
output "ecs_instance_public_ip" {
|
2025-07-12 18:19:18 +00:00
|
|
|
description = "Public IP of the ECS instance"
|
|
|
|
value = aws_instance.ecs_instance.public_ip
|
2025-07-12 08:51:48 +00:00
|
|
|
}
|
2025-07-12 18:19:18 +00:00
|
|
|
|
|
|
|
output "ecs_cluster_name" {
|
|
|
|
description = "Name of the ECS cluster"
|
|
|
|
value = aws_ecs_cluster.main.name
|
|
|
|
}
|
|
|
|
|
|
|
|
output "vpc_id" {
|
|
|
|
description = "ID of the VPC"
|
|
|
|
value = aws_vpc.main.id
|
|
|
|
}
|
|
|
|
|
|
|
|
output "public_subnet_ids" {
|
|
|
|
description = "IDs of the public subnets"
|
|
|
|
value = aws_subnet.public[*].id
|
|
|
|
}
|