Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docker File #134

Open
wants to merge 28 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
1500695
Adds feature delivery-date
ndm621 Jan 22, 2024
d25ed1a
Merge pull request #2 from ndm621/feature/add-delivery-date
ndm621 Jan 22, 2024
c7ddbce
Revert "Adds feature delivery-date"
ndm621 Jan 22, 2024
69ed3dd
Merge pull request #3 from ndm621/revert-delivery-date
ndm621 Jan 22, 2024
03181e8
Set up CI with Azure Pipelines
ndm621 Feb 10, 2024
e9f2f89
Update azure-pipelines.yml for Azure Pipelines
ndm621 Feb 10, 2024
8554868
Update azure-pipelines.yml for Azure Pipelines
ndm621 Feb 10, 2024
0cc6608
Update azure-pipelines.yml for Azure Pipelines
ndm621 Feb 11, 2024
5d3d575
Update azure-pipelines.yml for Azure Pipelines
ndm621 Feb 11, 2024
5206231
Update azure-pipelines.yml for Azure Pipelines
ndm621 Feb 11, 2024
eda3a89
Update azure-pipelines.yml for Azure Pipelines
ndm621 Feb 12, 2024
13f9d58
Create Dockerfile
ndm621 Feb 12, 2024
98bbac5
Create main.tf
ndm621 Feb 13, 2024
c1b42ce
Add files via upload
ndm621 Feb 13, 2024
03cbe98
Create main.tf
ndm621 Feb 13, 2024
3c6b317
Add files via upload
ndm621 Feb 13, 2024
838ceff
Create main.tf
ndm621 Feb 13, 2024
f98ab81
Add files via upload
ndm621 Feb 13, 2024
2a99bd5
Update variables.tf
ndm621 Feb 14, 2024
a6057d8
Update outputs.tf
ndm621 Feb 14, 2024
836bb14
Update azure-pipelines.yml for Azure Pipelines
ndm621 Feb 14, 2024
281908b
Create aks-terraform
ndm621 Feb 14, 2024
f5def72
Update azure-pipelines.yml for Azure Pipelines
ndm621 Feb 14, 2024
abff016
Update app.py
ndm621 Feb 19, 2024
efa8424
Update requirements.txt
ndm621 Feb 19, 2024
7939d3b
Update README.md
ndm621 Feb 19, 2024
1c7159a
Update README.md
ndm621 Feb 20, 2024
e8d3776
Update README.md
ndm621 Feb 20, 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
28 changes: 28 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Step 1 - Use an official Python runtime as a parent image. You can use `python:3.8-slim`.
FROM python:3.8-slim
# Step 2 - Set the working directory in the container
WORKDIR /app
# Step 3 Copy the application files in the container
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

