From afb51a0da4b5fe538c10b19070030a4294ba74d4 Mon Sep 17 00:00:00 2001 From: "Marlapati Venkata Naga Sai Teja[marlapativ]" Date: Tue, 28 May 2024 00:45:17 -0400 Subject: [PATCH 1/4] Readme + Refactoring --- INSTALLATION.md | 47 ++++++++++++++++++++++++++++++++++ README.md | 58 +++++++++++++++++++++++++++++++++++++++++- jenkins-ec2.tf | 49 +++++++++++++++-------------------- main.tf => provider.tf | 2 +- variables.tf | 47 +++++++++++++--------------------- vpc.tf | 26 +++++++++---------- 6 files changed, 156 insertions(+), 73 deletions(-) create mode 100644 INSTALLATION.md rename main.tf => provider.tf (98%) diff --git a/INSTALLATION.md b/INSTALLATION.md new file mode 100644 index 0000000..b090086 --- /dev/null +++ b/INSTALLATION.md @@ -0,0 +1,47 @@ +# Installation + +## Install and setup aws cli + +To install and set up the AWS cli, follow the instructions in the [official documentation](https://aws.amazon.com/cli/). Ensure that you have the necessary permissions and authentication set up to interact with your AWS projects. + +## Install Terraform + +To install Terraform, follow these general steps: + +1. Download Terraform: Visit the [Terraform website](https://developer.hashicorp.com/terraform/install) and download the appropriate package for your operating system. +2. Follow the installation instructions as specified. +3. Verify Installation: Open a terminal or command prompt and run terraform -version to ensure Terraform has been installed correctly. + + $ terraform -version + + Terraform v1.7.3 + on darwin_arm64 + + provider registry.terraform.io/hashicorp/google v5.15.0 + +## Setup Terraform in repo + +To set up Terraform within your repository, follow these steps: + +1. **Navigate to Repository**: Open a terminal or command prompt and navigate to the root directory of your repository. +2. **Initialize Terraform**: Run terraform init to initialize Terraform within the repository. This command initializes various Terraform configurations and plugins required for your infrastructure. + + $ terraform init + Initializing the backend... + Initializing modules... + + Initializing provider plugins... + - Reusing previous version of hashicorp/google from the dependency lock file + - Using previously-installed hashicorp/google v5.15.0 + Terraform has been successfully initialized! + +3. **Plan Infrastructure Changes**: After initialization, you can run terraform plan to see what changes Terraform will make to your infrastructure. Use -var-file to specify a variable file if needed. + + terraform plan + +4. **Apply Infrastructure Changes**: If the plan looks good, you can apply the changes by running terraform apply. Use -var-file to specify a variable file if needed. + + terraform apply + +5. **Destroy Infrastructure**: To destroy the infrastructure created by Terraform, you can run terraform destroy. Make sure to review the plan before proceeding. + + terraform destroy diff --git a/README.md b/README.md index 8d0d584..5d870f0 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,58 @@ # infra-jenkins -CS7125 Infrastructure as a service code for Jenkins + +This repo contains CSYE7125 Infrastructure as code(Terraform) files to setup Jenkins on AWS. + +## Installation + +Please follow the installation instructions required for setting up the project [here](INSTALLATION.md). + +## What's in this repo + +This repo contains the following files: + +- `provider.tf`: This file contains the terraform code to setup Jenkins on AWS. +- `variables.tf`: This file contains the variables required for the terraform code. +- `vpc.tf`: This file contains the terraform code to setup the VPC, Subnet, Internet Gateway, Route Table, and Security Group on AWS. +- `jenkins-ec2.tf`: This file contains the terraform code to setup the EC2 to host Jenkins instance from AMI on AWS. + +## Usage + +The following variables are required to create a VPC via terraform. + +| Variable | Type | Description | +| ------------------------------------------ | ------ | ---------------------------------------------------- | +| `region` | string | The region where the VPC will be created. | +| `vpc_name` | string | The name of the VPC. | +| `vpc_cidr_range` | string | The CIDR range for the VPC. | +| `subnet_name` | string | The name of the subnet. | +| `subnet_cidr_range` | string | The CIDR range for the subnet. | +| `subnet_zone` | string | The availability zone for the subnet. | +| `internet_gateway_name` | string | The name of the internet gateway. | +| `route_table_name` | string | The name of the route table. | +| `route_cidr` | string | The CIDR block for the route table. | +| `network_acl_ingress` | list | | +| `network_acl_ingress[protocol]` | string | The protocol for the network ACL ingress. | +| `network_acl_ingress[port]` | string | The port for the network ACL ingress. | +| `network_acl_ingress[number]` | string | The rule number for the network ACL ingress. | +| `network_acl_ingress[action]` | string | The action for the network ACL ingress. | +| `network_acl_ingress[cidr]` | string | The CIDR block for the network ACL ingress. | +| `network_acl_egress` | list | | +| `network_acl_egress[protocol]` | string | The protocol for the network ACL egress. | +| `network_acl_egress[port]` | string | The port for the network ACL egress. | +| `network_acl_egress[number]` | string | The rule number for the network ACL egress. | +| `network_acl_egress[action]` | string | The action for the network ACL egress. | +| `network_acl_egress[cidr]` | string | The CIDR block for the network ACL egress. | +| `jenkins_security_group_name` | string | The name of the security group. | +| `jenkins_security_group_ingress` | list | | +| `jenkins_security_group_ingress[protocol]` | string | The protocol for the security group ingress rules. | +| `jenkins_security_group_ingress[port]` | string | The port for the security group ingress rules. | +| `jenkins_security_group_ingress[cidr]` | string | The CIDR block for the security group ingress rules. | +| `jenkins_ec2` | object | | +| `jenkins_ec2[ami]` | string | The AMI ID for the Jenkins EC2 instance. | +| `jenkins_ec2[instance_name]` | string | The name of the Jenkins EC2 instance. | +| `jenkins_ec2[instance_type]` | string | The instance type for the Jenkins EC2 instance. | +| `jenkins_ec2[associate_public_ip_address]` | string | Whether to associate a public IP address or not. | +| `jenkins_ec2[volume]` | object | | +| `jenkins_ec2[volume][size]` | string | The size of the volume. | +| `jenkins_ec2[volume][type]` | string | The type of the volume. | +| `jenkins_ec2_eip_allocation_id` | string | The allocation ID for the Elastic IP. | diff --git a/jenkins-ec2.tf b/jenkins-ec2.tf index f2f66d6..96d486f 100644 --- a/jenkins-ec2.tf +++ b/jenkins-ec2.tf @@ -1,43 +1,36 @@ -data "aws_ami" "jenkins_ami" { - filter { - name = var.jenkins_ami_filter_name - values = [var.jenkins_ami_filter_value] - } -} - -resource "aws_security_group" "jenkins_allow" { +resource "aws_security_group" "jenkins" { name = var.jenkins_security_group_name - vpc_id = aws_vpc.jenkins_vpc.id + vpc_id = aws_vpc.jenkins.id } -resource "aws_vpc_security_group_ingress_rule" "name" { - for_each = var.jenkins_security_group_ingress_rules +resource "aws_vpc_security_group_ingress_rule" "jenkins" { + count = length(var.jenkins_security_group_ingress) - security_group_id = aws_security_group.jenkins_allow.id - cidr_ipv4 = each.value.cidr - from_port = each.value.port - ip_protocol = each.value.protocol - to_port = each.value.port + security_group_id = aws_security_group.jenkins.id + cidr_ipv4 = var.jenkins_security_group_ingress[count.index].cidr + from_port = var.jenkins_security_group_ingress[count.index].port + ip_protocol = var.jenkins_security_group_ingress[count.index].protocol + to_port = var.jenkins_security_group_ingress[count.index].port } -resource "aws_instance" "jenkins_vm" { - ami = data.aws_ami.jenkins_ami.id - instance_type = var.ec2_instance_type - subnet_id = aws_subnet.jenkins_subnet.id - associate_public_ip_address = var.ec2_associate_public_ip_address +resource "aws_instance" "jenkins" { + ami = var.jenkins_ec2.ami + subnet_id = aws_subnet.jenkins.id + associate_public_ip_address = var.jenkins_ec2.associate_public_ip_address + instance_type = var.jenkins_ec2.instance_type root_block_device { - volume_size = var.ec2_root_volume_size - volume_type = var.ec2_root_volume_type + volume_size = var.jenkins_ec2.volume.size + volume_type = var.jenkins_ec2.volume.type } - vpc_security_group_ids = [aws_security_group.jenkins_allow.id] + vpc_security_group_ids = [aws_security_group.jenkins.id] tags = { - Name = var.ec2_instance_name + Name = var.jenkins_ec2.instance_name } } resource "aws_eip_association" "eip_assoc" { - instance_id = aws_instance.jenkins_vm.id - allocation_id = var.eip_allocation_id -} \ No newline at end of file + instance_id = aws_instance.jenkins.id + allocation_id = var.jenkins_ec2_eip_allocation_id +} diff --git a/main.tf b/provider.tf similarity index 98% rename from main.tf rename to provider.tf index cbcea02..a103370 100644 --- a/main.tf +++ b/provider.tf @@ -9,4 +9,4 @@ terraform { provider "aws" { region = var.region -} \ No newline at end of file +} diff --git a/variables.tf b/variables.tf index 7c1d75c..c8333a7 100644 --- a/variables.tf +++ b/variables.tf @@ -22,15 +22,15 @@ variable "subnet_zone" { type = string } -variable "route_cidr" { +variable "internet_gateway_name" { type = string } -variable "internet_gateway_name" { +variable "route_table_name" { type = string } -variable "route_table_name" { +variable "route_cidr" { type = string } @@ -54,46 +54,33 @@ variable "network_acl_egress" { })) } -variable "jenkins_ami_filter_name" { - type = string -} - -variable "jenkins_ami_filter_value" { - type = string -} - variable "jenkins_security_group_name" { type = string } -variable "jenkins_security_group_ingress_rules" { - type = map(object({ +variable "jenkins_security_group_ingress" { + type = list(object({ protocol = string port = number cidr = string })) } -variable "ec2_instance_name" { - type = string -} - -variable "ec2_instance_type" { - type = string -} +variable "jenkins_ec2" { + type = object({ + ami = string -variable "ec2_associate_public_ip_address" { - type = bool -} + instance_name = string + instance_type = string -variable "ec2_root_volume_size" { - type = number + associate_public_ip_address = optional(bool, true) + volume = object({ + size = number + type = string + }) + }) } -variable "ec2_root_volume_type" { +variable "jenkins_ec2_eip_allocation_id" { type = string } - -variable "eip_allocation_id" { - type = string -} \ No newline at end of file diff --git a/vpc.tf b/vpc.tf index 7bde704..57685e9 100644 --- a/vpc.tf +++ b/vpc.tf @@ -1,12 +1,13 @@ -resource "aws_vpc" "jenkins_vpc" { +resource "aws_vpc" "jenkins" { cidr_block = var.vpc_cidr_range + tags = { Name = var.vpc_name } } -resource "aws_subnet" "jenkins_subnet" { - vpc_id = aws_vpc.jenkins_vpc.id +resource "aws_subnet" "jenkins" { + vpc_id = aws_vpc.jenkins.id cidr_block = var.subnet_cidr_range availability_zone = var.subnet_zone @@ -15,20 +16,20 @@ resource "aws_subnet" "jenkins_subnet" { } } -resource "aws_internet_gateway" "jenkins_internet_gateway" { - vpc_id = aws_vpc.jenkins_vpc.id +resource "aws_internet_gateway" "jenkins" { + vpc_id = aws_vpc.jenkins.id tags = { Name = var.internet_gateway_name } } -resource "aws_default_route_table" "jenkins_route_table" { - default_route_table_id = aws_vpc.jenkins_vpc.default_route_table_id +resource "aws_default_route_table" "jenkins" { + default_route_table_id = aws_vpc.jenkins.default_route_table_id route { cidr_block = var.route_cidr - gateway_id = aws_internet_gateway.jenkins_internet_gateway.id + gateway_id = aws_internet_gateway.jenkins.id } tags = { @@ -36,10 +37,9 @@ resource "aws_default_route_table" "jenkins_route_table" { } } -resource "aws_default_network_acl" "default" { - default_network_acl_id = aws_vpc.jenkins_vpc.default_network_acl_id - - subnet_ids = [aws_subnet.jenkins_subnet.id] +resource "aws_default_network_acl" "jenkins" { + default_network_acl_id = aws_vpc.jenkins.default_network_acl_id + subnet_ids = [aws_subnet.jenkins.id] dynamic "ingress" { for_each = var.network_acl_ingress @@ -64,4 +64,4 @@ resource "aws_default_network_acl" "default" { to_port = egress.value.port } } -} \ No newline at end of file +} From 8dffccb079f60ceb0a3794c0865c093c78b50797 Mon Sep 17 00:00:00 2001 From: "Marlapati Venkata Naga Sai Teja[marlapativ]" Date: Tue, 28 May 2024 01:05:08 -0400 Subject: [PATCH 2/4] File rename --- jenkins-ec2.tf => ec2.tf | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename jenkins-ec2.tf => ec2.tf (100%) diff --git a/jenkins-ec2.tf b/ec2.tf similarity index 100% rename from jenkins-ec2.tf rename to ec2.tf From fe3ad64cd8ba3922fbba1ea919859eaf9325f63a Mon Sep 17 00:00:00 2001 From: "Marlapati Venkata Naga Sai Teja[marlapativ]" Date: Tue, 28 May 2024 11:37:31 -0400 Subject: [PATCH 3/4] Adding Security groups egress rules --- ec2.tf | 11 ++++++++++- variables.tf | 8 ++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/ec2.tf b/ec2.tf index 96d486f..27eb617 100644 --- a/ec2.tf +++ b/ec2.tf @@ -13,10 +13,19 @@ resource "aws_vpc_security_group_ingress_rule" "jenkins" { to_port = var.jenkins_security_group_ingress[count.index].port } +resource "aws_vpc_security_group_egress_rule" "jenkins" { + count = length(var.jenkins_security_group_egress) + + security_group_id = aws_security_group.jenkins.id + cidr_ipv4 = var.jenkins_security_group_egress[count.index].cidr + from_port = var.jenkins_security_group_egress[count.index].port + ip_protocol = var.jenkins_security_group_egress[count.index].protocol + to_port = var.jenkins_security_group_egress[count.index].port +} + resource "aws_instance" "jenkins" { ami = var.jenkins_ec2.ami subnet_id = aws_subnet.jenkins.id - associate_public_ip_address = var.jenkins_ec2.associate_public_ip_address instance_type = var.jenkins_ec2.instance_type root_block_device { diff --git a/variables.tf b/variables.tf index c8333a7..1e18a15 100644 --- a/variables.tf +++ b/variables.tf @@ -66,6 +66,14 @@ variable "jenkins_security_group_ingress" { })) } +variable "jenkins_security_group_egress" { + type = list(object({ + protocol = string + port = number + cidr = string + })) +} + variable "jenkins_ec2" { type = object({ ami = string From b8b07ed3f854f8dc58e06438ea5eb68240e95ce0 Mon Sep 17 00:00:00 2001 From: "Marlapati Venkata Naga Sai Teja[marlapativ]" Date: Tue, 28 May 2024 11:39:05 -0400 Subject: [PATCH 4/4] Lint fix --- ec2.tf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ec2.tf b/ec2.tf index 27eb617..7701c9e 100644 --- a/ec2.tf +++ b/ec2.tf @@ -24,9 +24,9 @@ resource "aws_vpc_security_group_egress_rule" "jenkins" { } resource "aws_instance" "jenkins" { - ami = var.jenkins_ec2.ami - subnet_id = aws_subnet.jenkins.id - instance_type = var.jenkins_ec2.instance_type + ami = var.jenkins_ec2.ami + subnet_id = aws_subnet.jenkins.id + instance_type = var.jenkins_ec2.instance_type root_block_device { volume_size = var.jenkins_ec2.volume.size