From 56e7eb473f821709c5028cdb051d4c3f7e063e76 Mon Sep 17 00:00:00 2001 From: marcel-dempers Date: Tue, 14 Jul 2020 20:52:24 +1000 Subject: [PATCH] kubernetes on azure with terraform --- .gitignore | 4 + kubernetes/cloud/azure/getting-started.md | 2 +- kubernetes/cloud/azure/terraform/main.tf | 22 +++++ .../terraform/modules/cluster/cluster.tf | 72 +++++++++++++++ .../terraform/modules/cluster/outputs.tf | 19 ++++ .../terraform/modules/cluster/variables.tf | 16 ++++ .../cloud/azure/terraform/modules/k8s/k8s.tf | 68 ++++++++++++++ .../azure/terraform/modules/k8s/variables.tf | 11 +++ kubernetes/cloud/azure/terraform/readme.md | 89 +++++++++++++++++++ kubernetes/cloud/azure/terraform/variables.tf | 16 ++++ 10 files changed, 318 insertions(+), 1 deletion(-) create mode 100644 kubernetes/cloud/azure/terraform/main.tf create mode 100644 kubernetes/cloud/azure/terraform/modules/cluster/cluster.tf create mode 100644 kubernetes/cloud/azure/terraform/modules/cluster/outputs.tf create mode 100644 kubernetes/cloud/azure/terraform/modules/cluster/variables.tf create mode 100644 kubernetes/cloud/azure/terraform/modules/k8s/k8s.tf create mode 100644 kubernetes/cloud/azure/terraform/modules/k8s/variables.tf create mode 100644 kubernetes/cloud/azure/terraform/readme.md create mode 100644 kubernetes/cloud/azure/terraform/variables.tf diff --git a/.gitignore b/.gitignore index 3e438a8..52e235d 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,7 @@ node_modules/ __pycache__/ *.pem *.csr +# terraform +.terraform +*.tfstate +*.tfstate.* \ No newline at end of file diff --git a/kubernetes/cloud/azure/getting-started.md b/kubernetes/cloud/azure/getting-started.md index 93585d4..c1b64f2 100644 --- a/kubernetes/cloud/azure/getting-started.md +++ b/kubernetes/cloud/azure/getting-started.md @@ -70,7 +70,7 @@ cp ~/.ssh/id_rsa* . az aks create -n aks-getting-started \ --resource-group $RESOURCEGROUP \ --location australiaeast \ ---kubernetes-version 1.16.9 \ +--kubernetes-version 1.16.10 \ --load-balancer-sku standard \ --nodepool-name default \ --node-count 1 \ diff --git a/kubernetes/cloud/azure/terraform/main.tf b/kubernetes/cloud/azure/terraform/main.tf new file mode 100644 index 0000000..4d35bff --- /dev/null +++ b/kubernetes/cloud/azure/terraform/main.tf @@ -0,0 +1,22 @@ +provider "azurerm" { + version = "=2.0.0" + features {} +} + +module "cluster" { + source = "./modules/cluster/" + serviceprinciple_id = var.serviceprinciple_id + serviceprinciple_key = var.serviceprinciple_key + ssh_key = var.ssh_key + location = var.location + kubernetes_version = var.kubernetes_version + +} + +module "k8s" { + source = "./modules/k8s/" + host = "${module.cluster.host}" + client_certificate = "${base64decode(module.cluster.client_certificate)}" + client_key = "${base64decode(module.cluster.client_key)}" + cluster_ca_certificate= "${base64decode(module.cluster.cluster_ca_certificate)}" +} \ No newline at end of file diff --git a/kubernetes/cloud/azure/terraform/modules/cluster/cluster.tf b/kubernetes/cloud/azure/terraform/modules/cluster/cluster.tf new file mode 100644 index 0000000..ed89f15 --- /dev/null +++ b/kubernetes/cloud/azure/terraform/modules/cluster/cluster.tf @@ -0,0 +1,72 @@ +resource "azurerm_resource_group" "aks-getting-started" { + name = "aks-getting-started" + location = var.location +} + +resource "azurerm_kubernetes_cluster" "aks-getting-started" { + name = "aks-getting-started" + location = azurerm_resource_group.aks-getting-started.location + resource_group_name = azurerm_resource_group.aks-getting-started.name + dns_prefix = "aks-getting-started" + kubernetes_version = var.kubernetes_version + + default_node_pool { + name = "default" + node_count = 1 + vm_size = "Standard_E4s_v3" + type = "VirtualMachineScaleSets" + os_disk_size_gb = 250 + } + + service_principal { + client_id = var.serviceprinciple_id + client_secret = var.serviceprinciple_key + } + + linux_profile { + admin_username = "azureuser" + ssh_key { + key_data = var.ssh_key + } + } + + + network_profile { + network_plugin = "kubenet" + load_balancer_sku = "Standard" + } + + addon_profile { + aci_connector_linux { + enabled = false + } + + azure_policy { + enabled = false + } + + http_application_routing { + enabled = false + } + + kube_dashboard { + enabled = false + } + + oms_agent { + enabled = false + } + } +} + +/* +resource "azurerm_kubernetes_cluster_node_pool" "monitoring" { + name = "monitoring" + kubernetes_cluster_id = azurerm_kubernetes_cluster.aks-getting-started.id + vm_size = "Standard_DS2_v2" + node_count = 1 + os_disk_size_gb = 250 + os_type = "Linux" +} + +*/ \ No newline at end of file diff --git a/kubernetes/cloud/azure/terraform/modules/cluster/outputs.tf b/kubernetes/cloud/azure/terraform/modules/cluster/outputs.tf new file mode 100644 index 0000000..06433ef --- /dev/null +++ b/kubernetes/cloud/azure/terraform/modules/cluster/outputs.tf @@ -0,0 +1,19 @@ +output "kube_config" { + value = azurerm_kubernetes_cluster.aks-getting-started.kube_config_raw +} + +output "cluster_ca_certificate" { + value = azurerm_kubernetes_cluster.aks-getting-started.kube_config.0.cluster_ca_certificate +} + +output "client_certificate" { + value = azurerm_kubernetes_cluster.aks-getting-started.kube_config.0.client_certificate +} + +output "client_key" { + value = azurerm_kubernetes_cluster.aks-getting-started.kube_config.0.client_key +} + +output "host" { + value = azurerm_kubernetes_cluster.aks-getting-started.kube_config.0.host +} \ No newline at end of file diff --git a/kubernetes/cloud/azure/terraform/modules/cluster/variables.tf b/kubernetes/cloud/azure/terraform/modules/cluster/variables.tf new file mode 100644 index 0000000..7261847 --- /dev/null +++ b/kubernetes/cloud/azure/terraform/modules/cluster/variables.tf @@ -0,0 +1,16 @@ +variable "serviceprinciple_id" { +} + +variable "serviceprinciple_key" { +} + +variable "ssh_key" { +} + +variable "location" { + default = "australiaeast" +} + +variable "kubernetes_version" { + default = "1.16.10" +} \ No newline at end of file diff --git a/kubernetes/cloud/azure/terraform/modules/k8s/k8s.tf b/kubernetes/cloud/azure/terraform/modules/k8s/k8s.tf new file mode 100644 index 0000000..959848b --- /dev/null +++ b/kubernetes/cloud/azure/terraform/modules/k8s/k8s.tf @@ -0,0 +1,68 @@ + +provider "kubernetes" { + load_config_file = "false" + host = var.host + client_certificate = var.client_certificate + client_key = var.client_key + cluster_ca_certificate = var.cluster_ca_certificate +} + +resource "kubernetes_deployment" "example" { + metadata { + name = "terraform-example" + labels = { + test = "MyExampleApp" + } + } + + spec { + replicas = 3 + + selector { + match_labels = { + test = "MyExampleApp" + } + } + + template { + metadata { + labels = { + test = "MyExampleApp" + } + } + + spec { + container { + image = "nginx:1.7.8" + name = "example" + + resources { + limits { + cpu = "0.5" + memory = "512Mi" + } + requests { + cpu = "250m" + memory = "50Mi" + } + } + + liveness_probe { + http_get { + path = "/nginx_status" + port = 80 + + http_header { + name = "X-Custom-Header" + value = "Awesome" + } + } + + initial_delay_seconds = 3 + period_seconds = 3 + } + } + } + } + } +} diff --git a/kubernetes/cloud/azure/terraform/modules/k8s/variables.tf b/kubernetes/cloud/azure/terraform/modules/k8s/variables.tf new file mode 100644 index 0000000..680a37f --- /dev/null +++ b/kubernetes/cloud/azure/terraform/modules/k8s/variables.tf @@ -0,0 +1,11 @@ +variable "host" { +} + +variable "client_certificate" { +} + +variable "client_key" { +} + +variable "cluster_ca_certificate" { +} \ No newline at end of file diff --git a/kubernetes/cloud/azure/terraform/readme.md b/kubernetes/cloud/azure/terraform/readme.md new file mode 100644 index 0000000..44a22f4 --- /dev/null +++ b/kubernetes/cloud/azure/terraform/readme.md @@ -0,0 +1,89 @@ +# Getting Started with AKS using Terraform + +More resources: + +Terraform provider for Azure [here](https://github.com/terraform-providers/terraform-provider-azurerm)
+ +## Azure CLI + +We'll need the Azure CLI to gather information so we can build our Terraform file. + +``` +# Run Azure CLI +docker run -it --rm -v ${PWD}:/work -w /work --entrypoint /bin/sh mcr.microsoft.com/azure-cli:2.6.0 + +# Get Terraform + +curl -o /tmp/terraform.zip -LO https://releases.hashicorp.com/terraform/0.12.28/terraform_0.12.28_linux_amd64.zip + +unzip /tmp/terraform.zip +chmod +x terraform && mv /usr/local/bin/ + +cd kubernetes/cloud/azure/terraform/ +terraform init + +``` + +## Login to Azure + +``` +#login and follow prompts +az login + +# view and select your subscription account + +az account list -o table +SUBSCRIPTION= +az account set --subscription $SUBSCRIPTION + +``` + +## Create our Resource Group + +``` +RESOURCEGROUP=aks-getting-started +RESOURCEGROUP_ID=$(az group create -n $RESOURCEGROUP -l australiaeast | jq -r '.id') + +``` + +## Create Service Principal + +Kubernetes needs a service account to manage our Kubernetes cluster
+Lets create one!
+ +``` + +SERVICE_PRINCIPAL_JSON=$(az ad sp create-for-rbac --skip-assignment --name aks-getting-started-sp -o json) + +#Keep the `appId` and `password` for later use! + +SERVICE_PRINCIPAL=$(echo $SERVICE_PRINCIPAL_JSON | jq -r '.appId') +SERVICE_PRINCIPAL_SECRET=$(echo $SERVICE_PRINCIPAL_JSON | jq -r '.password') + +#grant contributor role over the resource group to our service principal + +az role assignment create --assignee $SERVICE_PRINCIPAL \ +--scope "/subscriptions/$SUBSCRIPTION/resourceGroups/$RESOURCEGROUP" \ +--role Contributor + +``` +For extra reference you can also take a look at the Microsoft Docs: [here](https://github.com/MicrosoftDocs/azure-docs/blob/master/articles/aks/kubernetes-service-principal.md)
+ +# Generate SSH key + +``` +ssh-keygen -t rsa -b 4096 -N "VeryStrongSecret123!" -C "your_email@example.com" -q -f ~/.ssh/id_rsa +SSH_KEY=$(cat ~/.ssh/id_rsa.pub) +``` + +## Terraform Azure Kubernetes Provider + +Documentation on all the Kubernetes fields for terraform [here](https://www.terraform.io/docs/providers/azurerm/r/kubernetes_cluster.html) + +``` +terraform plan -var serviceprinciple_id=$SERVICE_PRINCIPAL -var serviceprinciple_key="$SERVICE_PRINCIPAL_SECRET" -var ssh_key="$SSH_KEY" + +# Import existing resource group +terraform import -var serviceprinciple_id=$SERVICE_PRINCIPAL -var serviceprinciple_key="$SERVICE_PRINCIPAL_SECRET" -var ssh_key="$SSH_KEY" module.cluster.azurerm_resource_group.aks-getting-started $RESOURCEGROUP_ID +terraform apply -var serviceprinciple_id=$SERVICE_PRINCIPAL -var serviceprinciple_key="$SERVICE_PRINCIPAL_SECRET" -var ssh_key="$SSH_KEY" +``` \ No newline at end of file diff --git a/kubernetes/cloud/azure/terraform/variables.tf b/kubernetes/cloud/azure/terraform/variables.tf new file mode 100644 index 0000000..7261847 --- /dev/null +++ b/kubernetes/cloud/azure/terraform/variables.tf @@ -0,0 +1,16 @@ +variable "serviceprinciple_id" { +} + +variable "serviceprinciple_key" { +} + +variable "ssh_key" { +} + +variable "location" { + default = "australiaeast" +} + +variable "kubernetes_version" { + default = "1.16.10" +} \ No newline at end of file