Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
fd7bc75
adding delivery date
nasiima Jan 4, 2024
c0ab4a4
Merge pull request #2 from nasiima/feature/add-delivery-date
nasiima Jan 10, 2024
cf48ca2
Revert 'Delete azure-pipelines.yml'
nasiima Jan 10, 2024
98b6297
Merge pull request #3 from nasiima/revert-delivery-date
nasiima Jan 10, 2024
a962ae4
Update README.md
nasiima Jan 10, 2024
f1c5c0e
adding dockerfile
nasiima Jan 10, 2024
cd00770
Merge pull request #4 from nasiima/Dockerfile-creation
nasiima Jan 10, 2024
6feb3e4
Merge pull request #5 from nasiima/main
nasiima Jan 11, 2024
263b55e
revert delivery date
nasiima Jan 11, 2024
e7c1dd0
Merge pull request #6 from nasiima/revert-delivery-date
nasiima Jan 11, 2024
05a1e7a
docker file cleanup, compatible with m1, fixing pyodbc issues
nasiima Jan 14, 2024
a12a2be
documentation update
nasiima Jan 14, 2024
45681b3
Merge pull request #7 from nasiima/Dockerfile-creation
nasiima Jan 14, 2024
9079380
pushed to dockerhub
nasiima Jan 14, 2024
368ec11
Merge pull request #8 from nasiima/Dockerfile-creation
nasiima Jan 14, 2024
1093770
adding file
nasiima Feb 8, 2024
bb4a947
files and folders
nasiima Feb 12, 2024
8e6ea94
terraform scripting
nasiima Feb 12, 2024
1d63514
complete terrafrom apply successfully
nasiima Feb 12, 2024
a9828c2
Merge pull request #9 from nasiima/terraform
nasiima Feb 12, 2024
34572fa
adding yaml file and correcting docker issue
nasiima Feb 12, 2024
b108f52
complete kubernetes deployment
nasiima Feb 12, 2024
2ae7d2f
Merge pull request #10 from nasiima/kubernetes
nasiima Feb 12, 2024
c011b3d
Set up CI with Azure Pipelines
nasiima Feb 13, 2024
8d523e5
Set up CI with Azure Pipelines
nasiima Feb 13, 2024
7199daa
Set up CI with Azure Pipelines
nasiima Feb 13, 2024
715b820
Set up CI with Azure Pipelines
nasiima Feb 13, 2024
ebd7998
Set up CI with Azure Pipelines
nasiima Feb 13, 2024
8055885
Update azure-pipelines.yml for Azure Pipelines
nasiima Feb 13, 2024
a03d0ca
Update azure-pipelines.yml
nasiima Feb 16, 2024
695b0db
Update azure-pipelines.yml
nasiima Feb 16, 2024
60d42d5
Update azure-pipelines.yml
nasiima Feb 16, 2024
ac90bf7
Update azure-pipelines.yml
nasiima Feb 16, 2024
731daa7
Update azure-pipelines.yml
nasiima Feb 16, 2024
1dd855d
Update azure-pipelines.yml
nasiima Feb 16, 2024
6de610e
Update azure-pipelines.yml
nasiima Feb 16, 2024
4169e6a
fixing python version
nasiima Feb 16, 2024
6a0b4ad
tweak
nasiima Feb 16, 2024
94b4649
Merge pull request #11 from nasiima/kubernetes
nasiima Feb 16, 2024
e3c4fdd
modify yml
nasiima Feb 16, 2024
eb7e4d8
Merge pull request #12 from nasiima/kubernetes
nasiima Feb 16, 2024
34ca20f
including venv for build
nasiima Feb 16, 2024
8155886
Merge pull request #13 from nasiima/kubernetes
nasiima Feb 16, 2024
91049a0
fixing for pipeline
nasiima Feb 16, 2024
c9f036d
Merge pull request #14 from nasiima/kubernetes
nasiima Feb 16, 2024
ab9fa21
tweak
nasiima Feb 16, 2024
f9f35a1
Merge pull request #15 from nasiima/kubernetes
nasiima Feb 16, 2024
d1fa2df
remove venv
nasiima Feb 19, 2024
fe6d1b0
aks secret key integration
nasiima Feb 21, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Virtual environment
venv/

# Python compiled files
*.pyc
__pycache__/

# Flask specific files
flask/

*.terraform/
*terraform.tfstate
38 changes: 38 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# TODO: Step 1 - Use an official Python runtime as a parent image.
FROM --platform=linux/amd64 public.ecr.aws/docker/library/python:3.9.10-slim-buster

# TODO: Step 2 - Set the working directory in the container
# Set it to /app, a commonly used directory for web applications.
WORKDIR /app

# TODO: Step 3 - Copy the application files in the container
# Copy the contents of your local directory into the container's /app directory.
COPY . /app

