Deploying a fullstack app using terraform to provision ACR,AKS,and Azure SQL database.
Tags: devops, kubernetes, azure, node
Published: 2023-05-20 16:50:55

This article shows a step by step of how i accomplished my  final project fro the She Code Africa Cloud School Program 2023.


I managed to complete the project within a few days and with technologies such as Docker, Azure Container registry ,Azure kubernetes Service and Azure SQL Database.

I decide to use terraform to provison the infrastructure which included :
- Azure Container Registry
- Azure Kubernetes Service
- Azure SQL Database with sample database

![Image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dbdq5ubwq2c7oqwsl4ik.png)


```
terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~> 2.65"
    }

    random = {
      source  = "hashicorp/random"
      version = "3.1.0"
    }
  }
}

provider "azurerm" {
  features {}
}

resource "azurerm_resource_group" "emmilly-rg" {
  name     = "emmilly_mssql_acr_aks_rg"
  location = "South Africa North"
}

resource "azurerm_container_registry" "emmilly-acr" {
  name                = "emmillyacr"
  sku                 = "Premium"
  resource_group_name = azurerm_resource_group.emmilly-rg.name
  location            = azurerm_resource_group.emmilly-rg.location
}

resource "azurerm_kubernetes_cluster" "emmilly-k8s-cluster" {
  name                = "emmilly-aks"
  location            = azurerm_resource_group.emmilly-rg.location
  resource_group_name = azurerm_resource_group.emmilly-rg.name
  dns_prefix          = "emmilly-dns"
  public_network_access_enabled = true

  network_profile {
    network_plugin = "kubenet"
    load_balancer_sku = "standard"  
  }

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

  identity {
    type = "SystemAssigned"
  }

  tags = {
    Environment = "Production"
  }
}
resource "azurerm_role_assignment" "enablePulling" {
  principal_id                     = azurerm_kubernetes_cluster.emmilly-k8s-cluster.kubelet_identity[0].object_id
  role_definition_name             = "AcrPull"
  scope                            = azurerm_container_registry.emmilly-acr.id
  skip_service_principal_aad_check = true
}



resource "azurerm_mssql_server" "test-server" {
  name                         = "sqltest-server-emmilly"
  resource_group_name          = azurerm_resource_group.emmilly-rg.name
  location                     = azurerm_resource_group.emmilly-rg.location
  version                      = "12.0"
  administrator_login          = "emmilly"
  administrator_login_password = "emily@256"
  minimum_tls_version          = "1.2"

}

resource "azurerm_mssql_database" "test-db" {
  name           = "sqltest"
  server_id      = azurerm_mssql_server.test-server.id
  collation      = "SQL_Latin1_General_CP1_CI_AS"
  license_type   = "LicenseIncluded"
  read_scale     = false
  sku_name       = "S0"
  zone_redundant = false
  sample_name    = "AdventureWorksLT"

  tags = {
    dev = "Production"
  }
}
output "client_certificate" {
  value = azurerm_kubernetes_cluster.emmilly-k8s-cluster.kube_config.0.client_certificate
}

output "kube_config" {
  value = azurerm_kubernetes_cluster.emmilly-k8s-cluster.kube_config_raw

  sensitive = true
}

```
So after i wrote the terraform file, i validated and applied the file using.

Initialise terraform in the terminal.
```
terraform init

```

![rinit](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zc7cft5g9owg9wk8avib.png)


```
terraform validate
```

![terraform](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7kukkg4ydvv5vtu5u8qt.png)



```
terraform apply -auto-approve
```

![apply](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7vqy1bqwt8c8x6fn6dtr.png)

After provisioning the resources, i could see them on my portal.

![provisioned](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sztd1m2634wtmrnkvq3e.png)

Next i added a docker file to my node js application and built an image from it and tag it

```
docker build . -t shecloud
```
```
docker tag shecloud <loginservername/shecloud>
```
![build](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o5v8mte0ynkiu5k3d4rv.png)

Check built images with
```
docker images

```

![Images](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4wzl3p2g2qs8q6pbj907.png)



Next we had to log into the regisrty using docker

```
docker login <login server name>
```
To see your server username an password, enable the button.
![I](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2enaqy83s84h8rml0i8m.png)

![login](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/79xk7tbn2oukwfpky0l9.png)

![login2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p5nsirzoaftok38rrx8n.png)

To see your registry loginserver

![reg](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g8xn6cpnk5uc2njgcdfz.png)






```
docker push shecloud <loginservername>/shecloud
```

![push](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4oh2eizdzb01g4rz3nho.png)

After pushing, we should be able to see out image under repositories in the Azure Container registry.

![registry](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mk5w6dkgci1twl0u2vna.png)



Next login to be able to deploy to kubernetes.
```
az login
```

```
az account set --subscription xxxxxx-xxxx-xxxx-xxxxxx
```

```
az aks get-credentials --resource-group <resource group nae> --name <aks name>
```

![credential](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2y0ul9bda8z5wq29pyul.png)


```
kubectl get nodes
```

![nodes](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7f7qgzkr8jfagnob9fg2.png)

Next i deployed using this yaml file.

```

apiVersion: apps/v1
kind: Deployment
metadata:
  name: azure-shecloud
spec:
  replicas: 1
  selector:
    matchLabels:
      app: azure-shecloud
  template:
    metadata:
      labels:
        app: azure-shecloud
    spec:
      nodeSelector:
        "kubernetes.io/os": linux
      containers:
      - name: azure-shecloud
        image: emmillyacr.azurecr.io/shecloud:latest
        env:
        - name: ALLOW_EMPTY_PASSWORD
          value: "yes"
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
          limits:
            cpu: 250m
            memory: 256Mi
        ports:
        - containerPort: 3000
          name: azure-shecloud
---
apiVersion: v1
kind: Service
metadata:
  name: azure-shecloud
spec:
  type: LoadBalancer  
  ports:
  - port: 3000
  selector:
    app: azure-shecloud
---


```
```
 kubectl apply -f node_sql.yaml
```

![yaml file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0aq19kckrojsbq56zwsp.png)

Net to see the external ip Of the app we use

```
kubectl get svc
```

![service](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j3rnbv3jlbxcl8l7il4m.png)

Next we move to the portal to the database server network allow ips access.

![ips](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9ddgaca6gxhxz3a3pput.png)
**NB**: be sure to tick the box allowing services access server.

![tick](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cgl8vozh7ndt58ye9gl3.png)

Click save to save the changes .

When we check the External ip 20.87.94.72:3000

![webapp](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eb1d8xlpnpvymuybrf2y.png)