Skip to content

Commit

Permalink
Everything now works, only thing still to do is add IDE to each works…
Browse files Browse the repository at this point in the history
…tation
  • Loading branch information
robertpountney92 committed Dec 22, 2020
1 parent 2178ed4 commit d7e314e
Show file tree
Hide file tree
Showing 13 changed files with 78 additions and 110 deletions.
53 changes: 36 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,20 @@

## Introduction
Ever wonder how certificates and HTTPS actually work ?
I know I have for a long time. For years I pretended that I understood as it seems to be either expected as prior knowledge when at work or simply glossed over in many tutorials when you take the initiative to do a bit of self learning.
I know I have for a long time. For years I pretended that I understood, as it seemed to either be expected as prior knowledge when at work or simply glossed over in many tutorials when you take the initiative to do some self learning.

And nowadays all applications need to run as containerised workloads on scaleable platforms such as (the buzz word of all buzz words) Kubernetes.

So simply knowing how certificates work is not enough, we need to know how to do something useful with this knowledge...like deploying HTTPS applications on the covetted Kubernetes.
And nowadays, simply knowing how certificates work is not enough. We need to know how to do something useful with this knowledge. Such as deploying HTTPS applications on modern platform of choice, Kubernetes.

Hopefully all hope is not lost...This hands on session aims to explain what certificate are, how they are used for secure commication and also how we can leverage Kubernetes to deploy HTTPS applications with relative ease.

## Tutorial
This tutorial covers the steps required to deploy a HTTPS application on a pre-existing Kubernetes cluster build on on Azure Kubernetes Service (AKS)
This tutorial covers the steps required to deploy a HTTPS application on a pre-existing Kubernetes cluster built on on Azure Kubernetes Service (AKS).

In order to deploy our HTTPS application, we will leverage the Ingress resource, available by default, in Kubernetes

Ingress exposes HTTP and HTTPS routes from outside the cluster to services within the cluster.

![alt text](assets/simple_ingress_k8s.png "Simple Ingress Example Kubernetes")

### Initial setup
SSH into your workstation
Expand All @@ -25,12 +29,18 @@ Clone down this repoistory

Login to Azure using service principal

az login --service-principal -u <app_id> -p password --tenant <tenant_id>
az login --service-principal -u $APP_ID -p $APP_PW --tenant $TENANT_ID

### Deploy an HTTPS ingress controller using Helm
In order for the Ingress resource to work, the cluster must have an ingress controller running.

We can declaratively define Ingress resources using manifests, however it is the ingress controller that determines how this will be fulfilled. The Ingress controller watches for new Ingress rules and fulfills the mapping from services within the cluster to particular URLs/domain names for public consumption.

Unlike other types of controllers which run as part of the kube-controller-manager binary, Ingress controllers are not started automatically with a cluster. The most popular controller is provided by NGINX, we can add this to our cluster using Helm.

Helm is a package manager purpose built for Kubernetes. Helm has been pre-installed on your workstations.

Add the ingress-nginx repository (as this is not added to default Helm installation)
Add the ingress-nginx repository

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx

Expand All @@ -45,12 +55,14 @@ Once this is deployed, we can view the created service and assocaited EXTERNAL_I

kubectl get services ingress-nginx-controller

Configure an FQDN for the ingress controller `EXTERNAL_IP`
### Configure a FQDN for the ingress controller EXTERNAL_IP

During the installation, an Azure public IP address is created for the ingress controller which we can associate with a Fully Qualified Domain Name.

# Public IP address of your ingress controller
IP=$(kubectl get services ingress-nginx-controller | awk 'NR==2 {print $4}')

# Associate public IP address with DNS name, we will use the hostname of our workstation as an example
# Associate Public IP address with DNS name, we will use the hostname of our workstation as an example
DNSNAME=$(hostname)

# Get the resource-id of the public ip (Note may need to wait a few minutes for this to work)
Expand All @@ -65,23 +77,30 @@ Configure an FQDN for the ingress controller `EXTERNAL_IP`
# Set FQDN as variable
FQDN=$(az network public-ip show --ids $PUBLICIPID --query "[dnsSettings.fqdn]" --output tsv)