# Install system dependencies and ODBC driver
RUN apt-get update && apt-get install -y \
unixodbc unixodbc-dev odbcinst odbcinst1debian2 libpq-dev gcc && \
apt-get install -y gnupg && \
apt-get install -y wget && \
wget -qO- https://packages.microsoft.com/keys/microsoft.asc | apt-key add - && \
wget -qO- https://packages.microsoft.com/config/debian/10/prod.list > /etc/apt/sources.list.d/mssql-release.list && \
apt-get update && \
ACCEPT_EULA=Y apt-get install -y msodbcsql18 && \
apt-get purge -y --auto-remove wget && \
apt-get clean

# Install pip and setuptools
RUN pip install --upgrade pip setuptools


# TODO: Step 4 - Install Python packages specified in requirements.txt
# Assuming your requirements.txt is in the same directory as your Dockerfile.
RUN pip install --trusted-host pypi.python.org -r requirements.txt

# TODO: Step 5 - Expose port 5000
EXPOSE 5000

# TODO: Step 6 - Define Startup Command
# Specify the command that should be executed when the container launches.
# This command should run the file that starts the Flask application.
CMD ["python", "app.py"]
47 changes: 47 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ Welcome to the Web App DevOps Project repo! This application allows you to effic

- **Data Validation:** Ensure data accuracy and completeness with required fields, date restrictions, and card number validation.

- **Delivery Date Column:** An additional field is available to capture the Delivery Date of an order. While the feature is currently inactive, it can be activated by merging the changes from the "feature/add-delivery-date" branch into the main branch.

## Getting Started

### Prerequisites
Expand Down Expand Up @@ -53,6 +55,51 @@ To run the application, you simply need to run the `app.py` script in this repos

- **Database:** The application employs an Azure SQL Database as its database system to store order-related data.

### Docker containerization

**1. Dockerfile Creation:**
We utilized an official Python runtime as our parent image, specifically public.ecr.aws/docker/library/python:3.9.10-slim-buster. The working directory in the container was set to /app, and the application files were copied into the container's /app directory.
**2. System Dependencies and ODBC Driver Installation:**
System dependencies and the ODBC driver were installed to support the application. The installation process involved updating the package manager, installing necessary dependencies, and configuring the Microsoft ODBC driver.
**3. Pip and Python Package Installation:**
We upgraded pip and setuptools before installing Python packages specified in the requirements.txt file.
**4. Port Exposure and Startup Command:**
The Dockerfile exposed port 5000, which is the port the Flask application runs on. The startup command was set to launch the Flask application.


**Usage Instructions:**

**Docker Image Name:** nmohamed436/azure-end-to-end-devops
Tags: Latest
Ensure Docker is installed on your system.
Build the image using the provided Dockerfile. docker build -t nmohamed436/azure-end-to-end-devops:latest .
Run the container, exposing port 5000.
Access the application on http://localhost:5000.

**Deployment and Service Manifests:**

Created Deployment and Service manifests in the application-manifest.yaml file.
Deployment defines the desired state for the application pods, including image, ports, and replicas.
Service defines a ClusterIP service for internal communication within the AKS cluster.
**Deployment Strategy:**

Chose a RollingUpdate deployment strategy for its gradual and controlled rollout.
Configured a maximum surge and maximum unavailable percentage to manage the deployment process.
This strategy ensures minimal downtime and allows for easy rollback if issues arise during deployment.
**Testing and Validation:**

Conducted tests to ensure pods are created, containers are running, and the service is accessible.
Validated the application's functionality within the AKS cluster, focusing on critical features.
Monitored pod logs and used kubectl commands to troubleshoot and verify the health of pods.

**Distribution Plan:**

For internal users, no port forwarding is needed; users can access the service within the AKS cluster.
External users will require secure access; consider using Ingress controllers for HTTPS traffic.
Utilize RBAC and Network Policies to control access and enhance security.
Deploy the application in a namespace and control access through proper RBAC configurations.


## Contributors

- [Maya Iuga]([https://github.com/yourusername](https://github.com/maya-a-iuga))
Expand Down
22 changes: 22 additions & 0 deletions aks-terraform/.terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 26 additions & 0 deletions aks-terraform/aks-cluster-module/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
resource "azurerm_kubernetes_cluster" "aks_cluster" {
name = var.aks_cluster_name
location = var.cluster_location
resource_group_name = var.resource_group_name
dns_prefix = var.dns_prefix

default_node_pool {
name = "default"
node_count = 1
vm_size = "Standard_DS2_v2"
}

service_principal {
client_id = var.service_principal_client_id
client_secret = var.service_principal_secret
}

network_profile {
network_plugin = "azure"
network_policy = "calico"
}
tags = {
Terraform = "true"
Environment = "dev"
}
}
14 changes: 14 additions & 0 deletions aks-terraform/aks-cluster-module/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
output "aks_cluster_name" {
value = azurerm_kubernetes_cluster.aks_cluster.name
description = "Name of the provisioned AKS cluster"
}

output "aks_cluster_id" {
value = azurerm_kubernetes_cluster.aks_cluster.id
description = "ID of the provisioned AKS cluster"
}

output "aks_kubeconfig" {
value = azurerm_kubernetes_cluster.aks_cluster.kube_config_raw
description = "The Kubernetes configuration file for managing the AKS cluster with kubectl."
}
50 changes: 50 additions & 0 deletions aks-terraform/aks-cluster-module/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
variable "aks_cluster_name" {
type = string
description = "Name of the AKS cluster"
}

variable "cluster_location" {
type = string
description = "Azure region where the AKS cluster will be deployed"
}

variable "dns_prefix" {
type = string
description = "DNS prefix of the cluster"
}

variable "kubernetes_version" {
type = string
description = "Kubernetes version for the AKS cluster"
}

variable "service_principal_client_id" {
type = string
description = "Client ID for the service principal associated with the cluster"
}

variable "service_principal_secret" {
type = string
description = "Client Secret for the service principal associated with the cluster"
}

# Input variables from the networking module
variable "resource_group_name" {
type = string
description = "Name of the Azure Resource Group for networking resources"
}

variable "vnet_id" {
type = string
description = "ID of the Virtual Network (VNet) created by the networking module"
}

variable "control_plane_subnet_id" {
type = string
description = "ID of the control plane subnet created by the networking module"
}

variable "worker_node_subnet_id" {
type = string
description = "ID of the worker node subnet created by the networking module"
}
43 changes: 43 additions & 0 deletions aks-terraform/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">=3.0.0"
}
}
}