# Step 4 - Install Python packages specified in requirements.txt
RUN pip install --trusted-host pypi.python.org -r ./app/requirements.txt
# Step 5 - Expose port
EXPOSE 5000
# Step 6 - Define Startup Command
# CMD [ "flask", "run","--host","127.0.0.1","--port","5000"]
entrypoint ["python", "./app/app.py"]
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Welcome to the Web App DevOps Project repo! This application allows you to effic
- [Features](#features)
- [Getting Started](#getting-started)
- [Technology Stack](#technology-stack)
- [Developer Information](#developer-information)
- [Contributors](#contributors)
- [License](#license)

Expand Down Expand Up @@ -36,6 +37,8 @@ For the application to succesfully run, you need to install the following packag
- pyodbc (version 4.0.39)
- SQLAlchemy (version 2.0.21)
- werkzeug (version 2.2.3)
- azure-identity
- azure-keyvault-secrets

### Usage

Expand All @@ -53,9 +56,41 @@ 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.

## Developer Information

- **Future Modifications:**
Any new feature to be added in future will need to modify code in both the app.py and orders.html files. For example, Delivery Date feature can be added by by modifying the order class, @app_route and new_order sections in the app.py. Also Delivery Date will need to be added to the order.html in the table and form elements.

- **Containerization Process:**
Containerization involves:
1. Creating a Docker File where base image, work directory, required libraries and dependencies and necessary commands are listed
1. Building Docker Image using the Docker File
docker build -t <image-name>
1. Run the Docker Image to test all the features
docker run -p 5000:5000 <image-name>
1. Tag and Push the image to the Docker Hub
docker tag <image-name> docker-user-name>/<image-name-in-Docker>:tag
1. Verify the Docker Hub Image by pulling it from the hub
1. Cleanup
- Romove Containers
- docker ps -a
- docker rm <container-id>

- Remove Images
- docker images -a
- docker rmi <image-id>

- **Infrastructure as Code IaC:**
The folder aka-terraform has all the necessary files to provision the resources on the Kubernetes and then to AKS. These details include the following:
- Terraform Modules
- Cluster Module
- Networking Modules
- Input and Output Variables

## Contributors

- [Maya Iuga]([https://github.com/yourusername](https://github.com/maya-a-iuga))
- [Muhammad Nadeem Khan]([https://github.com/ndm621](https://github.com/ndm621))

## License

Expand Down
23 changes: 23 additions & 0 deletions aka-terraform/aks-cluster-module/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# aks-cluster-module/main.tf
# Create the AKS cluster
resource "azurerm_kubernetes_cluster" "aks_cluster" {
name = var.cluster_name
location = var.cluster_location
resource_group_name = var.resource_group_name
dns_prefix = var.dns_prefix
kubernetes_version = var.kubernetes_version

default_node_pool {
name = "default"
node_count = 1
vm_size = "Standard_DS2_v2"
enable_auto_scaling = true
min_count = 1
max_count = 3
}

service_principal {
client_id = var.service_principal_client_id
client_secret = var.service_principal_client_secret
}
}
14 changes: 14 additions & 0 deletions aka-terraform/aks-cluster-module/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
output "cluster_name" {
description = "Name of the AKS cluster."
value = azurerm_kubernetes_cluster.aks_cluster.name
}

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

output "aks_kubeconfig" {
description = "Kubeconfig file for accessing the AKS cluster."
value = azurerm_kubernetes_cluster.aks_cluster.kube_config_raw
}
59 changes: 59 additions & 0 deletions aka-terraform/aks-cluster-module/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
variable "cluster_name" {
description = "The name of the AKS cluster"
type = string
default = "aks-cluster"
}

variable "cluster_location" {
description = "The Azure Region of the AKS cluster"
type = string
default = "UK South"
}

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

variable "kubernetes_version" {
description = "Kubernetes version of the AKS cluster"
type = string
default = "value"
}

variable "service_principal_client_id" {
description = "Client ID of the service principal of the AKS cluster"
type = string
default = "value"
}

variable "service_principal_client_secret" {
description = "Client Secret of the service principal"
type = string
default = "value"
}

variable "resource_group_name" {
description = "Resource Group Name in Azure"
type = string
default = "aks-resources"
}

variable "vnet_id" {
description = "ID of the previously created VNet"
type = string
default = "aks-vnet"
}

variable "control_plane_subnet_id" {
description = "ID of the control plane subnet within the VNet"
type = string
default = "control-plane-subnet"
}

variable "worker_node_subnet_id" {
description = "ID of the worker node subnet within the VNet"
type = string
default = "worker-node-subnet"
}
40 changes: 40 additions & 0 deletions aka-terraform/application-manifest.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: flask-app-deployment
labels:
app: flask-app
spec:
replicas: 2
selector:
matchLabels:
app: flask-app
template:
metadata:
labels:
app: flask-app
spec:
containers:
- name: flask-app
image: ndm621/web-app-img:v1.0
ports:
- containerPort: 5000
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1

---
apiVersion: v1
kind: Service
metadata:
name: flask-app-service
spec:
selector:
app: flask-app
type: ClusterIP
ports:
- protocol: TCP
port: 80
targetPort: 5000
45 changes: 45 additions & 0 deletions aka-terraform/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
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 = "07bd18f6-a3df-4eda-91a2-e133a16dbf5c"
tenant_id = "47d4542c-f112-47f4-92c7-a838d8a5e8ef"
}

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

# Input variables for the networking module
resource_group_name = "networking-rg"
location = "UK South"
vnet_address_space = ["10.0.0.0/16"]

# Define more input variables as needed...
}

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

# Input variables for the AKS cluster module
cluster_name = "terraform-aks-cluster"
cluster_location = "UK South"
dns_prefix = "myaks-project"
kubernetes_version = "1.26.6" # Adjust the version as needed
service_principal_client_id = var.client_id
service_principal_client_secret = var.client_secret

# Input variables referencing outputs from the networking module
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
}
75 changes: 75 additions & 0 deletions aka-terraform/networking-module/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "=3.0.0"
}
}
}

provider "azurerm" {
features {}
}

# 1. Define the Azure resource group resource
resource "azurerm_resource_group" "aks" {
name = var.resource_group_name
location = "UK South"
}

# 2. Define Virtual Network (VNet)
resource "azurerm_virtual_network" "aks_vnet" {
name = "aks-vnet"
address_space = ["10.0.0.0/16"]
location = azurerm_resource_group.aks.location
resource_group_name = azurerm_resource_group.aks.name
depends_on = [ azurerm_resource_group.aks ]
}

resource "azurerm_subnet" "control_plane_subnet" {
name = "control-plane-subnet"
resource_group_name = azurerm_resource_group.aks.name
virtual_network_name = azurerm_virtual_network.aks_vnet.name
address_prefixes = ["10.0.1.0/24"]
}

resource "azurerm_subnet" "worker_node_subnet" {
name = "worker-node-subnet"
resource_group_name = azurerm_resource_group.aks.name
virtual_network_name = azurerm_virtual_network.aks_vnet.name
address_prefixes = ["10.0.2.0/24"]
}

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

resource "azurerm_network_security_rule" "kube_apiserver_rule" {
name = "kube-apiserver"
resource_group_name = azurerm_resource_group.aks.name
network_security_group_name = azurerm_network_security_group.aks_nsg.name
priority = 1001
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "6443"
source_address_prefix = "*"
destination_address_prefix = "*"
}

resource "azurerm_network_security_rule" "ssh_rule" {
name = "ssh "
resource_group_name = azurerm_resource_group.aks.name
network_security_group_name = azurerm_network_security_group.aks_nsg.name
priority = 1002
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "22"
source_address_prefix = "*"
destination_address_prefix = "*"
}
27 changes: 27 additions & 0 deletions aka-terraform/networking-module/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# networking-module/outputs.tf

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."
value = azurerm_subnet.control_plane_subnet.id
}

output "worker_node_subnet_id" {
description = "ID of the worker node subnet."
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.aks.name
}

# Define more output variables as needed...
output "aks_nsg_id" {
description = "ID of the Network Security Group (NSG) for AKS."
value = azurerm_network_security_group.aks_nsg.id
}
17 changes: 17 additions & 0 deletions aka-terraform/networking-module/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
variable "resource_group_name" {
description = "Resource Group Name in Azure"
type = string
default = "aks-resources"
}

variable "location" {
description = "location of account"
type = string
default = "UK South"
}

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