Prior to this interactive session, the kubernetes cert-manager has been pre-installed onto the Kubernetes cluster. See `aks-cluster` directory for details.
Cert-manager is a native Kubernetes certificate management controller. It can help with issuing certificates from a variety of sources, such as Let’s Encrypt, HashiCorp Vault or self signed certificates.
### Deploy demo application to Kubernetes cluster
Deploy the demo application using `kubectl apply`

Create cluster issuer
kubectl apply -f aks-helloworld.yaml

kubectl apply -f issuer.yaml
### Issue Certificates and configure Ingress
Prior to this interactive session, the kubernetes cert-manager controller has been pre-installed onto the Kubernetes cluster. See `aks-cluster` directory for details.

Run the two demo applications using `kubectl apply`
Cert-manager is a Kubernetes add-on to automate the management and issuance of TLS certificates from various issuing sources (i.e External CAs such as Let's Encrypt, Self Signed certificates or HashiCorp Vault).

kubectl apply -f aks-helloworld.yaml
Create Issuer

Create an ingress route
kubectl apply -f issuer.yaml

Create an Ingress route

sed -i "s/<REPLACE_ME>/$FQDN/g" hello-world-ingress.yaml
kubectl apply -f hello-world-ingress.yaml

Verify that the certificate was created successfully by checking READY is True, which may take several minutes.
Verify that the certificate was created successfully by checking READY is True, which may take a minute

kubectl get certificate

### View HTTPS applicaiton in browser
Finally navigate to the the Fully Qualified Domain Name, copy the result of the echo command to your browser

echo $FQDN
14 changes: 7 additions & 7 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
- [x] HELM
- [x] Azure CLI
- [x] kubectl
- [x] kubeconf file for the namespace
- [x] .kube/config file for the namespace
- [x] SSH
- [ ] IDE
- [ ] git (and clone down repo) - Need the repo to be public
- [ ] Service principal (permissions for the workstations - possibly one for all)
- [x] git
- [x] Service principal (permissions for the workstations - possibly one for all)
- [x] Service principal created
- [ ] Place credentials on attendee workstation for easy login
- [x] Place credentials on attendee workstation for easy login
- [x] K8s namespace configuration
- [ ] Correct K8s Roles/RoleBindings for each attendee (in progress )
- [x] Correct K8s Roles/RoleBindings for each attendee
- [x] Synopsis of topic
- [ ] Add steps for playground to README (Need to clean up and make more polished)
- [ ] Need to figure out how to add attach class to ingress resource (may need to revert to earlier version of kubernetes)
- [x] Add steps for playground to README (Need to clean up and make more polished)
- [x] Need to figure out how to add attach class to ingress resource
1 change: 0 additions & 1 deletion aks-cluster/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

az login


## Create AKS cluster using Terraform

terraform init
Expand Down
Binary file added assets/simple_ingress_k8s.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 2 additions & 15 deletions hello-world-ingress.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@ kind: Ingress
metadata:
name: hello-world-ingress
annotations:
# Need to install an earlier version of kubernetes on workstation to use this annotation
# kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /$1
nginx.ingress.kubernetes.io/use-regex: "true"
cert-manager.io/cluster-issuer: letsencrypt
cert-manager.io/issuer: letsencrypt
spec:
ingressClassName: nginx
tls:
Expand All @@ -21,15 +19,4 @@ spec:
- backend:
serviceName: aks-helloworld
servicePort: 80
path: /(.*)
---
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: nginx
# spec:
# controller: ingress-nginx-controller
# parameters:
# apiGroup: k8s.example.com
# kind: IngressParameters
# name: external-lb
path: /
6 changes: 5 additions & 1 deletion issuer.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
apiVersion: cert-manager.io/v1alpha2
# An Issuer is a custom resource definition (CRD) made available through the cert-manager controller
# Issuers represent CAs and allow us to automate the generation of signed certificates
kind: Issuer
metadata:
name: letsencrypt
spec:
# Automated Certificate Management Environment (ACME) Certificate Authority server
# Certificates issued by public ACME servers are typically trusted by client’s browsers by default
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: [email protected]
email: [email protected]
privateKeySecretRef:
name: letsencrypt
solvers:
Expand Down
3 changes: 1 addition & 2 deletions workstations/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ Must have built aks-cluster and resource group from other directory.
## Create workstations using Terraform

terraform init
terraform apply -target random_pet.pet -auto-approve # use -target flag to first apply only the
resources that the for_each depends on.
terraform apply -auto-approve -target random_pet.pet
terraform apply -auto-approve

Note: May need to perform `terraform refresh` if `azure_vm_public_ips` are not generated on initial apply.
Expand Down
10 changes: 1 addition & 9 deletions workstations/data-sources.tf
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,4 @@ data "terraform_remote_state" "aks-cluster" {
config = {
path = "../aks-cluster/terraform.tfstate"
}
}

# data "azurerm_resource_group" "default" {
# backend = "local"

# config = {
# path = "../aks-cluster/terraform.tfstate"
# }
# }
}
30 changes: 0 additions & 30 deletions workstations/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,4 @@ output "kubernetes_namespace_names" {

output "azure_vm_public_ips" {
value = [for pub_ip in azurerm_public_ip.public : pub_ip.ip_address]
}

# output "kubernetes_sa_secret_name" {
# # value = kubernetes_service_account.sa.secret[0].name
# value = [for sa in kubernetes_service_account.sa : sa.default_secret_name]
# }

# output "kubernetes_secret_ca_crt" {
# # value = kubernetes_service_account.sa.secret[0].name
# value = [for secret in data.kubernetes_secret.secret : secret.data["ca.crt"] ]
# }

# output "kubernetes_secret_token" {
# # value = kubernetes_service_account.sa.secret[0].name
# value = [for secret in data.kubernetes_secret.secret : secret.data["token"] ]
# }

# output "kubernetes_secret_ca_crt" {
# # value = kubernetes_service_account.sa.secret[0].name
# value = [for secret in data.kubernetes_secret.secret : secret.data]
# }

output "azure_service_principal_app_id" {
# value = kubernetes_service_account.sa.secret[0].name
value = azuread_service_principal.sp.application_id
}

output "azure_service_principal_obj_id" {
# value = kubernetes_service_account.sa.secret[0].name
value = azuread_service_principal.sp.object_id
}
3 changes: 3 additions & 0 deletions workstations/service-principal.tf
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
##############################################################################
# Create service principal with access to only the public-ip resouce in Azure
##############################################################################
resource "azuread_application" "app" {
name = "dpg"
homepage = "https://dpg"
Expand Down
9 changes: 5 additions & 4 deletions workstations/templates/custom_data.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@ apt-get install helm
# Install git
apt-get install git -y

# Install Azure CLI and login
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
az login --service-principal -u ${az_user} -p ${az_password} --tenant ${az_tenant}
# Install Azure CLI and add service principal creds to .bashrc as environment variables
curl -sL https://aka.ms/InstallAzureCLIDeb | bash
echo "export APP_ID=${az_user}" >> /home/${linux_user}/.bashrc
echo "export APP_PW=${az_password}" >> /home/${linux_user}/.bashrc
echo "export TENANT_ID=${az_tenant}" >> /home/${linux_user}/.bashrc

# Create .kube/config file
mkdir /home/${linux_user}/.kube
Expand All @@ -37,7 +39,6 @@ preferences: {}
clusters:
- cluster:
certificate-authority-data: ${ca_cert}
# You'll need the API endpoint of your Cluster here:
server: ${host}
name: verified-drake-aks
Expand Down
4 changes: 2 additions & 2 deletions workstations/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ variable "workstation_username" {
}

variable "workstation_password" {
default = "Password1234!"
default = "Password1234!"
sensitive = true
}

Expand All @@ -31,6 +31,6 @@ variable "vm_size" {
}

variable "app_password" {
default = "password"
default = "password"
sensitive = true
}
Loading

0 comments on commit d7e314e

Please sign in to comment.