From d7e314eaf1b1a043d20cd5774e81ed7ca01bccbf Mon Sep 17 00:00:00 2001 From: robertpountney92 Date: Tue, 22 Dec 2020 15:33:30 +0000 Subject: [PATCH] Everything now works, only thing still to do is add IDE to each workstation --- README.md | 53 +++++++++++++++++--------- TODO.md | 14 +++---- aks-cluster/README.md | 1 - assets/simple_ingress_k8s.png | Bin 0 -> 78127 bytes hello-world-ingress.yaml | 17 +-------- issuer.yaml | 6 ++- workstations/README.md | 3 +- workstations/data-sources.tf | 10 +---- workstations/outputs.tf | 30 --------------- workstations/service-principal.tf | 3 ++ workstations/templates/custom_data.sh | 9 +++-- workstations/variables.tf | 4 +- workstations/workstations.tf | 38 ++++++++---------- 13 files changed, 78 insertions(+), 110 deletions(-) create mode 100644 assets/simple_ingress_k8s.png diff --git a/README.md b/README.md index c4966e0..730ceb5 100644 --- a/README.md +++ b/README.md @@ -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 @@ -25,12 +29,18 @@ Clone down this repoistory Login to Azure using service principal - az login --service-principal -u -p password --tenant + 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 @@ -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) @@ -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//$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 diff --git a/TODO.md b/TODO.md index 3487883..aac6891 100644 --- a/TODO.md +++ b/TODO.md @@ -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) \ No newline at end of file +- [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 \ No newline at end of file diff --git a/aks-cluster/README.md b/aks-cluster/README.md index 7f2f219..5f6b082 100644 --- a/aks-cluster/README.md +++ b/aks-cluster/README.md @@ -7,7 +7,6 @@ az login - ## Create AKS cluster using Terraform terraform init diff --git a/assets/simple_ingress_k8s.png b/assets/simple_ingress_k8s.png new file mode 100644 index 0000000000000000000000000000000000000000..550fd62e377c12f4aaac830b4736bd6b6e5aba72 GIT binary patch literal 78127 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 C0U}-i literal 0 HcmV?d00001 diff --git a/hello-world-ingress.yaml b/hello-world-ingress.yaml index 41ccec0..e91d0cf 100644 --- a/hello-world-ingress.yaml +++ b/hello-world-ingress.yaml @@ -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: @@ -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 \ No newline at end of file + path: / \ No newline at end of file diff --git a/issuer.yaml b/issuer.yaml index 25dce43..1cb0019 100644 --- a/issuer.yaml +++ b/issuer.yaml @@ -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: robert.pountney@ecs.co.uk + email: user@example.com privateKeySecretRef: name: letsencrypt solvers: diff --git a/workstations/README.md b/workstations/README.md index b6eeb53..6e09d8e 100644 --- a/workstations/README.md +++ b/workstations/README.md @@ -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. diff --git a/workstations/data-sources.tf b/workstations/data-sources.tf index 33b251d..3aaf0fc 100644 --- a/workstations/data-sources.tf +++ b/workstations/data-sources.tf @@ -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" -# } -# } \ No newline at end of file +} \ No newline at end of file diff --git a/workstations/outputs.tf b/workstations/outputs.tf index 2ee89a5..0597f9b 100644 --- a/workstations/outputs.tf +++ b/workstations/outputs.tf @@ -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 } \ No newline at end of file diff --git a/workstations/service-principal.tf b/workstations/service-principal.tf index 40382d4..3a6e31c 100644 --- a/workstations/service-principal.tf +++ b/workstations/service-principal.tf @@ -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" diff --git a/workstations/templates/custom_data.sh b/workstations/templates/custom_data.sh index a97e196..417a853 100644 --- a/workstations/templates/custom_data.sh +++ b/workstations/templates/custom_data.sh @@ -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 @@ -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 diff --git a/workstations/variables.tf b/workstations/variables.tf index b4ce360..830d530 100644 --- a/workstations/variables.tf +++ b/workstations/variables.tf @@ -21,7 +21,7 @@ variable "workstation_username" { } variable "workstation_password" { - default = "Password1234!" + default = "Password1234!" sensitive = true } @@ -31,6 +31,6 @@ variable "vm_size" { } variable "app_password" { - default = "password" + default = "password" sensitive = true } \ No newline at end of file diff --git a/workstations/workstations.tf b/workstations/workstations.tf index 435181f..7c249bc 100644 --- a/workstations/workstations.tf +++ b/workstations/workstations.tf @@ -1,10 +1,11 @@ +############################################################################### # Configure isolated namespaces within the Kubernetes cluster for each attendee +############################################################################### resource "random_pet" "pet" { count = var.num_attendees } resource "kubernetes_namespace" "ns" { - depends_on = [random_pet.pet] for_each = toset(random_pet.pet.*.id) metadata { @@ -13,7 +14,6 @@ resource "kubernetes_namespace" "ns" { } resource "kubernetes_service_account" "sa" { - depends_on = [random_pet.pet] for_each = toset(random_pet.pet.*.id) metadata { @@ -23,8 +23,6 @@ resource "kubernetes_service_account" "sa" { } data "kubernetes_secret" "secret" { - # for_each = toset( [for s in kubernetes_service_account.sa : s.default_secret_name ]) - depends_on = [random_pet.pet] for_each = toset(random_pet.pet.*.id) metadata { @@ -34,7 +32,6 @@ data "kubernetes_secret" "secret" { } resource "kubernetes_role" "role" { - depends_on = [random_pet.pet] for_each = toset(random_pet.pet.*.id) metadata { @@ -67,12 +64,9 @@ resource "kubernetes_role" "role" { resources = ["ingresses"] verbs = ["*"] } - } - resource "kubernetes_role_binding" "rb" { - depends_on = [random_pet.pet] for_each = toset(random_pet.pet.*.id) metadata { @@ -92,7 +86,9 @@ resource "kubernetes_role_binding" "rb" { } } -# Create Azure virtual machines to act as workstations for attendees +#################################################################### +# Create Azure virtual machines to act as workstations for attendees +#################################################################### resource "azurerm_resource_group" "main" { name = "${var.prefix}-resources" location = var.location @@ -113,7 +109,6 @@ resource "azurerm_subnet" "internal" { } resource "azurerm_public_ip" "public" { - depends_on = [random_pet.pet] for_each = toset(random_pet.pet.*.id) name = "dpg-${each.key}-public-ip" @@ -139,7 +134,6 @@ resource "azurerm_network_interface" "main" { } resource "azurerm_virtual_machine" "main" { - depends_on = [random_pet.pet] for_each = toset(random_pet.pet.*.id) name = "dpg-${each.key}-vm" @@ -148,10 +142,8 @@ resource "azurerm_virtual_machine" "main" { network_interface_ids = [azurerm_network_interface.main[each.key].id] vm_size = var.vm_size - # Uncomment this line to delete the OS disk automatically when deleting the VM delete_os_disk_on_termination = true - # Uncomment this line to delete the data disks automatically when deleting the VM delete_data_disks_on_termination = true storage_image_reference { @@ -170,18 +162,20 @@ resource "azurerm_virtual_machine" "main" { computer_name = each.key admin_username = var.workstation_username admin_password = var.workstation_password - # custom_data = templatefile("${path.module}/templates/custom_data.sh", { user = var.workstation_username, host = data.terraform_remote_state.aks-cluster.outputs.host, namespace = kubernetes_namespace.ns[each.key].metadata[0].name, sa = kubernetes_service_account.sa[each.key].metadata[0].name, ca_cert = replace(replace(data.kubernetes_secret.secret[each.key].data["ca.crt"], "\n", ""), "/-----(\\w+\\s\\w+)-----/", ""), token = data.kubernetes_secret.secret[each.key].data["token"] }) custom_data = templatefile("${path.module}/templates/custom_data.sh", - { az_user = azuread_service_principal.sp.application_id, + { + az_user = azuread_service_principal.sp.application_id, az_password = var.app_password, - az_tenant = data.azurerm_client_config.current.tenant_id, - linux_user = var.workstation_username, - host = data.terraform_remote_state.aks-cluster.outputs.host, - namespace = kubernetes_namespace.ns[each.key].metadata[0].name, - sa = kubernetes_service_account.sa[each.key].metadata[0].name, - ca_cert = data.terraform_remote_state.aks-cluster.outputs.cluster_ca_certificate, - token = data.kubernetes_secret.secret[each.key].data["token"] }) + az_tenant = data.azurerm_client_config.current.tenant_id, + linux_user = var.workstation_username, + host = data.terraform_remote_state.aks-cluster.outputs.host, + namespace = kubernetes_namespace.ns[each.key].metadata[0].name, + sa = kubernetes_service_account.sa[each.key].metadata[0].name, + ca_cert = data.terraform_remote_state.aks-cluster.outputs.cluster_ca_certificate, + token = data.kubernetes_secret.secret[each.key].data["token"] } + ) + } os_profile_linux_config { disable_password_authentication = false }