From 60b2cf65c78bd40d58fd6a135a7f370c22edc218 Mon Sep 17 00:00:00 2001 From: "ochuko.ebireri" Date: Sat, 14 Sep 2024 15:42:27 -0600 Subject: [PATCH 01/10] added docker file --- bird/Dockerfile | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 bird/Dockerfile diff --git a/bird/Dockerfile b/bird/Dockerfile new file mode 100644 index 0000000..b35624c --- /dev/null +++ b/bird/Dockerfile @@ -0,0 +1,30 @@ +# Use the official Golang image as the base image for building the app +FROM golang:1.22.5-alpine AS builder + +# Set the current working directory inside the container +WORKDIR /app + +# Copy the go.mod and go.sum files first, then download the dependencies +COPY go.mod go.sum ./ +RUN go mod download + +# Copy the rest of the application source code +COPY . . + +# Build the Go application binary +RUN go build -o api . + +# Use a smaller base image for the runtime +FROM alpine:3.18 + +# Set a working directory +WORKDIR /app + +# Copy the binary from the builder stage +COPY --from=builder /app/api /app/api + +# Expose the port the app will run on +EXPOSE 8080 + +# Set the command to run the API binary +CMD ["./api"] From a0ead0cd660cabdb944c98040aa3f4303542f7d3 Mon Sep 17 00:00:00 2001 From: "ochuko.ebireri" Date: Thu, 19 Sep 2024 12:22:03 -0600 Subject: [PATCH 02/10] completed work --- .gitattributes | 2 + .github/workflows/docker-image.yaml | 48 +++++++++++++++ .github/workflows/pr.yaml | 50 +++++++++++++++ .github/workflows/ssh.yaml | 29 +++++++++ .github/workflows/terraform.tfstate | 9 +++ Makefile | 14 +++++ bird/Dockerfile | 13 +--- bird/main.go | 67 ++++++++++++++------ birdImage/Dockerfile | 21 +++++++ birdImage/main.go | 54 +++++++++++------ infra/README.md | 34 +++++++++++ infra/ami.tf | 25 ++++++++ infra/apache_install.sh | 6 ++ infra/ec2.tf | 38 ++++++++++++ infra/ecr.tf | 29 +++++++++ infra/key-pair.tf | 13 ++++ infra/local-values.tf | 10 +++ infra/main.tf | 39 ++++++++++++ infra/output.tf | 23 +++++++ infra/sg.tf | 33 ++++++++++ infra/var.tf | 30 +++++++++ infra/vpc.tf | 50 +++++++++++++++ k8/README.md | 50 +++++++++++++++ k8/bird-release/Chart.yaml | 5 ++ k8/bird-release/templates/deployment.yaml | 74 +++++++++++++++++++++++ k8/bird-release/templates/helper.tpl | 6 ++ k8/bird-release/templates/hpa.yaml | 38 ++++++++++++ k8/bird-release/templates/pv.yaml | 18 ++++++ k8/bird-release/templates/pvc.yaml | 12 ++++ k8/bird-release/templates/svc.yaml | 13 ++++ k8/bird-release/values.yaml | 25 ++++++++ 31 files changed, 832 insertions(+), 46 deletions(-) create mode 100644 .gitattributes create mode 100644 .github/workflows/docker-image.yaml create mode 100644 .github/workflows/pr.yaml create mode 100644 .github/workflows/ssh.yaml create mode 100644 .github/workflows/terraform.tfstate create mode 100644 Makefile create mode 100644 birdImage/Dockerfile create mode 100644 infra/README.md create mode 100644 infra/ami.tf create mode 100644 infra/apache_install.sh create mode 100644 infra/ec2.tf create mode 100644 infra/ecr.tf create mode 100644 infra/key-pair.tf create mode 100644 infra/local-values.tf create mode 100644 infra/main.tf create mode 100644 infra/output.tf create mode 100644 infra/sg.tf create mode 100644 infra/var.tf create mode 100644 infra/vpc.tf create mode 100644 k8/README.md create mode 100644 k8/bird-release/Chart.yaml create mode 100644 k8/bird-release/templates/deployment.yaml create mode 100644 k8/bird-release/templates/helper.tpl create mode 100644 k8/bird-release/templates/hpa.yaml create mode 100644 k8/bird-release/templates/pv.yaml create mode 100644 k8/bird-release/templates/pvc.yaml create mode 100644 k8/bird-release/templates/svc.yaml create mode 100644 k8/bird-release/values.yaml diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..ba3f231 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +.exe filter=lfs diff=lfs merge=lfs -text +*.exe filter=lfs diff=lfs merge=lfs -text diff --git a/.github/workflows/docker-image.yaml b/.github/workflows/docker-image.yaml new file mode 100644 index 0000000..89b50f0 --- /dev/null +++ b/.github/workflows/docker-image.yaml @@ -0,0 +1,48 @@ +# name: Docker Image CI + +# on: +# push: +# branches: [ "main" ] +# pull_request: +# branches: [ "main" ] + +# jobs: + +# build-and-push: +# runs-on: ubuntu-latest + +# steps: +# - uses: actions/checkout@v4 + +# # Step 1: Log in to Amazon ECR +# - name: Configure AWS credentials +# uses: aws-actions/configure-aws-credentials@v2 +# with: +# role-to-assume: arn:aws:iam::ACCOUNT_ID:role/ROLE_NAME # Optional, for using an IAM role +# aws-region: us-east-1 +# aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} +# aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + +# - name: Login to Amazon ECR +# run: | +# aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.us-east-1.amazonaws.com + +# # Step 2: Build the Docker image +# - name: Build the Docker image +# run: | +# IMAGE_NAME=$(basename "$PWD") +# docker build . --file Dockerfile --tag $IMAGE_NAME:latest + +# # Step 3: Tag the image with ECR repository URL +# - name: Tag the Docker image +# run: | +# IMAGE_NAME=$(basename "$PWD") +# ECR_URI=${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.us-east-1.amazonaws.com/$IMAGE_NAME +# docker tag $IMAGE_NAME:latest $ECR_URI:latest + +# # Step 4: Push the Docker image to ECR +# - name: Push the Docker image to ECR +# run: | +# IMAGE_NAME=$(basename "$PWD") +# ECR_URI=${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.us-east-1.amazonaws.com/$IMAGE_NAME +# docker push $ECR_URI:latest diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml new file mode 100644 index 0000000..bd57f86 --- /dev/null +++ b/.github/workflows/pr.yaml @@ -0,0 +1,50 @@ +# name: CI Pipeline + +# on: +# pull_request: +# types: [opened, synchronize, reopened] + +# jobs: +# build: +# name: Build and Test +# runs-on: ubuntu-latest + +# steps: +# # Checkout the repository code +# - name: Checkout code +# uses: actions/checkout@v3 + +# # Set up the programming language environment (example: Node.js) +# - name: Set up Node.js +# uses: actions/setup-node@v3 +# with: +# node-version: '14' + +# # Install dependencies +# - name: Install dependencies +# run: npm install + +# # Run tests +# - name: Run tests +# run: npm test + +# # Post success or failure message to the pull request +# notify: +# name: Notify GitHub PR +# runs-on: ubuntu-latest +# needs: build +# steps: +# - name: Post status to PR +# uses: actions/github-script@v6 +# with: +# script: | +# const status = "${{ job.status }}"; +# const message = status === 'success' +# ? ':white_check_mark: Build and tests passed!' +# : ':x: Build or tests failed.'; +# github.rest.issues.createComment({ +# issue_number: context.payload.pull_request.number, +# owner: context.repo.owner, +# repo: context.repo.repo, +# body: message +# }); diff --git a/.github/workflows/ssh.yaml b/.github/workflows/ssh.yaml new file mode 100644 index 0000000..d9b1070 --- /dev/null +++ b/.github/workflows/ssh.yaml @@ -0,0 +1,29 @@ +# name: Node CI + +# on: [push] + +# jobs: +# build: + +# runs-on: ubuntu-latest + +# steps: +# - uses: actions/checkout@v3 +# - name: Install Node.js +# uses: actions/setup-node@v3 +# with: +# node-version: '16.x' +# - name: Install npm dependencies +# run: npm install +# - name: Run build task +# run: npm run build --if-present +# - name: Deploy to Server +# uses: easingthemes/ssh-deploy@main +# with: +# SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} +# ARGS: "-rlgoDzvc -i --delete" +# SOURCE: "dist/" +# REMOTE_HOST: ${{ secrets.REMOTE_HOST }} +# REMOTE_USER: ${{ secrets.REMOTE_USER }} +# TARGET: ${{ secrets.REMOTE_TARGET }} +# EXCLUDE: "/dist/, /node_modules/" \ No newline at end of file diff --git a/.github/workflows/terraform.tfstate b/.github/workflows/terraform.tfstate new file mode 100644 index 0000000..3b00260 --- /dev/null +++ b/.github/workflows/terraform.tfstate @@ -0,0 +1,9 @@ +{ + "version": 4, + "terraform_version": "1.8.4", + "serial": 1, + "lineage": "baa12152-04e6-5772-e8cd-545f9a18b9ed", + "outputs": {}, + "resources": [], + "check_results": null +} diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6036112 --- /dev/null +++ b/Makefile @@ -0,0 +1,14 @@ +docker_registry_secret: + kubectl create secret docker-registry regcred \ + --docker-server={AWS-ACCOUNT}.dkr.ecr.{}.amazonaws.com \ + --docker-username=AWS \ + --docker-password=$(aws ecr get-login-password) \ + +docker-build: + docker build -f bird/Dockerfile -t bird . + + +docker-push: + + +k8s-deploy: diff --git a/bird/Dockerfile b/bird/Dockerfile index b35624c..b9f53e2 100644 --- a/bird/Dockerfile +++ b/bird/Dockerfile @@ -1,30 +1,19 @@ -# Use the official Golang image as the base image for building the app FROM golang:1.22.5-alpine AS builder -# Set the current working directory inside the container WORKDIR /app -# Copy the go.mod and go.sum files first, then download the dependencies -COPY go.mod go.sum ./ +COPY go.mod ./ RUN go mod download # Copy the rest of the application source code COPY . . -# Build the Go application binary RUN go build -o api . -# Use a smaller base image for the runtime FROM alpine:3.18 -# Set a working directory WORKDIR /app -# Copy the binary from the builder stage COPY --from=builder /app/api /app/api -# Expose the port the app will run on -EXPOSE 8080 - -# Set the command to run the API binary CMD ["./api"] diff --git a/bird/main.go b/bird/main.go index 99f03fe..e6cff08 100644 --- a/bird/main.go +++ b/bird/main.go @@ -5,9 +5,10 @@ import ( "encoding/json" "fmt" "io" - "math/rand/v2" + "math/rand" "net/http" "net/url" + "time" ) type Bird struct { @@ -16,6 +17,7 @@ type Bird struct { Image string } +// Function to return a default bird in case of errors func defaultBird(err error) Bird { return Bird{ Name: "Bird in disguise", @@ -24,48 +26,79 @@ func defaultBird(err error) Bird { } } +// Function to get bird image by bird name func getBirdImage(birdName string) (string, error) { - res, err := http.Get(fmt.Sprintf("http://localhost:4200?birdName=%s", url.QueryEscape(birdName))) - if err != nil { - return "", err - } - body, err := io.ReadAll(res.Body) - return string(body), err + res, err := http.Get(fmt.Sprintf("http://localhost:4200?birdName=%s", url.QueryEscape(birdName))) + if err != nil { + return "", err + } + defer res.Body.Close() // Ensure body is closed after reading + + body, err := io.ReadAll(res.Body) + if err != nil { + return "", err + } + return string(body), nil } +// Function to fetch bird factoid from API func getBirdFactoid() Bird { - res, err := http.Get(fmt.Sprintf("%s%d", "https://freetestapi.com/api/v1/birds/", rand.IntN(50))) + res, err := http.Get(fmt.Sprintf("%s%d", "https://freetestapi.com/api/v1/birds/", rand.Intn(50))) if err != nil { fmt.Printf("Error reading bird API: %s\n", err) return defaultBird(err) } + defer res.Body.Close() // Ensure body is closed after reading + body, err := io.ReadAll(res.Body) if err != nil { fmt.Printf("Error parsing bird API response: %s\n", err) return defaultBird(err) } + var bird Bird err = json.Unmarshal(body, &bird) if err != nil { - fmt.Printf("Error unmarshalling bird: %s", err) + fmt.Printf("Error unmarshalling bird: %s\n", err) + return defaultBird(err) + } + + // Fetch bird image + birdImage, err := getBirdImage(bird.Name) + if err != nil { + fmt.Printf("Error in getting bird image: %s\n", err) return defaultBird(err) } - birdImage, err := getBirdImage(bird.Name) - if err != nil { - fmt.Printf("Error in getting bird image: %s\n", err) - return defaultBird(err) - } - bird.Image = birdImage + bird.Image = birdImage return bird } +// HTTP handler for bird factoid endpoint func bird(w http.ResponseWriter, r *http.Request) { var buffer bytes.Buffer - json.NewEncoder(&buffer).Encode(getBirdFactoid()) - io.WriteString(w, buffer.String()) + err := json.NewEncoder(&buffer).Encode(getBirdFactoid()) + if err != nil { + http.Error(w, "Failed to encode bird factoid", http.StatusInternalServerError) + return + } + w.Header().Set("Content-Type", "application/json") + w.Write(buffer.Bytes()) +} + +// HTTP handler for health check endpoint +func healthCheck(w http.ResponseWriter, r *http.Request) { + w.Write([]byte("ok")) } func main() { + // Seed the random generator + rand.Seed(time.Now().UnixNano()) + + // Define HTTP handlers http.HandleFunc("/", bird) + http.HandleFunc("/healthz", healthCheck) + + // Start the HTTP server + fmt.Println("Server is starting on port 4201...") http.ListenAndServe(":4201", nil) } diff --git a/birdImage/Dockerfile b/birdImage/Dockerfile new file mode 100644 index 0000000..a3b2993 --- /dev/null +++ b/birdImage/Dockerfile @@ -0,0 +1,21 @@ +FROM golang:1.22.5-alpine AS builder + +WORKDIR /app + +COPY go.mod ./ +RUN go mod download + +# Copy the rest of the application source code +COPY . . + +RUN go build -o api . + +FROM alpine:3.18 + +WORKDIR /app + +COPY --from=builder /app/api /app/api + +EXPOSE 8080 + +CMD ["./api"] diff --git a/birdImage/main.go b/birdImage/main.go index 15feacb..8c423e7 100644 --- a/birdImage/main.go +++ b/birdImage/main.go @@ -10,62 +10,82 @@ import ( ) type Urls struct { - Thumb string + Thumb string `json:"thumb"` } type Links struct { - Urls Urls + Urls Urls `json:"urls"` } type ImageResponse struct { - Results []Links + Results []Links `json:"results"` } type Bird struct { Image string } +// Default image URL in case of errors or no results func defaultImage() string { - return "https://www.pokemonmillennium.net/wp-content/uploads/2015/11/missingno.png" + return "https://www.pokemonmillennium.net/wp-content/uploads/2015/11/missingno.png" } +// Function to get bird image using Unsplash API func getBirdImage(birdName string) string { - var query = fmt.Sprintf( - "https://api.unsplash.com/search/photos?page=1&query=%s&client_id=P1p3WPuRfpi7BdnG8xOrGKrRSvU1Puxc1aueUWeQVAI&per_page=1", - url.QueryEscape(birdName), - ) + query := fmt.Sprintf( + "https://api.unsplash.com/search/photos?page=1&query=%s&client_id=P1p3WPuRfpi7BdnG8xOrGKrRSvU1Puxc1aueUWeQVAI&per_page=1", + url.QueryEscape(birdName), + ) res, err := http.Get(query) if err != nil { fmt.Printf("Error reading image API: %s\n", err) return defaultImage() } + defer res.Body.Close() // Ensure the body is closed after reading + body, err := io.ReadAll(res.Body) if err != nil { fmt.Printf("Error parsing image API response: %s\n", err) return defaultImage() } + var response ImageResponse err = json.Unmarshal(body, &response) if err != nil { - fmt.Printf("Error unmarshalling bird image: %s", err) + fmt.Printf("Error unmarshalling bird image: %s\n", err) + return defaultImage() + } + + // Check if the result contains any images + if len(response.Results) == 0 { + fmt.Println("No images found for the bird") return defaultImage() } - return response.Results[0].Urls.Thumb + + return response.Results[0].Urls.Thumb } +// Handler for fetching bird image func bird(w http.ResponseWriter, r *http.Request) { var buffer bytes.Buffer - birdName := r.URL.Query().Get("birdName") - if birdName == "" { - json.NewEncoder(&buffer).Encode(defaultImage()) - } else { - json.NewEncoder(&buffer).Encode(getBirdImage(birdName)) - } + birdName := r.URL.Query().Get("birdName") + if birdName == "" { + json.NewEncoder(&buffer).Encode(defaultImage()) + } else { + json.NewEncoder(&buffer).Encode(getBirdImage(birdName)) + } + w.Header().Set("Content-Type", "application/json") io.WriteString(w, buffer.String()) } +// Health check handler +func healthCheck(w http.ResponseWriter, r *http.Request) { + w.Write([]byte("ok")) // Removed the incorrect `=` +} + func main() { http.HandleFunc("/", bird) + http.HandleFunc("/healthz", healthCheck) + fmt.Println("Server running on port 4200...") http.ListenAndServe(":4200", nil) } - diff --git a/infra/README.md b/infra/README.md new file mode 100644 index 0000000..0cb8754 --- /dev/null +++ b/infra/README.md @@ -0,0 +1,34 @@ +About: +This simple infra was provisioned on AWS using IAC(Terraform) to manage a k8s application already deployed using helm. + +Steps to Reproduce +A list of the resources provisioned include: +1. AWS vpc - Provisioned using a module +2. AWS ec2 instance with ubuntu AMI (provisioned using a data source) - The following commands were added to the userdata as part of the bootscript in order to install k8s and docker within the instance + +curl -sfL https://get.k3s.io | sh -s - --write-kubeconfig-mode 644 +curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--tls-san your_server_ip" sh - +sudo apt update -y && sudo apt install docker.io -y +sudo usermod -aG docker $USER + newgrp docker + + 3. AWS security group + 4. AWS ECR + +As soon as the ec2 instance is deployed you will be able to ssh into it using +ssh -i ubuntu@ or using ec2-instance-connect. The k3 will already be installed via the user data. +An attempt to run kubectl get nodes creates the following error: +'''k3s kubectl version +WARN[0000] Unable to read /etc/rancher/k3s/k3s.yaml, please start server with --write-kubeconfig-mode to modify kube config permissions +error: error loading config file "/etc/rancher/k3s/k3s.yaml" : open /etc/rancher/k3s/k3s.yaml: permission denied''' + +in order to overcome this , run the following commands: +export KUBECONFIG=~/.kube/config +mkdir ~/.kube 2> /dev/null +sudo k3s kubectl config view --raw > "$KUBECONFIG" +chmod 600 "$KUBECONFIG" + +afterwards all commands can run +its important to change the default namespace for the context to bird using the following commands : +> + command to verify it has been changed to bird as default \ No newline at end of file diff --git a/infra/ami.tf b/infra/ami.tf new file mode 100644 index 0000000..915a157 --- /dev/null +++ b/infra/ami.tf @@ -0,0 +1,25 @@ +#data source for the AMI +data "aws_ami" "ubuntu" { + most_recent = true + owners = ["amazon"] + + filter { + name = "name" + values = ["al2023-ami-*"] + } + + filter { + name = "root-device-type" + values = ["ebs"] + } + + filter { + name = "virtualization-type" + values = ["hvm"] + } + + filter { + name = "architecture" + values = ["x86_64"] + } +} \ No newline at end of file diff --git a/infra/apache_install.sh b/infra/apache_install.sh new file mode 100644 index 0000000..b43f2d0 --- /dev/null +++ b/infra/apache_install.sh @@ -0,0 +1,6 @@ +#! /bin/bash +curl -sfL https://get.k3s.io | sh -s - --write-kubeconfig-mode 644 +curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--tls-san your_server_ip" sh - +sudo apt update -y && sudo apt install docker.io -y +sudo usermod -aG docker $USER +newgrp docker \ No newline at end of file diff --git a/infra/ec2.tf b/infra/ec2.tf new file mode 100644 index 0000000..df0c8ef --- /dev/null +++ b/infra/ec2.tf @@ -0,0 +1,38 @@ + +resource "aws_instance" "web" { + ami = "ami-0e86e20dae9224db8" + key_name = "deployer-key" + subnet_id = element(module.vpc.public_subnets, 0) + user_data = "${file("apache_install.sh")}" + vpc_security_group_ids = [aws_security_group.bastion-instance.id] + associate_public_ip_address = true + instance_type = "t2.micro" + + provisioner "file" { + source = ".././k8" + destination = "/home/ec2-user/remote-directory" + + connection { + type = "ssh" + user = "ec2-user" + host = self.public_ip + private_key = tls_private_key.ed25519-example.private_key_pem + } + } + + provisioner "remote-exec" { + inline = [ + "echo 'Files copied!'" + ] + + connection { + type = "ssh" + user = "ec2-user" + host = self.public_ip + private_key = tls_private_key.ed25519-example.private_key_pem + } + } + tags = { + Name = local.name + } +} \ No newline at end of file diff --git a/infra/ecr.tf b/infra/ecr.tf new file mode 100644 index 0000000..d930506 --- /dev/null +++ b/infra/ecr.tf @@ -0,0 +1,29 @@ +module "ecr" { + source = "terraform-aws-modules/ecr/aws" + + repository_name = "private-example" + + repository_read_write_access_arns = ["arn:aws:iam::891376975226:role/Ec2roleforECR"] + repository_lifecycle_policy = jsonencode({ + rules = [ + { + rulePriority = 1, + description = "Keep last 30 images", + selection = { + tagStatus = "tagged", + tagPrefixList = ["v"], + countType = "imageCountMoreThan", + countNumber = 30 + }, + action = { + type = "expire" + } + } + ] + }) + + tags = { + Terraform = "true" + Environment = "dev" + } +} \ No newline at end of file diff --git a/infra/key-pair.tf b/infra/key-pair.tf new file mode 100644 index 0000000..76909f9 --- /dev/null +++ b/infra/key-pair.tf @@ -0,0 +1,13 @@ +resource "aws_key_pair" "deployer" { + key_name = "deployer-key" + public_key = tls_private_key.ed25519-example.public_key_openssh +} + +resource "tls_private_key" "ed25519-example" { + algorithm = "RSA" + rsa_bits =4096 +} +resource "local_file" "TF-key" { + content = tls_private_key.ed25519-example.private_key_pem + filename = "deployer-key.pem" +} \ No newline at end of file diff --git a/infra/local-values.tf b/infra/local-values.tf new file mode 100644 index 0000000..888ab66 --- /dev/null +++ b/infra/local-values.tf @@ -0,0 +1,10 @@ +locals { + owners = var.business_division + environment = var. environment + + name ="${var.business_division}-${var.environment}" + common_tags = { + owners = local.owners + environment = local.environment + } +} \ No newline at end of file diff --git a/infra/main.tf b/infra/main.tf new file mode 100644 index 0000000..e237cfc --- /dev/null +++ b/infra/main.tf @@ -0,0 +1,39 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = ">=3.29" + } + } +} + +provider "aws" { + profile ="default" + region = var.aws_region +} + +/* +resource "null_resource" "copy_key_pair" { + depends_on = [ module.bastion-instance, module.ec2_instance ] + connection { + type = "ssh" + host = module.bastion-instance.public_ip + user = "ec2-user" + password = "" + private_key = file("deployerkey") + } + provisioner "file" { + source = "deployerkey" + destination = "/tmp/deployerkey" + } + provisioner "remote-exec" { + inline = [ + "sudo chmod 400 /deployerkey" + ] + } + provisioner "local-exec" { + command = echo "echo VPC created on 'date' and VPC ID : ${module.vpc.voc_id} >> creation-time-vpc.txt + working_dir = "local-exec-output-files" + } +}*/ + diff --git a/infra/output.tf b/infra/output.tf new file mode 100644 index 0000000..845574c --- /dev/null +++ b/infra/output.tf @@ -0,0 +1,23 @@ +output "instance_ip_addr" { + description = "ip address of the instance" + value = aws_instance.web.public_ip +} + +output "aws_vpc" { + value = module.vpc.vpc_id +} + +output "arn" { + value = aws_instance.web.arn +} + +output "igw_arn" { + value = module.vpc.igw_arn +} + +output "azs" { + value = module.vpc.azs +} +output "name" { + value = module.vpc.name +} \ No newline at end of file diff --git a/infra/sg.tf b/infra/sg.tf new file mode 100644 index 0000000..2ee739d --- /dev/null +++ b/infra/sg.tf @@ -0,0 +1,33 @@ + +locals { + ports = [80, 22, 443] +} +resource "aws_security_group" "bastion-instance" { + name = "webserver" + vpc_id = module.vpc.vpc_id + description = "Inbound Rules for WebServer" + + dynamic "ingress" { + iterator = port + for_each = local.ports + content { + description = "description ${port.key}" + from_port = port.value + to_port = port.value + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + } + dynamic "egress" { + iterator = port + for_each = local.ports + content { + description = "description ${port.key}" + from_port = port.value + to_port = port.value + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + } + +} \ No newline at end of file diff --git a/infra/var.tf b/infra/var.tf new file mode 100644 index 0000000..bd747b3 --- /dev/null +++ b/infra/var.tf @@ -0,0 +1,30 @@ +variable "aws_region" { + description = "The AWS region" + type = string + default = "us-east-1" +} + +variable "instance_type" { + description = "instance type" + default = "t2.micro" + type= string + +} +variable "vpc_availability_zones" { + description = "value" + type = list(string) + default = ["us-east-1a", "us-east-1b", "us-east-1c"] + +} + +variable "business_division"{ + type =string + default = "li-fi" + +} + +variable "environment"{ + type= string + default = "dev" + +} \ No newline at end of file diff --git a/infra/vpc.tf b/infra/vpc.tf new file mode 100644 index 0000000..303b03f --- /dev/null +++ b/infra/vpc.tf @@ -0,0 +1,50 @@ +data "aws_availability_zones" "available"{ + state = "available" +} + +module "vpc" { + source = "terraform-aws-modules/vpc/aws" + + name = "${local.name}-vpc" + cidr = "10.0.0.0/16" + + azs = ["us-east-1a", "us-east-1b", "us-east-1c"] + private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"] + public_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"] + database_subnets = ["10.0.201.0/24", "10.0.202.0/24", "10.0.203.0/24"] + + create_database_subnet_group = true + create_database_subnet_route_table = true + enable_vpn_gateway = true + + #NAT Gateways - outbound communications + + enable_nat_gateway = true + single_nat_gateway = true + + #VPC DNS Parametrers + enable_dns_hostnames = true + enable_dns_support = true + + public_subnet_tags = { + Name = "public-subnets" + } + + private_subnet_tags = { + Name = "private-subnets" + } + + database_subnet_tags = { + Name = "database-subnets" + } + + tags = { + owner = "Ochuko" + Terraform = "true" + Environment = "dev" + } + + vpc_tags = { + Name = "vpc-dev" + } +} diff --git a/k8/README.md b/k8/README.md new file mode 100644 index 0000000..cf4d2ab --- /dev/null +++ b/k8/README.md @@ -0,0 +1,50 @@ +About: +The application was deployed using helm where I essentially built all the k8s resources from the ground up + +Steps to reproduce: +1. Build the docker image and push it to ECR(already created using iac): + + Retrieve an authentication token and authenticate your Docker client to your registry. Use the AWS CLI: + +aws ecr get-login-password --region | docker login --username AWS --password-stdin .dkr.ecr..amazonaws.com + +Build your Docker image using the following command. + +docker build -t . + +After the build completes, tag your image so you can push the image to this repository: + +docker tag : .dkr.ecr..amazonaws.com/: + +Run the following command to push this image to your newly created AWS repository: + +docker push .dkr.ecr..amazonaws.com/: + +NB: I added health check to each of the api and then built/pushed a new docker image to the ECR + +2. create a k8 bird namespace using the manifest file or using the command : + kubectl create ns + +3. create a registry secret in the namespace using the command + kubectl create secret docker-registry regcred \ + --docker-server=.dkr.ecr..amazonaws.com \ + --docker-username=AWS \ + --docker-password=$(aws ecr get-login-password) \ + --namespace= + + ensure that the 2 resources (namespace and docker registry secret) have already been created before deploying the helm chart + +4. install the application : + helm install -n + + Note- k8s resources deployed using this helm chart include - deployment, service, hpa + To test if the helm chart YAML syntax is corrct, we can render the helm chart locally using: + helm template + +5. Health checks are done on each of the api and liveness probe added to each of the containers in order to monitor the health + +The goal essentially is to build a CICD pipeline that ensues the build and deploy runs automatically rather than do it manually as it is(and it works). My first approach would be to integrate a github action and define the jobs/steps. Already began the process of integrating that but I am almost out of time.Beyond this task, I will ensure that is integrated and demonstrate that it works when we reconvene (hopefully). + +in order to test that the api works use + command +and then enter localhost:4201 into the browser \ No newline at end of file diff --git a/k8/bird-release/Chart.yaml b/k8/bird-release/Chart.yaml new file mode 100644 index 0000000..b310fc2 --- /dev/null +++ b/k8/bird-release/Chart.yaml @@ -0,0 +1,5 @@ +apiVersion: v2 +name: bird-release +description: A Helm chart for bird deployment +version: 0.1.0 +appVersion: "1.0" diff --git a/k8/bird-release/templates/deployment.yaml b/k8/bird-release/templates/deployment.yaml new file mode 100644 index 0000000..013a2df --- /dev/null +++ b/k8/bird-release/templates/deployment.yaml @@ -0,0 +1,74 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: bird-deployment + namespace: bird + labels: + app: bird +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + app: bird + template: + metadata: + labels: + app: bird + spec: + volumes: + - name: bird-release-pv + persistentVolumeClaim: + claimName: bird-release-pvc + containers: + - name: bird-container + image: "{{ .Values.image.repository }}:{{ .Values.image.birdTag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + volumeMounts: + - mountPath: "/var/www/html" + name: bird-release-pv + ports: + - name: bird-web + containerPort: {{ .Values.ports.birdContainerPort }} + livenessProbe: + httpGet: + path: /healthz + port: 4201 + scheme: HTTP + periodSeconds: 5 + initialDelaySeconds: 15 + failureThreshold: 10 + resources: + limits: + cpu: {{ .Values.resources.limits.cpu }} + memory: {{ .Values.resources.limits.memory }} + requests: + cpu: {{ .Values.resources.requests.cpu }} + memory: {{ .Values.resources.requests.memory }} + - name: birdimage-container + image: "{{ .Values.image.repository }}:{{ .Values.image.birdImageTag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + volumeMounts: + - mountPath: "/var/www/html" + name: bird-release-pv + ports: + - name: birdimage-web + containerPort: {{ .Values.ports.birdImageContainerPort }} + livenessProbe: + httpGet: + path: /healthz + port: 4200 + scheme: HTTP + periodSeconds: 5 + initialDelaySeconds: 15 + failureThreshold: 10 + resources: + limits: + cpu: {{ .Values.resources.limits.cpu }} + memory: {{ .Values.resources.limits.memory }} + requests: + cpu: {{ .Values.resources.requests.cpu }} + memory: {{ .Values.resources.requests.memory }} + imagePullSecrets: + {{- range .Values.imagePullSecrets }} + - name: {{ .name }} + {{- end }} diff --git a/k8/bird-release/templates/helper.tpl b/k8/bird-release/templates/helper.tpl new file mode 100644 index 0000000..2516677 --- /dev/null +++ b/k8/bird-release/templates/helper.tpl @@ -0,0 +1,6 @@ +{{/* +Create a default chart label. +*/}} +{{- define "bird-chart.labels" -}} +app: bird +{{- end }} diff --git a/k8/bird-release/templates/hpa.yaml b/k8/bird-release/templates/hpa.yaml new file mode 100644 index 0000000..86d877b --- /dev/null +++ b/k8/bird-release/templates/hpa.yaml @@ -0,0 +1,38 @@ + +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: bird-webui-hpa + namespace: bird +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: bird-release-deployment + minReplicas: 1 + maxReplicas: 10 + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 50 + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: 70 +status: + observedGeneration: 1 + #lastScaleTime: 05:00 + currentReplicas: 1 + desiredReplicas: 1 + currentMetrics: + - type: Resource + resource: + name: memory + current: + averageUtilization: 70 + averageValue: 10 \ No newline at end of file diff --git a/k8/bird-release/templates/pv.yaml b/k8/bird-release/templates/pv.yaml new file mode 100644 index 0000000..b819cb0 --- /dev/null +++ b/k8/bird-release/templates/pv.yaml @@ -0,0 +1,18 @@ +--- +apiVersion: v1 +kind: PersistentVolume +metadata: + name: bird-release-pv + namespace: bird + labels: + type: local +spec: + storageClassName: manual + capacity: + storage: 10Gi + accessModes: + - ReadWriteOnce + hostPath: + path: "/mnt/data" + + diff --git a/k8/bird-release/templates/pvc.yaml b/k8/bird-release/templates/pvc.yaml new file mode 100644 index 0000000..5af9d0a --- /dev/null +++ b/k8/bird-release/templates/pvc.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: bird-release-pvc + namespace: bird +spec: + storageClassName: manual + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 3Gi \ No newline at end of file diff --git a/k8/bird-release/templates/svc.yaml b/k8/bird-release/templates/svc.yaml new file mode 100644 index 0000000..b64af71 --- /dev/null +++ b/k8/bird-release/templates/svc.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Service +metadata: + name: bird-service + namespace: bird +spec: + selector: + app: bird + ports: + - name: bird-service-port + protocol: TCP + port: 4201 + targetPort: bird-web \ No newline at end of file diff --git a/k8/bird-release/values.yaml b/k8/bird-release/values.yaml new file mode 100644 index 0000000..a2e8e56 --- /dev/null +++ b/k8/bird-release/values.yaml @@ -0,0 +1,25 @@ +namespace: bird +replicaCount: 1 + +dockerSecret: "" + +image: + repository: 891376975226.dkr.ecr.us-east-1.amazonaws.com/private-example + birdTag: bird2.0 + birdImageTag: birdimage1.0 + pullPolicy: Always + +resources: + limits: + cpu: 500m + memory: 512Mi + requests: + cpu: 200m + memory: 256Mi + +imagePullSecrets: + - name: regcred + +ports: + birdContainerPort: 4201 + birdImageContainerPort: 4200 From 25ae95422aeae49b1fee17cb9ed5e0ff6a50cc77 Mon Sep 17 00:00:00 2001 From: "ochuko.ebireri" Date: Wed, 25 Sep 2024 10:52:46 -0600 Subject: [PATCH 03/10] new config --- .github/workflows/terraform.tfstate | 9 --- infra/ami.tf | 8 +-- infra/ec2.tf | 85 ++++++++++++++--------- infra/key-pair.tf | 6 +- infra/local-values.tf | 14 ++-- infra/main.tf | 29 +------- infra/output.tf | 10 +-- infra/sg.tf | 8 +-- infra/{apache_install.sh => user_data.sh} | 0 infra/var.tf | 32 ++++----- infra/vpc.tf | 36 +++++----- 11 files changed, 112 insertions(+), 125 deletions(-) delete mode 100644 .github/workflows/terraform.tfstate rename infra/{apache_install.sh => user_data.sh} (100%) diff --git a/.github/workflows/terraform.tfstate b/.github/workflows/terraform.tfstate deleted file mode 100644 index 3b00260..0000000 --- a/.github/workflows/terraform.tfstate +++ /dev/null @@ -1,9 +0,0 @@ -{ - "version": 4, - "terraform_version": "1.8.4", - "serial": 1, - "lineage": "baa12152-04e6-5772-e8cd-545f9a18b9ed", - "outputs": {}, - "resources": [], - "check_results": null -} diff --git a/infra/ami.tf b/infra/ami.tf index 915a157..645f740 100644 --- a/infra/ami.tf +++ b/infra/ami.tf @@ -1,7 +1,7 @@ #data source for the AMI data "aws_ami" "ubuntu" { - most_recent = true - owners = ["amazon"] + most_recent = true + owners = ["amazon"] filter { name = "name" @@ -19,7 +19,7 @@ data "aws_ami" "ubuntu" { } filter { - name = "architecture" - values = ["x86_64"] + name = "architecture" + values = ["x86_64"] } } \ No newline at end of file diff --git a/infra/ec2.tf b/infra/ec2.tf index df0c8ef..3228fbe 100644 --- a/infra/ec2.tf +++ b/infra/ec2.tf @@ -1,37 +1,58 @@ -resource "aws_instance" "web" { - ami = "ami-0e86e20dae9224db8" - key_name = "deployer-key" - subnet_id = element(module.vpc.public_subnets, 0) - user_data = "${file("apache_install.sh")}" - vpc_security_group_ids = [aws_security_group.bastion-instance.id] - associate_public_ip_address = true - instance_type = "t2.micro" - - provisioner "file" { - source = ".././k8" - destination = "/home/ec2-user/remote-directory" - - connection { - type = "ssh" - user = "ec2-user" - host = self.public_ip - private_key = tls_private_key.ed25519-example.private_key_pem - } - } +# resource "aws_instance" "web" { +# ami = "ami-0e86e20dae9224db8" +# key_name = "deployer-key" +# subnet_id = element(module.vpc.public_subnets, 0) +# user_data = "${file("apache_install.sh")}" +# vpc_security_group_ids = [aws_security_group.bastion-instance.id] +# associate_public_ip_address = true +# instance_type = "t2.micro" + +# provisioner "file" { +# source = ".././k8" +# destination = "/home/ec2-user/remote-directory" + +# connection { +# type = "ssh" +# user = "ec2-user" +# host = self.public_ip +# private_key = tls_private_key.ed25519-example.private_key_pem +# } +# } + +# provisioner "remote-exec" { +# inline = [ +# "echo 'Files copied!'" +# ] + +# connection { +# type = "ssh" +# user = "ec2-user" +# host = self.public_ip +# private_key = tls_private_key.ed25519-example.private_key_pem +# } +# } +# tags = { +# Name = local.name +# } +# } + + +module "ec2_instance" { + source = "terraform-aws-modules/ec2-instance/aws" + + name = "test-instance" + + instance_type = "t2.micro" + ami = "ami-0e86e20dae9224db8" + key_name = "deployer-key" + availability_zone = var.vpc_availability_zones[0] + user_data = file("user_data.sh") + associate_public_ip_address = true + monitoring = true + vpc_security_group_ids = [aws_security_group.bastion-instance.id] + subnet_id = module.vpc.public_subnets[0] - provisioner "remote-exec" { - inline = [ - "echo 'Files copied!'" - ] - - connection { - type = "ssh" - user = "ec2-user" - host = self.public_ip - private_key = tls_private_key.ed25519-example.private_key_pem - } - } tags = { Name = local.name } diff --git a/infra/key-pair.tf b/infra/key-pair.tf index 76909f9..2cac14d 100644 --- a/infra/key-pair.tf +++ b/infra/key-pair.tf @@ -5,9 +5,9 @@ resource "aws_key_pair" "deployer" { resource "tls_private_key" "ed25519-example" { algorithm = "RSA" - rsa_bits =4096 + rsa_bits = 4096 } resource "local_file" "TF-key" { - content = tls_private_key.ed25519-example.private_key_pem - filename = "deployer-key.pem" + content = tls_private_key.ed25519-example.private_key_pem + filename = "deployer-key.pem" } \ No newline at end of file diff --git a/infra/local-values.tf b/infra/local-values.tf index 888ab66..0b87860 100644 --- a/infra/local-values.tf +++ b/infra/local-values.tf @@ -1,10 +1,10 @@ locals { - owners = var.business_division - environment = var. environment + owners = var.business_division + environment = var.environment - name ="${var.business_division}-${var.environment}" - common_tags = { - owners = local.owners - environment = local.environment - } + name = "${var.business_division}-${var.environment}" + common_tags = { + owners = local.owners + environment = local.environment + } } \ No newline at end of file diff --git a/infra/main.tf b/infra/main.tf index e237cfc..79f5f81 100644 --- a/infra/main.tf +++ b/infra/main.tf @@ -1,39 +1,14 @@ terraform { required_providers { aws = { - source = "hashicorp/aws" + source = "hashicorp/aws" version = ">=3.29" } } } provider "aws" { - profile ="default" + profile = "default" region = var.aws_region } -/* -resource "null_resource" "copy_key_pair" { - depends_on = [ module.bastion-instance, module.ec2_instance ] - connection { - type = "ssh" - host = module.bastion-instance.public_ip - user = "ec2-user" - password = "" - private_key = file("deployerkey") - } - provisioner "file" { - source = "deployerkey" - destination = "/tmp/deployerkey" - } - provisioner "remote-exec" { - inline = [ - "sudo chmod 400 /deployerkey" - ] - } - provisioner "local-exec" { - command = echo "echo VPC created on 'date' and VPC ID : ${module.vpc.voc_id} >> creation-time-vpc.txt - working_dir = "local-exec-output-files" - } -}*/ - diff --git a/infra/output.tf b/infra/output.tf index 845574c..7af6a6f 100644 --- a/infra/output.tf +++ b/infra/output.tf @@ -1,22 +1,22 @@ output "instance_ip_addr" { description = "ip address of the instance" - value = aws_instance.web.public_ip + value = module.ec2_instance.public_ip } output "aws_vpc" { - value = module.vpc.vpc_id + value = module.vpc.vpc_id } output "arn" { - value = aws_instance.web.arn + value = module.ec2_instance.arn } output "igw_arn" { - value = module.vpc.igw_arn + value = module.vpc.igw_arn } output "azs" { - value = module.vpc.azs + value = module.vpc.azs } output "name" { value = module.vpc.name diff --git a/infra/sg.tf b/infra/sg.tf index 2ee739d..b2f4e8a 100644 --- a/infra/sg.tf +++ b/infra/sg.tf @@ -17,8 +17,8 @@ resource "aws_security_group" "bastion-instance" { protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } - } - dynamic "egress" { + } + dynamic "egress" { iterator = port for_each = local.ports content { @@ -28,6 +28,6 @@ resource "aws_security_group" "bastion-instance" { protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } - } - + } + } \ No newline at end of file diff --git a/infra/apache_install.sh b/infra/user_data.sh similarity index 100% rename from infra/apache_install.sh rename to infra/user_data.sh diff --git a/infra/var.tf b/infra/var.tf index bd747b3..80e52fa 100644 --- a/infra/var.tf +++ b/infra/var.tf @@ -1,30 +1,30 @@ variable "aws_region" { - description = "The AWS region" - type = string - default = "us-east-1" + description = "The AWS region" + type = string + default = "us-east-1" } variable "instance_type" { - description = "instance type" - default = "t2.micro" - type= string - + description = "instance type" + default = "t2.micro" + type = string + } variable "vpc_availability_zones" { - description = "value" - type = list(string) - default = ["us-east-1a", "us-east-1b", "us-east-1c"] + description = "value" + type = list(string) + default = ["us-east-1a", "us-east-1b", "us-east-1c"] } -variable "business_division"{ - type =string - default = "li-fi" +variable "business_division" { + type = string + default = "li-fi" } -variable "environment"{ - type= string - default = "dev" +variable "environment" { + type = string + default = "dev" } \ No newline at end of file diff --git a/infra/vpc.tf b/infra/vpc.tf index 303b03f..6d203c5 100644 --- a/infra/vpc.tf +++ b/infra/vpc.tf @@ -1,5 +1,5 @@ -data "aws_availability_zones" "available"{ - state = "available" +data "aws_availability_zones" "available" { + state = "available" } module "vpc" { @@ -8,30 +8,30 @@ module "vpc" { name = "${local.name}-vpc" cidr = "10.0.0.0/16" - azs = ["us-east-1a", "us-east-1b", "us-east-1c"] - private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"] - public_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"] + azs = ["us-east-1a", "us-east-1b", "us-east-1c"] + private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"] + public_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"] database_subnets = ["10.0.201.0/24", "10.0.202.0/24", "10.0.203.0/24"] - - create_database_subnet_group = true - create_database_subnet_route_table = true - enable_vpn_gateway = true - + + create_database_subnet_group = true + create_database_subnet_route_table = true + enable_vpn_gateway = true + #NAT Gateways - outbound communications enable_nat_gateway = true - single_nat_gateway = true + single_nat_gateway = true #VPC DNS Parametrers - enable_dns_hostnames = true - enable_dns_support = true + enable_dns_hostnames = true + enable_dns_support = true - public_subnet_tags = { + public_subnet_tags = { Name = "public-subnets" } - private_subnet_tags = { - Name = "private-subnets" + private_subnet_tags = { + Name = "private-subnets" } database_subnet_tags = { @@ -39,8 +39,8 @@ module "vpc" { } tags = { - owner = "Ochuko" - Terraform = "true" + owner = "Ochuko" + Terraform = "true" Environment = "dev" } From 8be343e88c929af1b03b3ac878e4ab1563b8058b Mon Sep 17 00:00:00 2001 From: "ochuko.ebireri" Date: Wed, 25 Sep 2024 10:55:30 -0600 Subject: [PATCH 04/10] ec2 modification --- infra/ec2.tf | 39 --------------------------------------- 1 file changed, 39 deletions(-) diff --git a/infra/ec2.tf b/infra/ec2.tf index 3228fbe..7355c86 100644 --- a/infra/ec2.tf +++ b/infra/ec2.tf @@ -1,43 +1,4 @@ -# resource "aws_instance" "web" { -# ami = "ami-0e86e20dae9224db8" -# key_name = "deployer-key" -# subnet_id = element(module.vpc.public_subnets, 0) -# user_data = "${file("apache_install.sh")}" -# vpc_security_group_ids = [aws_security_group.bastion-instance.id] -# associate_public_ip_address = true -# instance_type = "t2.micro" - -# provisioner "file" { -# source = ".././k8" -# destination = "/home/ec2-user/remote-directory" - -# connection { -# type = "ssh" -# user = "ec2-user" -# host = self.public_ip -# private_key = tls_private_key.ed25519-example.private_key_pem -# } -# } - -# provisioner "remote-exec" { -# inline = [ -# "echo 'Files copied!'" -# ] - -# connection { -# type = "ssh" -# user = "ec2-user" -# host = self.public_ip -# private_key = tls_private_key.ed25519-example.private_key_pem -# } -# } -# tags = { -# Name = local.name -# } -# } - - module "ec2_instance" { source = "terraform-aws-modules/ec2-instance/aws" From d75715015b0bec6d71c74c7d91eef325d048090d Mon Sep 17 00:00:00 2001 From: "ochuko.ebireri" Date: Wed, 25 Sep 2024 10:59:28 -0600 Subject: [PATCH 05/10] removed spaces in var file --- infra/var.tf | 7 ------- 1 file changed, 7 deletions(-) diff --git a/infra/var.tf b/infra/var.tf index 80e52fa..d0b4daa 100644 --- a/infra/var.tf +++ b/infra/var.tf @@ -3,28 +3,21 @@ variable "aws_region" { type = string default = "us-east-1" } - variable "instance_type" { description = "instance type" default = "t2.micro" type = string - } variable "vpc_availability_zones" { description = "value" type = list(string) default = ["us-east-1a", "us-east-1b", "us-east-1c"] - } - variable "business_division" { type = string default = "li-fi" - } - variable "environment" { type = string default = "dev" - } \ No newline at end of file From 943273cbad25858d11e937a8f33a634de71afa0b Mon Sep 17 00:00:00 2001 From: "ochuko.ebireri" Date: Wed, 25 Sep 2024 16:32:13 -0600 Subject: [PATCH 06/10] nekw --- .github/workflows/docker-image.yaml | 100 +++++++++++++++------------- .github/workflows/pr.yaml | 50 -------------- .github/workflows/ssh.yaml | 29 -------- 3 files changed, 52 insertions(+), 127 deletions(-) delete mode 100644 .github/workflows/pr.yaml delete mode 100644 .github/workflows/ssh.yaml diff --git a/.github/workflows/docker-image.yaml b/.github/workflows/docker-image.yaml index 89b50f0..2b5a067 100644 --- a/.github/workflows/docker-image.yaml +++ b/.github/workflows/docker-image.yaml @@ -1,48 +1,52 @@ -# name: Docker Image CI - -# on: -# push: -# branches: [ "main" ] -# pull_request: -# branches: [ "main" ] - -# jobs: - -# build-and-push: -# runs-on: ubuntu-latest - -# steps: -# - uses: actions/checkout@v4 - -# # Step 1: Log in to Amazon ECR -# - name: Configure AWS credentials -# uses: aws-actions/configure-aws-credentials@v2 -# with: -# role-to-assume: arn:aws:iam::ACCOUNT_ID:role/ROLE_NAME # Optional, for using an IAM role -# aws-region: us-east-1 -# aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} -# aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - -# - name: Login to Amazon ECR -# run: | -# aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.us-east-1.amazonaws.com - -# # Step 2: Build the Docker image -# - name: Build the Docker image -# run: | -# IMAGE_NAME=$(basename "$PWD") -# docker build . --file Dockerfile --tag $IMAGE_NAME:latest - -# # Step 3: Tag the image with ECR repository URL -# - name: Tag the Docker image -# run: | -# IMAGE_NAME=$(basename "$PWD") -# ECR_URI=${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.us-east-1.amazonaws.com/$IMAGE_NAME -# docker tag $IMAGE_NAME:latest $ECR_URI:latest - -# # Step 4: Push the Docker image to ECR -# - name: Push the Docker image to ECR -# run: | -# IMAGE_NAME=$(basename "$PWD") -# ECR_URI=${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.us-east-1.amazonaws.com/$IMAGE_NAME -# docker push $ECR_URI:latest +name: Docker Image CI + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + + build-and-push: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + # Step 1: Log in to Amazon ECR + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v2 + with: + role-to-assume: arn:aws:iam::ACCOUNT_ID:role/ROLE_NAME + aws-region: us-east-1 + + - name: Login to Amazon ECR + run: | + aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 891376975226.dkr.ecr.us-east-1.amazonaws.com + + # Step 2: Build the Docker image + - name: Build the Docker image + run: | + IMAGE_NAME=$(basename "$PWD") + docker build . --file Dockerfile --tag $IMAGE_NAME:latest + + # Step 3: Tag the image with ECR repository URL + - name: Tag the Docker image + run: | + IMAGE_NAME=$(basename "$PWD") + ECR_URI=891376975226.dkr.ecr.us-east-1.amazonaws.com/$IMAGE_NAME + docker tag $IMAGE_NAME:latest $ECR_URI:latest + + # Step 4: Push the Docker image to ECR + - name: Push the Docker image to ECR + run: | + IMAGE_NAME=$(basename "$PWD") + ECR_URI=891376975226.dkr.ecr.us-east-1.amazonaws.com/$IMAGE_NAME + docker push $ECR_URI:latest + + - name: Push the Docker image to ECR + run: | + IMAGE_NAME=$(basename "$PWD") + ECR_URI=891376975226.dkr.ecr.us-east-1.amazonaws.com/$IMAGE_NAME + docker push $ECR_URI:latest \ No newline at end of file diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml deleted file mode 100644 index bd57f86..0000000 --- a/.github/workflows/pr.yaml +++ /dev/null @@ -1,50 +0,0 @@ -# name: CI Pipeline - -# on: -# pull_request: -# types: [opened, synchronize, reopened] - -# jobs: -# build: -# name: Build and Test -# runs-on: ubuntu-latest - -# steps: -# # Checkout the repository code -# - name: Checkout code -# uses: actions/checkout@v3 - -# # Set up the programming language environment (example: Node.js) -# - name: Set up Node.js -# uses: actions/setup-node@v3 -# with: -# node-version: '14' - -# # Install dependencies -# - name: Install dependencies -# run: npm install - -# # Run tests -# - name: Run tests -# run: npm test - -# # Post success or failure message to the pull request -# notify: -# name: Notify GitHub PR -# runs-on: ubuntu-latest -# needs: build -# steps: -# - name: Post status to PR -# uses: actions/github-script@v6 -# with: -# script: | -# const status = "${{ job.status }}"; -# const message = status === 'success' -# ? ':white_check_mark: Build and tests passed!' -# : ':x: Build or tests failed.'; -# github.rest.issues.createComment({ -# issue_number: context.payload.pull_request.number, -# owner: context.repo.owner, -# repo: context.repo.repo, -# body: message -# }); diff --git a/.github/workflows/ssh.yaml b/.github/workflows/ssh.yaml deleted file mode 100644 index d9b1070..0000000 --- a/.github/workflows/ssh.yaml +++ /dev/null @@ -1,29 +0,0 @@ -# name: Node CI - -# on: [push] - -# jobs: -# build: - -# runs-on: ubuntu-latest - -# steps: -# - uses: actions/checkout@v3 -# - name: Install Node.js -# uses: actions/setup-node@v3 -# with: -# node-version: '16.x' -# - name: Install npm dependencies -# run: npm install -# - name: Run build task -# run: npm run build --if-present -# - name: Deploy to Server -# uses: easingthemes/ssh-deploy@main -# with: -# SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} -# ARGS: "-rlgoDzvc -i --delete" -# SOURCE: "dist/" -# REMOTE_HOST: ${{ secrets.REMOTE_HOST }} -# REMOTE_USER: ${{ secrets.REMOTE_USER }} -# TARGET: ${{ secrets.REMOTE_TARGET }} -# EXCLUDE: "/dist/, /node_modules/" \ No newline at end of file From b79c288d4717c7b12683767c06bb6d7f0984d3ef Mon Sep 17 00:00:00 2001 From: "ochuko.ebireri" Date: Wed, 25 Sep 2024 16:37:22 -0600 Subject: [PATCH 07/10] new three --- .github/workflows/docker-image.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-image.yaml b/.github/workflows/docker-image.yaml index 2b5a067..1297581 100644 --- a/.github/workflows/docker-image.yaml +++ b/.github/workflows/docker-image.yaml @@ -18,7 +18,7 @@ jobs: - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v2 with: - role-to-assume: arn:aws:iam::ACCOUNT_ID:role/ROLE_NAME + role-to-assume: arn:aws:iam::891376975226:role/OIDCRolefors3 aws-region: us-east-1 - name: Login to Amazon ECR From a2d8b289db552a5d3be6893c40691e025780bf10 Mon Sep 17 00:00:00 2001 From: "ochuko.ebireri" Date: Wed, 25 Sep 2024 16:44:39 -0600 Subject: [PATCH 08/10] newfour --- .github/workflows/docker-image.yaml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker-image.yaml b/.github/workflows/docker-image.yaml index 2b5a067..be2cdf2 100644 --- a/.github/workflows/docker-image.yaml +++ b/.github/workflows/docker-image.yaml @@ -10,7 +10,10 @@ jobs: build-and-push: runs-on: ubuntu-latest - + permissions: + id-token: write + contents: read + steps: - uses: actions/checkout@v4 @@ -18,7 +21,7 @@ jobs: - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v2 with: - role-to-assume: arn:aws:iam::ACCOUNT_ID:role/ROLE_NAME + role-to-assume: arn:aws:iam::891376975226:role/OIDCRolefors3 aws-region: us-east-1 - name: Login to Amazon ECR From 21b1d340e24a4feb67ea51c98e23ef4fe775087a Mon Sep 17 00:00:00 2001 From: "ochuko.ebireri" Date: Wed, 25 Sep 2024 19:48:35 -0600 Subject: [PATCH 09/10] shenkes --- .github/workflows/docker-image.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-image.yaml b/.github/workflows/docker-image.yaml index 2b5a067..1297581 100644 --- a/.github/workflows/docker-image.yaml +++ b/.github/workflows/docker-image.yaml @@ -18,7 +18,7 @@ jobs: - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v2 with: - role-to-assume: arn:aws:iam::ACCOUNT_ID:role/ROLE_NAME + role-to-assume: arn:aws:iam::891376975226:role/OIDCRolefors3 aws-region: us-east-1 - name: Login to Amazon ECR From ad93809c00ae560661be8ba0257fd66e85851472 Mon Sep 17 00:00:00 2001 From: "ochuko.ebireri" Date: Wed, 25 Sep 2024 20:19:45 -0600 Subject: [PATCH 10/10] shenkes --- .github/workflows/docker-image.yaml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/docker-image.yaml b/.github/workflows/docker-image.yaml index be2cdf2..d591e9c 100644 --- a/.github/workflows/docker-image.yaml +++ b/.github/workflows/docker-image.yaml @@ -47,9 +47,3 @@ jobs: IMAGE_NAME=$(basename "$PWD") ECR_URI=891376975226.dkr.ecr.us-east-1.amazonaws.com/$IMAGE_NAME docker push $ECR_URI:latest - - - name: Push the Docker image to ECR - run: | - IMAGE_NAME=$(basename "$PWD") - ECR_URI=891376975226.dkr.ecr.us-east-1.amazonaws.com/$IMAGE_NAME - docker push $ECR_URI:latest \ No newline at end of file