diff --git a/.gitignore b/.gitignore index 9b8a46e..a685588 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,9 @@ *.tfstate *.tfstate.* +*.lock.* +.terraform.lock.* + # Crash log files crash.log crash.*.log @@ -32,3 +35,6 @@ override.tf.json # Ignore CLI configuration files .terraformrc terraform.rc + +notes.txt +**/secret/* diff --git a/Ansible/README.md b/Ansible/README.md index 967dfb1..3d22501 100644 --- a/Ansible/README.md +++ b/Ansible/README.md @@ -1,3 +1,23 @@ -# DevOps-Exercise-Ansible -DevOps home Ansible task +# Ansible Configuration Manager +This Ansible project utilizes the `geerlingguy.docker` [role](https://galaxy.ansible.com/ui/standalone/roles/geerlingguy/docker/documentation/) to download Docker onto a selected host, create a new user and give it permissions to run Docker commands. + +## Prerequisites + +1. Install Ansible + + +## Usage + +1. Navigate to project directory. + +2. Edit `hosts.yaml`, replace `` with the IP of the instance that was outputed from the terraform. + +3. Download required roles: + ```bash + ansible-galaxy install -r requirements.yml + ``` +4. Run the playbook with the following command: + ```bash + ansible-playbook -i hosts.yaml playbook.yaml + ``` \ No newline at end of file diff --git a/Ansible/hosts.yaml b/Ansible/hosts.yaml new file mode 100644 index 0000000..8ce003f --- /dev/null +++ b/Ansible/hosts.yaml @@ -0,0 +1,6 @@ +ungrouped: + hosts: + : + vars: + ansible_user: "ubuntu" + ansible_ssh_private_key_file: "../Terraform/secret/devops_kp.pem" \ No newline at end of file diff --git a/Ansible/playbook.yaml b/Ansible/playbook.yaml new file mode 100644 index 0000000..ae2dec0 --- /dev/null +++ b/Ansible/playbook.yaml @@ -0,0 +1,9 @@ +- hosts: all + become: true + + vars: + docker_users: + - "devops" + + roles: + - geerlingguy.docker \ No newline at end of file diff --git a/Ansible/requirements.yaml b/Ansible/requirements.yaml new file mode 100644 index 0000000..6344df6 --- /dev/null +++ b/Ansible/requirements.yaml @@ -0,0 +1 @@ +- src: geerlingguy.docker \ No newline at end of file diff --git a/Terraform/README.md b/Terraform/README.md index c580875..0dac5f1 100644 --- a/Terraform/README.md +++ b/Terraform/README.md @@ -1,3 +1,90 @@ -# DevOps-Exercise-Terraform -DevOps home Terraform task +# Terraform Infrastructure as Code (IaC) +This Terraform project sets up an Amazon Web Services (AWS) environment with the following components: + +1. **Virtual Private Cloud (VPC)**: A custom VPC with private and public subnets. +2. **Internet Gateway**: Allows connection to the internet. +3. **Security Groups (SGs)**: + - `external_connection_sg`: Allows inbound traffic on port 443 (HTTPS), port 22 (SSH) and ICMP (ping) from a private IP. + - `internal_connection_sg`: Allows inbound traffic on port 22 (SSH) from the `internal_connection_sg`. +4. **Key Pair**: + - Generate a Key Pair to enable SSH connection with instance + - Download private key file to use for SSH connection. +5. **EC2 Instance**: + - Launches a t3.micro EC2 instance in the public subnet. + - Associates the `external_connection_sg` with the instance. + - Associates the generated Key Pair with the instance. + +## Prerequisites + +1. Install Terraform +2. Configure AWS credentials: Ensure your AWS access keys are set up. + +## Variables + +- `aws_region`: AWS Region to deploy the VPC in (default: `us-east-1`). +- `keypair_name`: Keypair name (default: `devops_kp`). +- `private_ip`: Personal IP to connect with. +- `tags`: Tags to add to all resources (default: `{ "Terraform": "true", "DevopsMaster": "true" }`). +- `vpc_name`: The Name of the VPC. +- `vpc_cidr`: CIDR block for VPC. +- `vpc_private_subnets`: List of private subnets to create in VPC. +- `vpc_public_subnets`: List of public subnets to create in VPC. + +## Security Groups + +### External Connection Security Group + +- Name: `external-connection-sg` +- Description: Allows SSH, HTTPS, and ping traffic externally. +- Ingress rules: + - SSH (port 22) from private IP. + - HTTPS (port 443) from private IP. + - ICMP (ping) from private IP. + +### Internal Connection Security Group + +- Name: `internal-connection-sg` +- Description: Allows SSH traffic internally. +- Ingress rule: + - SSH (port 22) from the `internal-connection-sg`. +- Egress rule: + - SSH (port 22) from the `internal-connection-sg`. + +## Usage + +1. Clone this repository. +2. Navigate to the project directory. +3. Initialize Terraform: + ```bash + terraform init + ``` +4. Create `terraform.tfvars` file with required variables. For example: + ```yaml + private_ip = ["45.80.184.49/32"] + vpc_cidr = "10.42.0.0/16" + vpc_name = "Production" + vpc_private_subnets = ["10.42.1.0/24"] + vpc_public_subnets = ["10.42.2.0/24"] + ``` +5. Test the infrastructure: + ```bash + terraform plan + ``` +6. When previous step completes successfully, deploy the infrastructure: + ```bash + terraform apply + ``` +7. Destroy the infrastructure when done: + ```bash + terraform destroy + ``` + +## Outputs + +- `instance_ip`: public IP of EC2 instance + +## Notes + +- Replace the default values in `variables.tf` with your desired settings. +- Ensure AWS credentials configured (either via environment variables or AWS CLI). diff --git a/Terraform/data.tf b/Terraform/data.tf new file mode 100644 index 0000000..3983b9a --- /dev/null +++ b/Terraform/data.tf @@ -0,0 +1,15 @@ +data "aws_ami" "ubuntu" { + most_recent = true + + filter { + name = "name" + values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"] + } + + filter { + name = "virtualization-type" + values = ["hvm"] + } + + owners = ["099720109477"] # Canonical +} \ No newline at end of file diff --git a/Terraform/instance.tf b/Terraform/instance.tf new file mode 100644 index 0000000..d961a6b --- /dev/null +++ b/Terraform/instance.tf @@ -0,0 +1,10 @@ +resource "aws_instance" "application" { + key_name = aws_key_pair.generated_key.key_name + ami = data.aws_ami.ubuntu.id + instance_type = "t3.micro" + associate_public_ip_address = true + vpc_security_group_ids = ["${aws_security_group.external_connection_sg.id}", "${aws_security_group.internal_connection_sg.id}"] + subnet_id = module.vpc.public_subnets[0] + + tags = var.tags +} diff --git a/Terraform/keypair.tf b/Terraform/keypair.tf new file mode 100644 index 0000000..9f809b1 --- /dev/null +++ b/Terraform/keypair.tf @@ -0,0 +1,15 @@ +resource "tls_private_key" "keypair_prv_key" { + algorithm = "RSA" + rsa_bits = 4096 +} + +resource "aws_key_pair" "generated_key" { + key_name = var.keypair_name + public_key = tls_private_key.keypair_prv_key.public_key_openssh +} + +resource "local_file" "pk_file" { + content = tls_private_key.keypair_prv_key.private_key_pem + filename = "${local.keypair_export_path}/${var.keypair_name}.pem" + file_permission = "0400" +} diff --git a/Terraform/locals.tf b/Terraform/locals.tf new file mode 100644 index 0000000..fdd51ad --- /dev/null +++ b/Terraform/locals.tf @@ -0,0 +1,4 @@ +locals { + vpc_azs = ["${var.aws_region}a"] + keypair_export_path = "${path.root}/secret" +} \ No newline at end of file diff --git a/Terraform/outputs.tf b/Terraform/outputs.tf new file mode 100644 index 0000000..37f1c47 --- /dev/null +++ b/Terraform/outputs.tf @@ -0,0 +1,3 @@ +output "instance_ip" { + value = aws_instance.application.public_ip +} \ No newline at end of file diff --git a/Terraform/sg.tf b/Terraform/sg.tf new file mode 100644 index 0000000..8969d1c --- /dev/null +++ b/Terraform/sg.tf @@ -0,0 +1,74 @@ +resource "aws_security_group" "external_connection_sg" { + name = "external-connection-sg" + description = "Allow SSH, HTTPS and ping traffic externally" + vpc_id = module.vpc.vpc_id +} + +resource "aws_security_group_rule" "External_SSH" { + type = "ingress" + from_port = 22 + to_port = 22 + protocol = "tcp" + cidr_blocks = var.private_ip + description = "SSH" + security_group_id = aws_security_group.external_connection_sg.id +} + +resource "aws_security_group_rule" "HTTPS" { + type = "ingress" + from_port = 443 + to_port = 443 + protocol = "tcp" + cidr_blocks = var.private_ip + description = "HTTPS" + + security_group_id = aws_security_group.external_connection_sg.id +} + +resource "aws_security_group_rule" "ping" { + type = "ingress" + from_port = 8 + to_port = 0 + protocol = "icmp" + cidr_blocks = var.private_ip + description = "ping" + + security_group_id = aws_security_group.external_connection_sg.id +} + +resource "aws_security_group_rule" "internet" { + type = "egress" + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + description = "access out" + + security_group_id = aws_security_group.external_connection_sg.id +} + +resource "aws_security_group" "internal_connection_sg" { + name = "internal-connection-sg" + description = "Allow SSH traffic internally" + vpc_id = module.vpc.vpc_id +} + +resource "aws_security_group_rule" "Internal_ingress_SSH" { + type = "ingress" + from_port = 22 + to_port = 22 + protocol = "tcp" + self = true + description = "SSH" + security_group_id = aws_security_group.internal_connection_sg.id +} + +resource "aws_security_group_rule" "Internal_egress_SSH" { + type = "egress" + from_port = 22 + to_port = 22 + protocol = "tcp" + self = true + description = "SSH" + security_group_id = aws_security_group.internal_connection_sg.id +} diff --git a/Terraform/terraform.tf b/Terraform/terraform.tf new file mode 100644 index 0000000..112fdf0 --- /dev/null +++ b/Terraform/terraform.tf @@ -0,0 +1,12 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.0" + } + } +} + +provider "aws" { + region = var.aws_region +} \ No newline at end of file diff --git a/Terraform/variables.tf b/Terraform/variables.tf new file mode 100644 index 0000000..8b274ff --- /dev/null +++ b/Terraform/variables.tf @@ -0,0 +1,45 @@ +variable "vpc_name" { + description = "The Name of the VPC." + type = string +} + +variable "aws_region" { + description = "AWS Region to deploy the VPC in" + type = string + default = "us-east-1" +} + +variable "vpc_cidr" { + description = "CIDR block for VPC" + type = string +} + +variable "vpc_private_subnets" { + description = "List of private subnets to create in VPC" + type = list(string) +} + +variable "vpc_public_subnets" { + description = "List of public subnets to create in VPC" + type = list(string) +} + +variable private_ip { + description = "Personal IP to connect with" + type = list(string) +} + +variable tags { + description = "Tags to add to all resources" + type = map + default = { + Terraform = "true" + DevopsMaster = "true" + } +} + +variable "keypair_name" { + description = "keypair_name" + type = string + default = "devops_kp" +} diff --git a/Terraform/vpc.tf b/Terraform/vpc.tf new file mode 100644 index 0000000..bc4b9a3 --- /dev/null +++ b/Terraform/vpc.tf @@ -0,0 +1,16 @@ +module "vpc" { + source = "terraform-aws-modules/vpc/aws" + + name = var.vpc_name + cidr = var.vpc_cidr + + azs = local.vpc_azs + private_subnets = var.vpc_private_subnets + public_subnets = var.vpc_public_subnets + + enable_nat_gateway = true + single_nat_gateway = true + one_nat_gateway_per_az = false + + tags = var.tags +} \ No newline at end of file