# Security group for API instance resource "aws_security_group" "api_instance" { name = "${var.app_name}-api-instance-sg" description = "Security group for API EC2 instance" vpc_id = aws_vpc.main.id ingress { from_port = 80 to_port = 80 protocol = "tcp" security_groups = [aws_security_group.alb.id] description = "HTTP from ALB only" } ingress { from_port = 22 to_port = 22 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"] } tags = { Name = "${var.app_name}-api-instance-sg" } } # IAM role for EC2 instance resource "aws_iam_role" "api_instance" { name = "${var.app_name}-api-instance-role" assume_role_policy = jsonencode({ Version = "2012-10-17" Statement = [ { Action = "sts:AssumeRole" Effect = "Allow" Principal = { Service = "ec2.amazonaws.com" } } ] }) } # IAM policy for ECR access resource "aws_iam_role_policy" "ecr_access" { name = "${var.app_name}-ecr-access" role = aws_iam_role.api_instance.id policy = jsonencode({ Version = "2012-10-17" Statement = [ { Effect = "Allow" Action = [ "ecr:GetAuthorizationToken", "ecr:BatchCheckLayerAvailability", "ecr:GetDownloadUrlForLayer", "ecr:BatchGetImage" ] Resource = "*" } ] }) } # Instance profile resource "aws_iam_instance_profile" "api" { name = "${var.app_name}-api-instance-profile" role = aws_iam_role.api_instance.name } # Add SSM managed policy for remote management resource "aws_iam_role_policy_attachment" "ssm_managed_instance_core" { role = aws_iam_role.api_instance.name policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore" } # Get latest Amazon Linux 2 AMI data "aws_ami" "amazon_linux_2" { most_recent = true owners = ["amazon"] filter { name = "name" values = ["amzn2-ami-hvm-*-x86_64-gp2"] } filter { name = "virtualization-type" values = ["hvm"] } } # EC2 instance for API resource "aws_instance" "api" { ami = data.aws_ami.amazon_linux_2.id instance_type = "t3.micro" subnet_id = aws_subnet.public[0].id vpc_security_group_ids = [aws_security_group.api_instance.id] associate_public_ip_address = true iam_instance_profile = aws_iam_instance_profile.api.name user_data = base64encode(templatefile("${path.module}/user-data.sh", { database_url = "postgresql://${aws_db_instance.filamenteka.username}:${random_password.db_password.result}@${aws_db_instance.filamenteka.endpoint}/${aws_db_instance.filamenteka.db_name}?sslmode=require" jwt_secret = random_password.jwt_secret.result admin_password = var.admin_password ecr_url = aws_ecr_repository.api.repository_url aws_region = var.aws_region })) tags = { Name = "${var.app_name}-api-instance" } depends_on = [aws_db_instance.filamenteka] } # Elastic IP for API instance resource "aws_eip" "api" { instance = aws_instance.api.id domain = "vpc" tags = { Name = "${var.app_name}-api-eip" } } # Output the API URL output "api_instance_url" { value = "http://${aws_eip.api.public_ip}" description = "API instance URL" }