provider "azurerm" {
features {}

client_id = var.client_id
client_secret = var.client_secret
subscription_id = var.subscription_id
tenant_id = var.tenant_id
}

module "networking" {
source = "./networking-module"

resource_group_name = "my-resource-group"
location = "UK South"
vnet_address_space = ["10.0.0.0/16"]
}

module "aks_cluster" {
source = "./aks-cluster-module"

aks_cluster_name = "my-resource-group"
cluster_location = "UK South"
dns_prefix = "webapps"
kubernetes_version = "1.28.4"
service_principal_client_id = var.client_id
service_principal_secret = var.client_secret

resource_group_name = module.networking.resource_group_name
vnet_id = module.networking.vnet_id
control_plane_subnet_id = module.networking.control_plane_subnet_id
worker_node_subnet_id = module.networking.worker_node_subnet_id

}
59 changes: 59 additions & 0 deletions aks-terraform/networking-module/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
resource "azurerm_resource_group" "network" {
name = var.resource_group_name
location = var.location
}

resource "azurerm_virtual_network" "aks_vnet" {
name = "aks-vnet"
resource_group_name = azurerm_resource_group.network.name
location = var.location
address_space = var.vnet_address_space
}

resource "azurerm_subnet" "control_plane_subnet" {
name = "control-plane-subnet"
resource_group_name = azurerm_resource_group.network.name
virtual_network_name = azurerm_virtual_network.aks_vnet.name
address_prefixes = ["10.0.1.0/24"] # Replace with the desired subnet address space
}

resource "azurerm_subnet" "worker_node_subnet" {
name = "worker-node-subnet"
resource_group_name = azurerm_resource_group.network.name
virtual_network_name = azurerm_virtual_network.aks_vnet.name
address_prefixes = ["10.0.2.0/24"] # Replace with the desired subnet address space
}

resource "azurerm_network_security_group" "aks_nsg" {
name = "aks-nsg"
location = var.location
resource_group_name = azurerm_resource_group.network.name
}

resource "azurerm_network_security_rule" "kube_apiserver_rule" {
name = "kube-apiserver-rule"
priority = 1001
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "6443"
source_address_prefix = "92.19.71.227/32" # Replace with your public IP address
destination_address_prefix = "*"
resource_group_name = azurerm_resource_group.network.name
network_security_group_name = azurerm_network_security_group.aks_nsg.name
}

resource "azurerm_network_security_rule" "ssh_rule" {
name = "ssh-rule"
priority = 1002
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "22"
source_address_prefix = "92.19.71.227/32" # Replace with your public IP address
destination_address_prefix = "*"
resource_group_name = azurerm_resource_group.network.name
network_security_group_name = azurerm_network_security_group.aks_nsg.name
}
24 changes: 24 additions & 0 deletions aks-terraform/networking-module/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
output "vnet_id" {
description = "ID of the Virtual Network (VNet)"
value = azurerm_virtual_network.aks_vnet.id
}

output "control_plane_subnet_id" {
description = "ID of the control plane subnet within the VNet"
value = azurerm_subnet.control_plane_subnet.id
}

output "worker_node_subnet_id" {
description = "ID of the worker node subnet within the VNet"
value = azurerm_subnet.worker_node_subnet.id
}

output "resource_group_name" {
description = "Name of the Azure Resource Group for networking resources"
value = azurerm_resource_group.network.name
}

output "aks_nsg_id" {
description = "ID of the Network Security Group (NSG)"
value = azurerm_network_security_group.aks_nsg.id
}
18 changes: 18 additions & 0 deletions aks-terraform/networking-module/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
variable "resource_group_name" {
description = "Name of the Azure Resource Group"
type = string
default = "my-resource-group"
}

variable "location" {
description = "Azure region for networking resources"
type = string
default = "UK South"
}

variable "vnet_address_space" {
description = "Address space for the Virtual Network (VNet)"
type = list(string)
default = ["10.0.0.0/16"]
}

Loading