Files
nvhi-atsila-microservice/terraform/main.tf

328 lines
8.3 KiB
Terraform
Raw Normal View History

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
}
2025-07-14 03:15:21 +00:00
# Security Group - Updated for SSM (removed SSH, kept application access)
2025-07-12 08:51:48 +00:00
resource "aws_security_group" "ecs_sg" {
name = "${var.cluster_name}-sg"
2025-07-14 03:15:21 +00:00
description = "Allow HTTP to ECS and HTTPS outbound for SSM/ECR"
2025-07-12 08:51:48 +00:00
vpc_id = aws_vpc.main.id
2025-07-14 03:15:21 +00:00
# HTTP access for application
2025-07-12 08:51:48 +00:00
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"]
}
2025-07-14 03:15:21 +00:00
# HTTPS outbound for SSM, ECR, and AWS services
egress {
description = "HTTPS outbound for AWS services"
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
# HTTP outbound for package updates
2025-07-12 08:51:48 +00:00
egress {
2025-07-14 03:15:21 +00:00
description = "HTTP outbound for package updates"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
# DNS resolution
egress {
description = "DNS resolution"
from_port = 53
to_port = 53
protocol = "udp"
2025-07-12 08:51:48 +00:00
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "${var.cluster_name}-sg"
}
}
2025-07-14 03:15:21 +00:00
# Key Pair (keeping for compatibility, but not needed for SSM)
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"
}
}
2025-07-14 03:15:21 +00:00
# IAM Role Policy Attachment for ECS
2025-07-12 18:19:18 +00:00
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"
}
2025-07-14 03:15:21 +00:00
# IAM Role Policy Attachment for SSM
resource "aws_iam_role_policy_attachment" "ecs_instance_ssm_policy" {
role = aws_iam_role.ecs_instance_role.name
policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
}
2025-07-15 04:26:49 +00:00
# ECS Task Execution Role
resource "aws_iam_role" "ecs_task_execution_role" {
name = "${var.cluster_name}-task-execution-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "ecs-tasks.amazonaws.com"
}
}
]
})
tags = {
Name = "${var.cluster_name}-task-execution-role"
}
}
# Attach AWS managed policy for ECS task execution
resource "aws_iam_role_policy_attachment" "ecs_task_execution_role_policy" {
role = aws_iam_role.ecs_task_execution_role.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
}
# Additional policy for ECR access
resource "aws_iam_role_policy" "ecs_task_execution_ecr_policy" {
name = "${var.cluster_name}-task-execution-ecr-policy"
role = aws_iam_role.ecs_task_execution_role.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage"
]
Resource = "*"
}
]
})
}
2025-07-12 18:19:18 +00:00
# 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-14 03:15:21 +00:00
# User data script for ECS instance with SSM
2025-07-12 18:19:18 +00:00
locals {
2025-07-14 03:15:21 +00:00
user_data = base64encode(templatefile("${path.module}/user_data.sh", {
cluster_name = var.cluster_name
}))
2025-07-12 18:19:18 +00:00
}
# 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-15 04:26:49 +00:00
# ECS Service (will be created by Jenkins pipeline)
# Commented out because Jenkins will create the service
# resource "aws_ecs_service" "main" {
# name = "${var.cluster_name}-service"
# cluster = aws_ecs_cluster.main.id
# desired_count = 1
# launch_type = "EC2"
# task_definition = "${var.cluster_name}-task:1"
#
# depends_on = [aws_instance.ecs_instance]
#
# lifecycle {
# ignore_changes = [task_definition]
# }
#
# tags = {
# Name = "${var.cluster_name}-service"
# }
# }
2025-07-12 18:19:18 +00:00
# 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
2025-07-14 03:15:21 +00:00
output "ecs_instance_id" {
description = "Instance ID for SSM access"
value = aws_instance.ecs_instance.id
}
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
2025-07-15 04:26:49 +00:00
}
output "ecs_task_execution_role_arn" {
description = "ARN of the ECS task execution role"
value = aws_iam_role.ecs_task_execution_role.arn
2025-07-12 18:19:18 +00:00
}