diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..8c8f2e3 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,57 @@ +pipeline { + agent any + environment { + dockerCreds = credentials('dockerhub_login') // used to get the username for next var + registry = "${dockerCreds_USR}/nodejs-webserver" + registryCredentials = "dockerhub_login" + dockerImage = "" // empty var, will be written to later + } + stages { + stage('Build Image') { + steps { + dir('web') { + script { + dockerImage = docker.build(registry) + } + } + } + } + stage('Test App') { + environment { + SERVER_IMAGE = dockerImage.imageName() + } + steps { + sh 'docker compose up -d' + sh 'curl -s http://localhost/web1' + sh 'curl -s http://localhost/web2' + sh 'docker compose down' + } + } + stage('Push Image') { + steps { + script { + docker.withRegistry("", registryCredentials) { + dockerImage.push("${env.BUILD_NUMBER}") + dockerImage.push("latest") + } + } + } + } + stage('Clean Up') { + steps { + sh "docker image prune --all --force --filter 'until=48h'" // ensure that we don't accrue too many out-of-date images + } + } + stage('Deploy To Cluster') { + steps { + sh 'cp -u /mnt/k3s/config config.yaml' + sh 'cp -u nginx/nginx.conf terraform/nginx.conf' + dir('terraform') { + sh 'terraform init' + sh 'terraform apply -auto-approve -no-color -var config_path=${WORKSPACE}/config.yaml -var server_image=${registry}' + sh 'terraform output -no-color' + } + } + } + } +} diff --git a/terraform/main.tf b/terraform/main.tf new file mode 100644 index 0000000..07c23f1 --- /dev/null +++ b/terraform/main.tf @@ -0,0 +1,14 @@ +module "web1" { + source = "./web_deploy" + + image = "${var.server_image}" + replicas = 3 + deployment_name = "web1" +} +module "web2" { + source = "./web_deploy" + + image = "${var.server_image}" + replicas = 3 + deployment_name = "web2" +} diff --git a/terraform/nginx.tf b/terraform/nginx.tf new file mode 100644 index 0000000..34ccf98 --- /dev/null +++ b/terraform/nginx.tf @@ -0,0 +1,87 @@ +resource "kubernetes_deployment" "nginx" { + metadata { + name = "nginx" + labels = { + app = "nginx" + } + } + + spec { + replicas = 3 + + selector { + match_labels = { + app = "nginx" + } + } + + template { + metadata { + labels = { + app = "nginx" + } + annotations = { + "config.linkerd.io/proxy-cpu-limit" = "10m" + "linkerd.io/inject" = "enabled" + } + } + + spec { + container { + image = "nginx:alpine" + name = "nginx" + + resources { + limits = { + cpu = "200m" + memory = "256Mi" + } + requests = { + cpu = "100m" + memory = "128Mi" + } + } + + volume_mount { + name = "${kubernetes_config_map.nginx.metadata.0.name}" + mount_path = "/etc/nginx/conf.d/" + } + } + volume { + name = "${kubernetes_config_map.nginx.metadata.0.name}" + config_map { + name = "${kubernetes_config_map.nginx.metadata.0.name}" + } + } + } + } + } +} + +resource "kubernetes_service" "nginx" { + metadata { + name = "nginx" + } + spec { + selector = { + app = "nginx" + } + + port { + port = 80 + target_port = 80 + } + + type = "NodePort" + } +} + +resource "kubernetes_config_map" "nginx" { + metadata { + name = "nginx-config" + } + + data = { + "default.conf" = "${file("nginx.conf")}" + } +} diff --git a/terraform/outputs.tf b/terraform/outputs.tf new file mode 100644 index 0000000..7f78b77 --- /dev/null +++ b/terraform/outputs.tf @@ -0,0 +1,3 @@ +output "node_port" { + value = "${kubernetes_service.nginx.spec.0.port.0.node_port}" +} diff --git a/terraform/providers.tf b/terraform/providers.tf new file mode 100644 index 0000000..bc822a2 --- /dev/null +++ b/terraform/providers.tf @@ -0,0 +1,12 @@ +terraform { + required_providers { + kubernetes = { + source = "hashicorp/kubernetes" + version = "2.37.1" + } + } +} + +provider "kubernetes" { + config_path = var.config_path +} diff --git a/terraform/redis.tf b/terraform/redis.tf new file mode 100644 index 0000000..76670c0 --- /dev/null +++ b/terraform/redis.tf @@ -0,0 +1,42 @@ +resource "kubernetes_pod" "redis" { + metadata { + name = "redis" + labels = { + app = "redis" + } + annotations = { + "config.linkerd.io/proxy-cpu-limit" = "10m" + "linkerd.io/inject" = "enabled" + } + } + + spec { + container { + image = "redislabs/redismod" + name = "redis" + + port { + container_port = 6379 + } + } + } +} + +resource "kubernetes_service" "redis" { + metadata { + name = "redis" + } + + spec { + port { + port = 6379 + target_port = 6379 + } + + selector = { + app = "redis" + } + + type = "ClusterIP" + } +} diff --git a/terraform/variables.tf b/terraform/variables.tf new file mode 100644 index 0000000..46653a2 --- /dev/null +++ b/terraform/variables.tf @@ -0,0 +1,2 @@ +variable "config_path" {} +variable "server_image" {} diff --git a/terraform/web_deploy/main.tf b/terraform/web_deploy/main.tf new file mode 100644 index 0000000..2782c96 --- /dev/null +++ b/terraform/web_deploy/main.tf @@ -0,0 +1,67 @@ +resource "kubernetes_deployment" "deploy" { + metadata { + name = "${var.deployment_name}" + labels = { + app = "nodejs-${var.deployment_name}" + } + } + + spec { + replicas = var.replicas + + selector { + match_labels = { + app = "nodejs-${var.deployment_name}" + } + } + + template { + metadata { + labels = { + app = "nodejs-${var.deployment_name}" + } + annotations = { + "config.linkerd.io/proxy-cpu-limit" = "10m" + "linkerd.io/inject" = "enabled" + } + } + + spec { + container { + image = "${var.image}" + image_pull_policy = "Always" + name = "${var.deployment_name}" + + resources { + limits = { + cpu = "200m" + memory = "256Mi" + } + requests = { + cpu = "100m" + memory = "128Mi" + } + } + } + } + } + } +} + +resource "kubernetes_service" "svc" { + metadata { + name = "${var.deployment_name}" + } + spec { + selector = { + app = "nodejs-${var.deployment_name}" + } + + port { + port = 5000 + target_port = 5000 + } + + type = "ClusterIP" + } +} diff --git a/terraform/web_deploy/variables.tf b/terraform/web_deploy/variables.tf new file mode 100644 index 0000000..fedd5c0 --- /dev/null +++ b/terraform/web_deploy/variables.tf @@ -0,0 +1,3 @@ +variable "deployment_name" {} +variable "replicas" {} +variable "image" {}