Skip to content

Commit

Permalink
Merge pull request #7 from lexxnsk/task_4
Browse files Browse the repository at this point in the history
Task 4
  • Loading branch information
lexxnsk authored Nov 3, 2024
2 parents 9965290 + 6925f12 commit 2727bb7
Show file tree
Hide file tree
Showing 11 changed files with 1,793 additions and 56 deletions.
34 changes: 34 additions & 0 deletions PR_descriptions/task_4.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Task 4 - Pull Request description
1. Task: [CLICK ME](https://github.com/rolling-scopes-school/tasks/blob/master/devops/modules/3_ci-configuration/task_4.md)
2. Screenshots (if needed): Check ./screenshots/ folder
3. Code: [CLICK ME](https://github.com/lexxnsk/rsschool-devops-course-tasks/tree/task_4)
4. Done 2024-11-03 17:00 / deadline 2024-11-04 00:59
5. Score: 100 / 100
###### Evaluation Criteria (100 points for covering all criteria)

1. **Helm Installation and Verification (10 points)**

- [+] Helm is installed and verified by deploying the Nginx chart.

2. **Cluster Requirements (10 points)**

- [+] The cluster has a solution for managing persistent volumes (PV) and persistent volume claims (PVC).

3. **Jenkins Installation (50 points)**

- [+] Jenkins is installed using Helm in a separate namespace.
- [+] Jenkins is available from the internet.

4. **Jenkins Configuration (10 points)**

- [+] Jenkins configuration is stored on a persistent volume and is not lost when Jenkins' pod is terminated.

5. **Verification (10 points)**

- [+] A simple Jenkins freestyle project is created and runs successfully, writing "Hello world" into the log.

6. **Additional Tasks (10 points)**
- **GitHub Actions (GHA) Pipeline (5 points)**
- [+] A GHA pipeline is set up to deploy Jenkins.
- **Authentication and Security (5 points)**
- [+] Authentication and security settings are configured for Jenkins.
126 changes: 118 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ This repository contains the Terraform configuration files used for provisioning
├── README.md
├── ec2.tf
├── igw.tf
├── jenkins-sa.yaml
├── jenkins-values.yaml
├── jenkins-volume.yaml
├── main.tf
├── nacl.tf
├── nat.tf
Expand All @@ -31,7 +34,7 @@ This repository contains the Terraform configuration files used for provisioning
- **```PR_descriptions/```**:
This directory contains the descriptions for Pull Request.
- **```screenshots/```**:
This directory contains screenshots and texts that verify the correct configuration of AWS accounts and installed software versions.
This directory contains necessary screenshots and texts.
- **```.gitignore```**:
This file specifies which files or directories should be ignored by Git when tracking changes in a repository.
- **```README.md```**:
Expand All @@ -40,6 +43,12 @@ This repository contains the Terraform configuration files used for provisioning
This file defines resources related to EC2 instances.
- **```igw.tf```**:
This file defines resources related to the Internet Gateway (IGW).
- **```jenkins-sa.yaml```**:
This file contains the configuration for a Service Account in a K3S cluster that is specifically used for Jenkins.
- **```jenkins-values.yaml```**:
This file contains configuration values that customize the deployment of Jenkins within a K3S cluster.
- **```jenkins-volume.yaml```**:
This file contains configuration to define persistent storage for Jenkins in a K3S environment.
- **```main.tf```**:
The main configuration file where the core infrastructure is defined. This typically includes high-level resources such as modules, remote backends, and resource declarations.
- **```nacl.tf```**:
Expand Down Expand Up @@ -121,14 +130,115 @@ You can list it using this command:
- Check it:
```ssh-add -l```
- Connect to the K3S Server node from your laptop via Bastion Host:
```ssh -A -J ec2-user@<PUBLIC_BASTION_IP> -i aws.pem ec2-user@<PRIVATE_K3S_SERVER_NODE_IP>```
```ssh -A -J ec2-user@<PUBLIC_BASTION_IP> ec2-user@<PRIVATE_K3S_SERVER_NODE_IP> 6443:localhost:6443```

**K3S installation consists of 2 nodes:**
**K3S installation consists of 1 node:**
You can check its status by:
```sudo /usr/local/bin/k3s kubectl get nodes```
```sudo /usr/local/bin/k3s kubectl get pods```
```sudo /usr/local/bin/k3s kubectl describe pods```
```sudo /usr/local/bin/k3s kubectl get services```
```
kubectl get nodes
kubectl get pods
kubectl describe pods
kubectl get services
```

**Connection to the K3S Server node from your laptop using port forwarding:**
- [Install](https://kubernetes.io/docs/tasks/tools/install-kubectl-macos/) KubeCTL binary locally on your laptop]
- Setup ssh port forwarding to your local machine:
```ssh -A -J [email protected] [email protected] -L 6443:localhost:6443```
- Check if it works using curl:
```
curl -k https://localhost:6443/
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {},
"status": "Failure",
"message": "Unauthorized",
"reason": "Unauthorized",
"code": 401
}%
```
- Copy content of a file ```/etc/rancher/k3s/k3s.yaml``` from K3S server node to your laptop
- Change permissions to prevent annoying warnings by ```chmod 600 /Users/amyslivets/Documents/AWS/k3s.yml```
- Export path to this local file to a variable and check it:
```
export KUBECONFIG=/Users/amyslivets/Documents/AWS/k3s.yml
echo $KUBECONFIG
/Users/amyslivets/Documents/AWS/k3s.yml
```
- Now kubectl should work locally from your laptop:
```
amyslivets@MacBook-Air-Alex rsschool-devops-course-tasks % kubectl get nodes
NAME STATUS ROLES AGE VERSION
ip-10-0-2-106 Ready control-plane,master 19m v1.30.6+k3s1
```

App deployment is done by executing:
```sudo /usr/local/bin/k3s kubectl apply -f https://k8s.io/examples/pods/simple-pod.yaml```
```kubectl apply -f https://k8s.io/examples/pods/simple-pod.yaml```


---
## Task 4 clarifications:
**K3S preparation:**
- You can change default K3S namespace by:
```kubectl config set-context --current --namespace=jenkins```
- You can install Jenkins using next commands:
```
helm repo add jenkins https://charts.jenkins.io
helm repo update
kubectl apply -f jenkins-volume.yaml
kubectl create namespace jenkins
kubectl apply -f jenkins-sa.yaml
chart=jenkinsci/jenkins
helm install jenkins -n jenkins -f jenkins-values.yaml $chart
```
- You can describe pod and then check init container logs for debug:
```kubectl logs jenkins-0 -c init```
```kubectl describe pod jenkins-0```
- You can check current pods status and check persistency by:
```
kubectl get pods
kubectl delete pod jenkins-0
kubectl get pods
```
- You can check service by:
```
kubectl get svc jenkins -n jenkins
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
jenkins NodePort 10.43.125.237 <none> 8080:32000/TCP 27m
```
- You can check current K3s storage class using this command:
```
kubectl get storageclass
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
jenkins-pv kubernetes.io/no-provisioner Delete WaitForFirstConsumer false 56m
local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 62m
```
- Here is a simple NGINX reverse proxy config to be installed on Bastion Host:
```
sudo vi /etc/nginx/conf.d/jenkins.conf
server {
listen 80;
server_name jenkins.myslivets.ru;
location / {
proxy_pass http://10.0.2.10:32000; # Forward requests to Jenkins
proxy_http_version 1.1; # Use HTTP/1.1 for proxying
proxy_set_header Upgrade $http_upgrade; # Handle WebSocket connections
proxy_set_header Connection 'upgrade'; # Handle WebSocket connections
proxy_set_header Host $host; # Preserve original Host header
proxy_set_header X-Real-IP $remote_addr; # Pass the client IP address
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # Preserve client IP
proxy_set_header X-Forwarded-Proto $scheme; # Preserve protocol (http or https)
}
}
chmod 600 /Users/amyslivets/Documents/AWS/k3s.yml
sudo nginx -t
sudo systemctl restart nginx
```
- You can simulate Jenkins on Server Node by running a simple Python Server:
```
sudo python3 -m http.server 32000
```
135 changes: 107 additions & 28 deletions ec2.tf
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,76 @@

# # # # # # # # # # # Task_3 code start # # # # # # # # # #

# # Create a Bastion Host instance for secure access to private subnets
# resource "aws_instance" "bastion_host" {
# ami = var.ec2_ami_k3s
# instance_type = var.ec2_instance_bastion
# subnet_id = aws_subnet.public[0].id
# vpc_security_group_ids = [
# aws_security_group.allow_ssh.id,
# aws_security_group.allow_icmp.id,
# aws_security_group.allow_k3s.id
# ]
# key_name = aws_key_pair.my_key.key_name
# tags = {
# Name = "Bastion Node"
# }
# }

# # Create a K3S Server Node ec2 instance in Private nerwork
# resource "aws_instance" "server_node" {
# ami = var.ec2_ami_k3s
# instance_type = var.ec2_instance_k3s
# subnet_id = aws_subnet.private[0].id
# vpc_security_group_ids = [
# aws_security_group.allow_ssh.id,
# aws_security_group.allow_icmp.id,
# aws_security_group.allow_k3s.id,
# aws_security_group.allow_http.id,
# aws_security_group.allow_https.id
# ]
# key_name = aws_key_pair.my_key.key_name
# tags = {
# Name = "K3S Server node"
# }
# # This installs k3s server node
# user_data = <<-EOF
# #!/bin/bash
# curl -sfL https://get.k3s.io/ | INSTALL_K3S_EXEC="server" sh -s - --token ${var.k3s_token}
# EOF
# }

# # Create a K3S Agent Node ec2 instance in Private nerwork
# resource "aws_instance" "agent_node_1" {
# ami = var.ec2_ami_k3s
# instance_type = var.ec2_instance_k3s
# subnet_id = aws_subnet.private[1].id
# vpc_security_group_ids = [
# aws_security_group.allow_ssh.id,
# aws_security_group.allow_icmp.id,
# aws_security_group.allow_k3s.id,
# aws_security_group.allow_http.id,
# aws_security_group.allow_https.id
# ]
# key_name = aws_key_pair.my_key.key_name
# tags = {
# Name = "K3S Agent node 1 - test"
# }
# # This installs k3s agent node and joins it to a server node
# user_data = <<-EOF
# #!/bin/bash
# curl -sfL https://get.k3s.io/ | INSTALL_K3S_EXEC="agent" K3S_URL=https://${aws_instance.server_node.private_ip}:6443/ K3S_TOKEN=${var.k3s_token} sh -s -
# EOF
# depends_on = [aws_instance.server_node]
# }

# # # # # # # # # # # Task_3 code end # # # # # # # # # #



# # # # # # # # # # # Task_4 code start # # # # # # # # # #


# Create a Bastion Host instance for secure access to private subnets
resource "aws_instance" "bastion_host" {
ami = var.ec2_ami_k3s
Expand All @@ -48,7 +118,8 @@ resource "aws_instance" "bastion_host" {
vpc_security_group_ids = [
aws_security_group.allow_ssh.id,
aws_security_group.allow_icmp.id,
aws_security_group.allow_k3s.id
aws_security_group.allow_k3s.id,
aws_security_group.allow_web.id
]
key_name = aws_key_pair.my_key.key_name
tags = {
Expand All @@ -65,42 +136,50 @@ resource "aws_instance" "server_node" {
aws_security_group.allow_ssh.id,
aws_security_group.allow_icmp.id,
aws_security_group.allow_k3s.id,
aws_security_group.allow_http.id,
aws_security_group.allow_https.id
aws_security_group.allow_web.id
]
key_name = aws_key_pair.my_key.key_name
# Specify the fixed private IP address
private_ip = var.server_node_fixed_private_ip
tags = {
Name = "K3S Server node"
}
# This installs k3s server node
# This installs K3S server node and Helm
user_data = <<-EOF
#!/bin/bash
# Install K3S
curl -sfL https://get.k3s.io/ | INSTALL_K3S_EXEC="server" sh -s - --token ${var.k3s_token}
# Install Helm
curl -sfL https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | sh -s -
# fix Jenkins pod start problem
sudo mkdir -p /data/jenkins-volume
sudo chown -R 1000:1000 /data/jenkins-volume
EOF
}

# Create a K3S Agent Node ec2 instance in Private nerwork
resource "aws_instance" "agent_node_1" {
ami = var.ec2_ami_k3s
instance_type = var.ec2_instance_k3s
subnet_id = aws_subnet.private[1].id
vpc_security_group_ids = [
aws_security_group.allow_ssh.id,
aws_security_group.allow_icmp.id,
aws_security_group.allow_k3s.id,
aws_security_group.allow_http.id,
aws_security_group.allow_https.id
]
key_name = aws_key_pair.my_key.key_name
tags = {
Name = "K3S Agent node 1 - test"
}
# This installs k3s agent node and joins it to a server node
user_data = <<-EOF
#!/bin/bash
curl -sfL https://get.k3s.io/ | INSTALL_K3S_EXEC="agent" K3S_URL=https://${aws_instance.server_node.private_ip}:6443/ K3S_TOKEN=${var.k3s_token} sh -s -
EOF
depends_on = [aws_instance.server_node]
}
# # Create a K3S Agent Node ec2 instance in Private nerwork. Uncomment it, if you want to create an agent node.
# resource "aws_instance" "agent_node_1" {
# ami = var.ec2_ami_k3s
# instance_type = var.ec2_instance_k3s
# subnet_id = aws_subnet.private[1].id
# vpc_security_group_ids = [
# aws_security_group.allow_ssh.id,
# aws_security_group.allow_icmp.id,
# aws_security_group.allow_k3s.id,
# aws_security_group.allow_http.id,
# aws_security_group.allow_https.id
# ]
# key_name = aws_key_pair.my_key.key_name
# tags = {
# Name = "K3S Agent node 1 - test"
# }
# # This installs k3s agent node and joins it to a server node
# user_data = <<-EOF
# #!/bin/bash
# curl -sfL https://get.k3s.io/ | INSTALL_K3S_EXEC="agent" K3S_URL=https://${aws_instance.server_node.private_ip}:6443/ K3S_TOKEN=${var.k3s_token} sh -s -
# EOF
# depends_on = [aws_instance.server_node]
# }


# # # # # # # # # # # Task_3 code end # # # # # # # # # #
# # # # # # # # # # # Task_4 code end # # # # # # # # # #
Loading

0 comments on commit 2727bb7

Please sign in to comment.