1+ # This block configures Terraform itself - it's like "settings" for how Terraform should run our code.
2+ # This prevents surprises and makes our infrastructure more reliable!
3+
4+ terraform {
5+ required_version = " >=1.0"
6+ required_providers {
7+ aws = {
8+ source = " hashicorp/aws"
9+ version = " ~>5.0"
10+ }
11+ }
12+ }
13+
14+ # AWS provider
15+
16+ provider "aws" {
17+ region = var. aws_region
18+ }
19+
20+ # VPC
21+
22+ resource "aws_vpc" "main" {
23+ cidr_block = var. vpc_cidr
24+ enable_dns_hostnames = true
25+ enable_dns_support = true
26+
27+ tags = {
28+ Name = " ${ var . project_name } -vpc"
29+ }
30+ }
31+
32+ # Internet Gateway
33+
34+ resource "aws_internet_gateway" "main" {
35+ vpc_id = aws_vpc. main . id
36+
37+ tags = {
38+ Name = " ${ var . project_name } -igw"
39+ }
40+ }
41+
42+ # Public Subnet
43+ resource "aws_subnet" "public" {
44+ vpc_id = aws_vpc. main . id
45+ cidr_block = var. public_subnet_cidr
46+ availability_zone = var. availability_zone
47+ map_public_ip_on_launch = true
48+
49+ tags = {
50+ Name = " ${ var . project_name } -public-subnet"
51+ }
52+ }
53+
54+ # Route Table for Public Subnet
55+ resource "aws_route_table" "public" {
56+ vpc_id = aws_vpc. main . id
57+
58+ route {
59+ cidr_block = " 0.0.0.0/0"
60+ gateway_id = aws_internet_gateway. main . id
61+ }
62+
63+ tags = {
64+ Name = " ${ var . project_name } -public-rt"
65+ }
66+ }
67+
68+ # Route Table Association
69+ resource "aws_route_table_association" "public" {
70+ subnet_id = aws_subnet. public . id
71+ route_table_id = aws_route_table. public . id
72+ }
73+
74+ # Security Group
75+ resource "aws_security_group" "api_server" {
76+ name = " ${ var . project_name } -sg"
77+ description = " Security group for API server"
78+ vpc_id = aws_vpc. main . id
79+
80+ ingress {
81+ description = " SSH"
82+ from_port = 22
83+ to_port = 22
84+ protocol = " tcp"
85+ cidr_blocks = [" 0.0.0.0/0" ]
86+ }
87+
88+ ingress {
89+ description = " HTTP"
90+ from_port = 80
91+ to_port = 80
92+ protocol = " tcp"
93+ cidr_blocks = [" 0.0.0.0/0" ]
94+ }
95+
96+ ingress {
97+ description = " HTTPS"
98+ from_port = 443
99+ to_port = 443
100+ protocol = " tcp"
101+ cidr_blocks = [" 0.0.0.0/0" ]
102+ }
103+
104+ ingress {
105+ description = " Kubernetes API"
106+ from_port = 6443
107+ to_port = 6443
108+ protocol = " tcp"
109+ cidr_blocks = [" 0.0.0.0/0" ]
110+ }
111+
112+ egress {
113+ from_port = 0
114+ to_port = 0
115+ protocol = " -1"
116+ cidr_blocks = [" 0.0.0.0/0" ]
117+ }
118+
119+ tags = {
120+ Name = " ${ var . project_name } -sg"
121+ }
122+ }
123+
124+ # IAM Role for EC2
125+
126+ resource "aws_iam_role" "ec2_role" {
127+ name = " ${ var . project_name } -ec2-role"
128+
129+ assume_role_policy = jsonencode ({
130+ Version = " 2012-10-17"
131+ Statement = [
132+ {
133+ Action = " sts:AssumeRole"
134+ Effect = " Allow"
135+ Principal = {
136+ Service = " ec2.amazonaws.com"
137+ }
138+ }
139+ ]
140+
141+ })
142+
143+ tags = {
144+ Name = " ${ var . project_name } -ec2-role"
145+ }
146+ }
147+
148+ # IAM Role Policy Attachment
149+
150+ resource "aws_iam_role_policy_attachment" "ec2_ssm" {
151+ role = aws_iam_role. ec2_role . name
152+ policy_arn = " arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
153+ }
154+
155+ resource "aws_iam_role_policy_attachment" "ec2_s3" {
156+ role = aws_iam_role. ec2_role . name
157+ policy_arn = " arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess"
158+ }
159+
160+ resource "aws_iam_role_policy_attachment" "ec2_ecr" {
161+ role = aws_iam_role. ec2_role . name
162+ policy_arn = " arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
163+ }
164+
165+ # IAM Instance Profile
166+
167+ resource "aws_iam_instance_profile" "ec2_profile" {
168+ name = " ${ var . project_name } -ec2-profile"
169+ role = aws_iam_role. ec2_role . name
170+ }
171+
172+ # EC2 Instance
173+
174+ resource "aws_instance" "api_server" {
175+ ami = var. ami_id
176+ instance_type = var. instance_type
177+ key_name = var. key_name
178+ subnet_id = aws_subnet. public . id
179+ vpc_security_group_ids = [aws_security_group . api_server . id ]
180+ iam_instance_profile = aws_iam_instance_profile. ec2_profile . name
181+
182+ root_block_device {
183+ volume_type = " gp3"
184+ volume_size = 50
185+ encrypted = true
186+ }
187+
188+ tags = {
189+ Name = " ${ var . project_name } -api_server"
190+ }
191+
192+ lifecycle {
193+ ignore_changes = [ami ]
194+ }
195+ }
196+
197+ # Elastic IP
198+
199+ resource "aws_eip" "api_server" {
200+ instance = aws_instance. api_server . id
201+ domain = " vpc"
202+
203+ tags = {
204+ Name = " ${ var . project_name } -eip"
205+ }
206+ }
0 commit comments