diff --git a/20_app_gateway_ingress/aspnetapp.yaml b/20_app_gateway_ingress/aspnetapp.yaml index 290f4dd..88517be 100644 --- a/20_app_gateway_ingress/aspnetapp.yaml +++ b/20_app_gateway_ingress/aspnetapp.yaml @@ -1,50 +1,53 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: webapp + name: aspnetapp + labels: + app: aspnetapp spec: + replicas: 3 selector: matchLabels: - app: webapp - replicas: 3 + app: aspnetapp template: metadata: labels: - app: webapp + app: aspnetapp spec: containers: - - image: mcr.microsoft.com/dotnet/samples:aspnetapp - name: aspnetapp - ports: - - containerPort: 80 + - name: aspnetapp + image: mcr.microsoft.com/dotnet/samples:aspnetapp + ports: + - containerPort: 8080 + protocol: TCP --- apiVersion: v1 kind: Service metadata: - name: webapp-svc + name: aspnetapp spec: - ports: - - port: 80 - protocol: TCP - targetPort: 80 selector: - app: webapp - type: ClusterIP + app: aspnetapp + ports: + - protocol: TCP + port: 80 + targetPort: 8080 --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: - name: webapp-ingress + name: aspnetapp + # annotations: + # kubernetes.io/ingress.class: azure/application-gateway spec: ingressClassName: azure-application-gateway rules: - # - host: webapp.houssem.cloud - - http: - paths: - - path: / - pathType: Exact - backend: - service: - name: webapp-svc - port: - number: 80 \ No newline at end of file + - http: + paths: + - path: / + backend: + service: + name: aspnetapp + port: + number: 80 + pathType: Exact \ No newline at end of file diff --git a/420_pod_topology_spread_constraints/Readme.md b/420_pod_topology_spread_constraints/Readme.md new file mode 100644 index 0000000..2c05d80 --- /dev/null +++ b/420_pod_topology_spread_constraints/Readme.md @@ -0,0 +1,3 @@ +# Pod Topology Spread Constraints + +https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ \ No newline at end of file diff --git a/510_ai_ollama_k8s/webui-deployment.yaml b/510_ai_ollama_k8s/webui-deployment.yaml index 616d139..f2f9ca1 100644 --- a/510_ai_ollama_k8s/webui-deployment.yaml +++ b/510_ai_ollama_k8s/webui-deployment.yaml @@ -38,4 +38,4 @@ spec: volumes: - name: webui-volume persistentVolumeClaim: - claimName: open-webui-pvc \ No newline at end of file + claimName: open-webui-pvc \ No newline at end of file diff --git a/80_aks_backup/cmmands.ps1 b/80_aks_backup/cmmands.ps1 index e17506c..927abd9 100644 --- a/80_aks_backup/cmmands.ps1 +++ b/80_aks_backup/cmmands.ps1 @@ -16,14 +16,14 @@ $AKS_RG_02="rg-aks-2" $VAULT_NAME="backup-vault" $VAULT_RG="rg-backup-vault" -$SA_NAME="storage4aks1backup13" +$SA_NAME="storage4aks1backup17" $SA_RG="rg-backup-storage" $BLOB_CONTAINER_NAME="aks-backup" $SUBSCRIPTION_ID=$(az account list --query [?isDefault].id -o tsv) # 2. Create Backup Vault resource group and Backup Vault -az group create --name $VAULT_RG --location westeurope +az group create --name $VAULT_RG --location swedencentral az dataprotection backup-vault create ` --vault-name $VAULT_NAME ` @@ -32,7 +32,7 @@ az dataprotection backup-vault create ` # 3. Create storage acount and Blob container for storing Backup data -az group create --name $SA_RG --location westeurope +az group create --name $SA_RG --location swedencentral az storage account create ` --name $SA_NAME ` @@ -48,11 +48,11 @@ az storage container create ` # 4. Create first AKS cluster with CSI Disk Driver and Snapshot Controller -az aks get-versions -l westeurope -o table +az aks get-versions -l swedencentral -o table -az group create --name $AKS_RG_01 --location westeurope +az group create --name $AKS_RG_01 --location swedencentral -az aks create -g $AKS_RG_01 -n $AKS_NAME_01 -k "1.27.3" --zones 1 2 3 --node-vm-size "Standard_B2als_v2" +az aks create -g $AKS_RG_01 -n $AKS_NAME_01 -k "1.30.5" --zones 1 2 3 --node-vm-size "Standard_B2als_v2" # Verify that CSI Disk Driver and Snapshot Controller are installed @@ -63,9 +63,9 @@ az aks show -g $AKS_RG_01 -n $AKS_NAME_01 --query storageProfile # 5. Create second AKS cluster with CSI Disk Driver and Snapshot Controller -az group create --name $AKS_RG_02 --location westeurope +az group create --name $AKS_RG_02 --location swedencentral -az aks create -g $AKS_RG_02 -n $AKS_NAME_02 -k "1.27.3" --zones 1 2 3 --node-vm-size "Standard_B2als_v2" +az aks create -g $AKS_RG_02 -n $AKS_NAME_02 -k "1.30.5" --zones 1 2 3 --node-vm-size "Standard_B2als_v2" # Verify that CSI Disk Driver and Snapshot Controller are installed diff --git a/80_aks_backup_tf/Readme.md b/80_aks_backup_tf/Readme.md index 7fcc9e0..f74c7c7 100644 --- a/80_aks_backup_tf/Readme.md +++ b/80_aks_backup_tf/Readme.md @@ -1,12 +1,7 @@ -# Private Azure Grafana, Prometheus and Log Analytics with AKS +# AKS Backup with Terraform and Velero ## Introduction -With AKS, you can use `Azure Monitor Workspace for Prometheus` and `Azure Managed Grafana` to collect, query and visualize the metrics from AKS. -And to collect logs, you can use `Azure Log Analytics`. - -This lab will provide an implementation for monitoring and logging. - ## Architecture ![](images/architecture.png) @@ -37,4 +32,4 @@ terraform destroy ## More readings -https://learn.microsoft.com/en-us/azure/azure-monitor/essentials/azure-monitor-workspace-manage?tabs=azure-portal +https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/data_protection_backup_instance_kubernetes_cluster diff --git a/80_aks_backup_tf/aks-2.tf b/80_aks_backup_tf/aks-2.tf new file mode 100644 index 0000000..919f901 --- /dev/null +++ b/80_aks_backup_tf/aks-2.tf @@ -0,0 +1,70 @@ +resource "azurerm_kubernetes_cluster" "aks-2" { + name = "aks-cluster" + location = azurerm_resource_group.rg-2.location + resource_group_name = azurerm_resource_group.rg-2.name + dns_prefix = "aks" + kubernetes_version = "1.30.5" + + network_profile { + network_plugin = "azure" + network_plugin_mode = "overlay" + } + + default_node_pool { + name = "systempool" + temporary_name_for_rotation = "syspool" + node_count = 3 + vm_size = "standard_b2als_v2" + zones = [1, 2, 3] + } + + identity { + type = "SystemAssigned" + } + + lifecycle { + ignore_changes = [ + default_node_pool.0.upgrade_settings + ] + } +} + +resource "azurerm_role_assignment" "cluster_2_msi_contributor_on_snap_rg" { + scope = azurerm_resource_group.rg-backup.id + role_definition_name = "Contributor" + principal_id = azurerm_kubernetes_cluster.aks-2.identity[0].principal_id +} + +resource "azurerm_kubernetes_cluster_extension" "extension-2" { + name = "backup-extension" + cluster_id = azurerm_kubernetes_cluster.aks-2.id + extension_type = "Microsoft.DataProtection.Kubernetes" + release_train = "stable" + release_namespace = "dataprotection-microsoft" + configuration_settings = { + "configuration.backupStorageLocation.bucket" = azurerm_storage_container.container.name + "configuration.backupStorageLocation.config.storageAccount" = azurerm_storage_account.storage.name + "configuration.backupStorageLocation.config.resourceGroup" = azurerm_storage_account.storage.resource_group_name + "configuration.backupStorageLocation.config.subscriptionId" = data.azurerm_client_config.current.subscription_id + "credentials.tenantId" = data.azurerm_client_config.current.tenant_id + } +} + +resource "azurerm_role_assignment" "extension_2_storage_account_contributor" { + scope = azurerm_storage_account.storage.id + role_definition_name = "Storage Account Contributor" + principal_id = azurerm_kubernetes_cluster_extension.extension-2.aks_assigned_identity[0].principal_id +} + +resource "azurerm_kubernetes_cluster_trusted_access_role_binding" "aks_cluster_2_trusted_access" { + kubernetes_cluster_id = azurerm_kubernetes_cluster.aks-2.id + name = "trusted-access" + roles = ["Microsoft.DataProtection/backupVaults/backup-operator"] + source_resource_id = azurerm_data_protection_backup_vault.backup-vault.id +} + +resource "azurerm_role_assignment" "vault_msi_read_on_cluster_2" { + scope = azurerm_kubernetes_cluster.aks-2.id + role_definition_name = "Reader" + principal_id = azurerm_data_protection_backup_vault.backup-vault.identity[0].principal_id +} \ No newline at end of file diff --git a/80_aks_backup_tf/aks-backup-extenstion.tf b/80_aks_backup_tf/aks-backup-extenstion.tf index f2793b7..acaa36f 100644 --- a/80_aks_backup_tf/aks-backup-extenstion.tf +++ b/80_aks_backup_tf/aks-backup-extenstion.tf @@ -6,14 +6,14 @@ resource "azurerm_kubernetes_cluster_extension" "extension" { release_namespace = "dataprotection-microsoft" configuration_settings = { "configuration.backupStorageLocation.bucket" = azurerm_storage_container.container.name - "configuration.backupStorageLocation.config.resourceGroup" = azurerm_storage_account.storage.resource_group_name "configuration.backupStorageLocation.config.storageAccount" = azurerm_storage_account.storage.name + "configuration.backupStorageLocation.config.resourceGroup" = azurerm_storage_account.storage.resource_group_name "configuration.backupStorageLocation.config.subscriptionId" = data.azurerm_client_config.current.subscription_id "credentials.tenantId" = data.azurerm_client_config.current.tenant_id } } -resource "azurerm_role_assignment" "extension_and_storage_account_permission" { +resource "azurerm_role_assignment" "extension_storage_account_contributor" { scope = azurerm_storage_account.storage.id role_definition_name = "Storage Account Contributor" principal_id = azurerm_kubernetes_cluster_extension.extension.aks_assigned_identity[0].principal_id diff --git a/80_aks_backup_tf/aks.tf b/80_aks_backup_tf/aks.tf index 5e30630..3c2ccbd 100644 --- a/80_aks_backup_tf/aks.tf +++ b/80_aks_backup_tf/aks.tf @@ -3,27 +3,34 @@ resource "azurerm_kubernetes_cluster" "aks" { location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name dns_prefix = "aks" - kubernetes_version = "1.29.0" + kubernetes_version = "1.30.5" network_profile { network_plugin = "azure" network_plugin_mode = "overlay" - ebpf_data_plane = "cilium" } default_node_pool { - name = "systempool" - node_count = 3 - vm_size = "standard_b2als_v2" + name = "systempool" + temporary_name_for_rotation = "syspool" + node_count = 3 + vm_size = "standard_b2als_v2" + zones = [1, 2, 3] } identity { type = "SystemAssigned" } + + lifecycle { + ignore_changes = [ + default_node_pool.0.upgrade_settings + ] + } } resource "azurerm_role_assignment" "cluster_msi_contributor_on_snap_rg" { scope = azurerm_resource_group.rg-backup.id role_definition_name = "Contributor" principal_id = azurerm_kubernetes_cluster.aks.identity[0].principal_id -} \ No newline at end of file +} diff --git a/80_aks_backup_tf/backup_instance.tf b/80_aks_backup_tf/backup_instance.tf index 0b390f7..576a284 100644 --- a/80_aks_backup_tf/backup_instance.tf +++ b/80_aks_backup_tf/backup_instance.tf @@ -1,22 +1,28 @@ -resource "azurerm_data_protection_backup_instance_kubernetes_cluster" "backup-instance" { - name = "backup-instance" +resource "azurerm_data_protection_backup_instance_kubernetes_cluster" "backup_instance_aks" { + name = "backup-instance-aks" location = azurerm_resource_group.rg.location vault_id = azurerm_data_protection_backup_vault.backup-vault.id kubernetes_cluster_id = azurerm_kubernetes_cluster.aks.id snapshot_resource_group_name = azurerm_resource_group.rg-backup.name - backup_policy_id = azurerm_data_protection_backup_policy_kubernetes_cluster.backup-policy-aks.id + backup_policy_id = azurerm_data_protection_backup_policy_kubernetes_cluster.backup_policy_aks.id backup_datasource_parameters { - excluded_namespaces = ["test-excluded-namespaces"] - excluded_resource_types = ["exvolumesnapshotcontents.snapshot.storage.k8s.io"] + # excluded_namespaces = ["ns1"] + # excluded_resource_types = ["exvolumesnapshotcontents.snapshot.storage.k8s.io"] cluster_scoped_resources_enabled = true - included_namespaces = ["*"] # ["test-included-namespaces"] - included_resource_types = ["*"] # ["involumesnapshotcontents.snapshot.storage.k8s.io"] - label_selectors = ["*"] # ["kubernetes.io/metadata.name:test"] - volume_snapshot_enabled = true + # included_namespaces = ["*"] # ["test-included-namespaces"] + # included_resource_types = ["*"] # ["involumesnapshotcontents.snapshot.storage.k8s.io"] + # label_selectors = ["*"] # ["kubernetes.io/metadata.name:test"] + volume_snapshot_enabled = true } depends_on = [ - azurerm_role_assignment.extension_and_storage_account_permission, + azurerm_role_assignment.extension_storage_account_contributor, + azurerm_role_assignment.vault_msi_read_on_cluster, + azurerm_role_assignment.vault_msi_read_on_snap_rg, + azurerm_role_assignment.cluster_msi_contributor_on_snap_rg, + azurerm_role_assignment.vault_msi_snapshot_contributor_on_snap_rg, + azurerm_role_assignment.vault_msi_data_operator_on_snap_rg, + azurerm_role_assignment.vault_msi_data_contributor_on_storage, ] -} \ No newline at end of file +} diff --git a/80_aks_backup_tf/backup_policy.tf b/80_aks_backup_tf/backup_policy.tf index 50e7162..1486530 100644 --- a/80_aks_backup_tf/backup_policy.tf +++ b/80_aks_backup_tf/backup_policy.tf @@ -1,4 +1,4 @@ -resource "azurerm_data_protection_backup_policy_kubernetes_cluster" "backup-policy-aks" { +resource "azurerm_data_protection_backup_policy_kubernetes_cluster" "backup_policy_aks" { name = "backup-policy-aks" resource_group_name = azurerm_data_protection_backup_vault.backup-vault.resource_group_name vault_name = azurerm_data_protection_backup_vault.backup-vault.name diff --git a/80_aks_backup_tf/backup_vault.tf b/80_aks_backup_tf/backup_vault.tf index 77bf993..e0cb96e 100644 --- a/80_aks_backup_tf/backup_vault.tf +++ b/80_aks_backup_tf/backup_vault.tf @@ -1,9 +1,12 @@ resource "azurerm_data_protection_backup_vault" "backup-vault" { - name = "backup-vault" - resource_group_name = azurerm_resource_group.rg.name - location = azurerm_resource_group.rg.location - datastore_type = "VaultStore" - redundancy = "LocallyRedundant" + name = "backup-vault" + resource_group_name = azurerm_resource_group.rg.name + location = azurerm_resource_group.rg.location + datastore_type = "VaultStore" + redundancy = "LocallyRedundant" # `GeoRedundant` + # cross_region_restore_enabled = "false" # can only be specified when `redundancy` is specified for `GeoRedundant` + soft_delete = "Off" + retention_duration_in_days = 14 identity { type = "SystemAssigned" @@ -20,4 +23,22 @@ resource "azurerm_role_assignment" "vault_msi_read_on_snap_rg" { scope = azurerm_resource_group.rg-backup.id role_definition_name = "Reader" principal_id = azurerm_data_protection_backup_vault.backup-vault.identity[0].principal_id -} \ No newline at end of file +} + +resource "azurerm_role_assignment" "vault_msi_snapshot_contributor_on_snap_rg" { + scope = azurerm_resource_group.rg-backup.id + role_definition_name = "Disk Snapshot Contributor" + principal_id = azurerm_data_protection_backup_vault.backup-vault.identity[0].principal_id +} + +resource "azurerm_role_assignment" "vault_msi_data_operator_on_snap_rg" { + scope = azurerm_resource_group.rg-backup.id + role_definition_name = "Data Operator for Managed Disks" + principal_id = azurerm_data_protection_backup_vault.backup-vault.identity[0].principal_id +} + +resource "azurerm_role_assignment" "vault_msi_data_contributor_on_storage" { + scope = azurerm_storage_account.storage.id + role_definition_name = "Storage Blob Data Contributor" + principal_id = azurerm_data_protection_backup_vault.backup-vault.identity[0].principal_id +} diff --git a/80_aks_backup_tf/deploy_disk_lrs.yaml b/80_aks_backup_tf/deploy_disk_lrs.yaml new file mode 100644 index 0000000..b74492e --- /dev/null +++ b/80_aks_backup_tf/deploy_disk_lrs.yaml @@ -0,0 +1,39 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx-lrs +spec: + selector: + matchLabels: + app: nginx-lrs + template: + metadata: + labels: + app: nginx-lrs + spec: + containers: + - name: nginx + image: nginx + command: + - "/bin/sh" + - "-c" + - while true; do echo $(date) >> /mnt/azuredisk/outfile; sleep 60; done + volumeMounts: + - name: azuredisk-lrs + mountPath: "/mnt/azuredisk" + volumes: + - name: azuredisk-lrs + persistentVolumeClaim: + claimName: azure-managed-disk-lrs +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: azure-managed-disk-lrs +spec: + accessModes: + - ReadWriteOnce + storageClassName: managed-csi + resources: + requests: + storage: 5Gi \ No newline at end of file diff --git a/80_aks_backup_tf/deploy_disk_zrs_sc.yaml b/80_aks_backup_tf/deploy_disk_zrs_sc.yaml new file mode 100644 index 0000000..81dbee7 --- /dev/null +++ b/80_aks_backup_tf/deploy_disk_zrs_sc.yaml @@ -0,0 +1,50 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx-zrs +spec: + selector: + matchLabels: + app: nginx-zrs + template: + metadata: + labels: + app: nginx-zrs + spec: + containers: + - name: nginx + image: nginx + command: + - "/bin/sh" + - "-c" + - while true; do echo $(date) >> /mnt/azuredisk/outfile; sleep 60; done + volumeMounts: + - name: azuredisk-zrs + mountPath: "/mnt/azuredisk" + volumes: + - name: azuredisk-zrs + persistentVolumeClaim: + claimName: azure-managed-disk-zrs +--- +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: managed-csi-zrs +parameters: + skuname: StandardSSD_ZRS +provisioner: disk.csi.azure.com +reclaimPolicy: Delete +volumeBindingMode: WaitForFirstConsumer +allowVolumeExpansion: true +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: azure-managed-disk-zrs +spec: + accessModes: + - ReadWriteOnce + storageClassName: managed-csi-zrs + resources: + requests: + storage: 5Gi \ No newline at end of file diff --git a/80_aks_backup_tf/providers.tf b/80_aks_backup_tf/providers.tf index 9f4bf2a..efbeea4 100644 --- a/80_aks_backup_tf/providers.tf +++ b/80_aks_backup_tf/providers.tf @@ -6,7 +6,7 @@ terraform { azurerm = { source = "hashicorp/azurerm" - version = "= 3.95.0" + version = "= 4.6.0" } time = { @@ -17,6 +17,7 @@ terraform { } provider "azurerm" { + subscription_id = "dcef7009-6b94-4382-afdc-17eb160d709a" features {} } diff --git a/80_aks_backup_tf/rg.tf b/80_aks_backup_tf/rg.tf index db048fa..48f5e14 100644 --- a/80_aks_backup_tf/rg.tf +++ b/80_aks_backup_tf/rg.tf @@ -1,9 +1,14 @@ resource "azurerm_resource_group" "rg" { - name = "rg-akscluster-${var.prefix}" + name = "rg-aks-${var.prefix}" location = var.location } resource "azurerm_resource_group" "rg-backup" { name = "rg-aks-backup-${var.prefix}" location = var.location +} + +resource "azurerm_resource_group" "rg-2" { + name = "rg-aks-2-${var.prefix}" + location = var.location } \ No newline at end of file diff --git a/80_aks_backup_tf/storage_account.tf b/80_aks_backup_tf/storage_account.tf index 4caaf58..9b14f74 100644 --- a/80_aks_backup_tf/storage_account.tf +++ b/80_aks_backup_tf/storage_account.tf @@ -1,13 +1,14 @@ resource "azurerm_storage_account" "storage" { - name = "storage19753" - resource_group_name = azurerm_resource_group.rg.name - location = azurerm_resource_group.rg.location - account_tier = "Standard" - account_replication_type = "LRS" + name = "storage19753" + resource_group_name = azurerm_resource_group.rg-backup.name + location = azurerm_resource_group.rg-backup.location + account_tier = "Standard" + account_replication_type = "LRS" + cross_tenant_replication_enabled = true } resource "azurerm_storage_container" "container" { name = "backup-container" storage_account_name = azurerm_storage_account.storage.name container_access_type = "private" -} \ No newline at end of file +} diff --git a/80_aks_backup_tf/variables.tf b/80_aks_backup_tf/variables.tf index 462f1c9..27560f5 100644 --- a/80_aks_backup_tf/variables.tf +++ b/80_aks_backup_tf/variables.tf @@ -1,5 +1,5 @@ variable "prefix" { - default = "80" + default = "80-dev" } variable "location" { diff --git a/_550_aks_container_storage/acstor-pod.yaml b/_550_aks_container_storage/acstor-pod.yaml new file mode 100644 index 0000000..922e64f --- /dev/null +++ b/_550_aks_container_storage/acstor-pod.yaml @@ -0,0 +1,29 @@ +kind: Pod +apiVersion: v1 +metadata: + name: fiopod +spec: + nodeSelector: + acstor.azure.com/io-engine: acstor + containers: + - name: fio + image: nixery.dev/shell/fio + args: + - sleep + - "1000000" + volumeMounts: + - mountPath: "/volume" + name: ephemeralvolume + volumes: + - name: ephemeralvolume + ephemeral: + volumeClaimTemplate: + metadata: + labels: + type: my-ephemeral-volume + spec: + accessModes: [ "ReadWriteOnce" ] + storageClassName: acstor-ephemeraldisk-nvme # replace with the name of your storage class if different + resources: + requests: + storage: 1Gi \ No newline at end of file diff --git a/_550_aks_container_storage/aks.tf b/_550_aks_container_storage/aks.tf new file mode 100644 index 0000000..de24534 --- /dev/null +++ b/_550_aks_container_storage/aks.tf @@ -0,0 +1,61 @@ +resource "azurerm_kubernetes_cluster" "aks" { + name = "aks-cluster" + resource_group_name = azurerm_resource_group.rg.name + location = azurerm_resource_group.rg.location + kubernetes_version = "1.30.5" + dns_prefix = "aks" + private_cluster_enabled = false + + + network_profile { + network_plugin = "azure" + network_plugin_mode = "overlay" + } + + default_node_pool { + name = "systempool" + temporary_name_for_rotation = "syspool" + vm_size = "standard_l8s_v3" # "Standard_D4s_v5" + node_count = 3 + zones = [1, 2, 3] + vnet_subnet_id = azurerm_subnet.snet-aks.id + } + + identity { + type = "SystemAssigned" + } + + storage_profile { + blob_driver_enabled = true + disk_driver_enabled = true + file_driver_enabled = true + snapshot_controller_enabled = true + } + + lifecycle { + ignore_changes = [ + default_node_pool[0].upgrade_settings + ] + } +} + +resource "terraform_data" "aks-get-crdentials" { + triggers_replace = [ + azurerm_kubernetes_cluster.aks.id + ] + + provisioner "local-exec" { + command = "az aks get-credentials --resource-group ${azurerm_resource_group.rg.name} --name ${azurerm_kubernetes_cluster.aks.name} --overwrite-existing" + } +} + +resource "terraform_data" "enable-aks-container-storage" { + triggers_replace = [ + azurerm_kubernetes_cluster.aks.id + ] + + provisioner "local-exec" { + command = "az aks update --resource-group ${azurerm_resource_group.rg.name} --name ${azurerm_kubernetes_cluster.aks.name} --enable-azure-container-storage ephemeralDisk --storage-pool-option NVMe" # azureDisk, ephemeralDisk, or elasticSan. NVMe, Temp, all + } +} + diff --git a/_550_aks_container_storage/provider.tf b/_550_aks_container_storage/provider.tf new file mode 100644 index 0000000..7317f2f --- /dev/null +++ b/_550_aks_container_storage/provider.tf @@ -0,0 +1,13 @@ +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "4.6.0" + } + } +} + +provider "azurerm" { + subscription_id = "dcef7009-6b94-4382-afdc-17eb160d709a" + features {} +} diff --git a/_550_aks_container_storage/rg.tf b/_550_aks_container_storage/rg.tf new file mode 100644 index 0000000..e8904c2 --- /dev/null +++ b/_550_aks_container_storage/rg.tf @@ -0,0 +1,4 @@ +resource "azurerm_resource_group" "rg" { + name = "rg-aks-550-container-storage" + location = "swedencentral" +} \ No newline at end of file diff --git a/_550_aks_container_storage/storagepool.yaml b/_550_aks_container_storage/storagepool.yaml new file mode 100644 index 0000000..649051c --- /dev/null +++ b/_550_aks_container_storage/storagepool.yaml @@ -0,0 +1,9 @@ +apiVersion: containerstorage.azure.com/v1 +kind: StoragePool +metadata: + name: ephemeraldisk-nvme + namespace: acstor +spec: + poolType: + ephemeralDisk: + diskType: nvme \ No newline at end of file diff --git a/_550_aks_container_storage/vnet.tf b/_550_aks_container_storage/vnet.tf new file mode 100644 index 0000000..865d38f --- /dev/null +++ b/_550_aks_container_storage/vnet.tf @@ -0,0 +1,28 @@ +resource "azurerm_virtual_network" "vnet-aks" { + name = "vnet-aks" + location = azurerm_resource_group.rg.location + resource_group_name = azurerm_resource_group.rg.name + address_space = ["10.224.0.0/22"] +} + +resource "azurerm_subnet" "snet-aks" { + name = "snet-aks" + virtual_network_name = azurerm_virtual_network.vnet-aks.name + resource_group_name = azurerm_virtual_network.vnet-aks.resource_group_name + address_prefixes = ["10.224.0.0/24"] +} + +resource "azurerm_subnet" "snet-acr" { + name = "snet-acr" + virtual_network_name = azurerm_virtual_network.vnet-aks.name + resource_group_name = azurerm_virtual_network.vnet-aks.resource_group_name + address_prefixes = ["10.224.1.0/24"] +} + +resource "azurerm_subnet" "snet-bastion" { + name = "AzureBastionSubnet" + virtual_network_name = azurerm_virtual_network.vnet-aks.name + resource_group_name = azurerm_virtual_network.vnet-aks.resource_group_name + address_prefixes = ["10.224.2.0/24"] +} + diff --git a/__411_acr_cache/acr.tf b/__411_acr_cache/acr.tf new file mode 100644 index 0000000..8454ead --- /dev/null +++ b/__411_acr_cache/acr.tf @@ -0,0 +1,50 @@ +resource "azurerm_container_registry" "acr" { + name = "acr4aks4dev" + resource_group_name = azurerm_resource_group.rg.name + location = azurerm_resource_group.rg.location + sku = "Premium" + admin_enabled = false + public_network_access_enabled = true + zone_redundancy_enabled = false + anonymous_pull_enabled = false + data_endpoint_enabled = false + network_rule_bypass_option = "AzureServices" + + georeplications { + location = "westeurope" + zone_redundancy_enabled = true + tags = {} + } + + # georeplications { + # location = "northeurope" + # zone_redundancy_enabled = true + # tags = {} + # } + + network_rule_set { + default_action = "Deny" + + ip_rule { + action = "Allow" + ip_range = "176.177.25.47/32" + } + } +} + +resource "terraform_data" "acr_import_app1" { + triggers_replace = [ + azurerm_container_registry.acr.id + ] + + provisioner "local-exec" { + command = "az acr import --name ${azurerm_container_registry.acr.name} --source ghcr.io/jelledruyts/inspectorgadget:latest --image team1/app1:v1" + } +} + +# resource "azurerm_role_assignment" "acrpull" { +# principal_id = azurerm_kubernetes_cluster.aks.kubelet_identity[0].object_id +# role_definition_name = "AcrPull" +# scope = azurerm_container_registry.acr.id +# skip_service_principal_aad_check = true +# } \ No newline at end of file diff --git a/__411_acr_cache/acr_agent_pool.tf b/__411_acr_cache/acr_agent_pool.tf new file mode 100644 index 0000000..028426a --- /dev/null +++ b/__411_acr_cache/acr_agent_pool.tf @@ -0,0 +1,9 @@ +# resource "azurerm_container_registry_agent_pool" "acr-agentpool" { +# name = "acr-agentpool" +# resource_group_name = azurerm_resource_group.rg.name +# location = "westeurope" # azurerm_resource_group.rg.location # List of available regions for the resource type is 'eastus,westeurope,westus2,southcentralus,canadacentral,centralus,eastasia,eastus2,northeurope,switzerlandnorth' +# container_registry_name = azurerm_container_registry.acr.name +# instance_count = 1 +# tier = "S1" # S1 (2 vCPUs, 3 GiB RAM), S2 (4 vCPUs, 8 GiB RAM), S3 (8 vCPUs, 16 GiB RAM) or I6 (64 vCPUs, 216 GiB RAM, Isolated). +# virtual_network_subnet_id = azurerm_subnet.snet-acr.id +# } diff --git a/__411_acr_cache/acr_cache_rule.tf b/__411_acr_cache/acr_cache_rule.tf new file mode 100644 index 0000000..b9f8ec0 --- /dev/null +++ b/__411_acr_cache/acr_cache_rule.tf @@ -0,0 +1,7 @@ +# resource "azurerm_container_registry_cache_rule" "cache_rule" { +# name = "cacherule" +# container_registry_id = azurerm_container_registry.acr.id +# target_repo = "target" +# source_repo = "docker.io/hello-world" +# credential_set_id = "${azurerm_container_registry.acr.id}/credentialSets/example" +# } \ No newline at end of file diff --git a/__411_acr_cache/acr_pe.tf b/__411_acr_cache/acr_pe.tf new file mode 100644 index 0000000..8a7b04f --- /dev/null +++ b/__411_acr_cache/acr_pe.tf @@ -0,0 +1,30 @@ +# resource "azurerm_private_endpoint" "pe-acr" { +# name = "pe-acr" +# location = azurerm_resource_group.rg.location +# resource_group_name = azurerm_resource_group.rg.name +# subnet_id = azurerm_subnet.snet-acr.id + +# private_service_connection { +# name = "connection-acr" +# private_connection_resource_id = azurerm_container_registry.acr.id +# is_manual_connection = false +# subresource_names = ["registry"] +# } + +# private_dns_zone_group { +# name = "private-dns-zone-group-acr" +# private_dns_zone_ids = [azurerm_private_dns_zone.private-dns-zone-acr.id] +# } +# } + +# resource "azurerm_private_dns_zone" "private-dns-zone-acr" { +# name = "privatelink.azurecr.io" +# resource_group_name = azurerm_resource_group.rg.name +# } + +# resource "azurerm_private_dns_zone_virtual_network_link" "link-dns-vnet" { +# name = "link-dns-vnet" +# private_dns_zone_name = azurerm_private_dns_zone.private-dns-zone-acr.name +# resource_group_name = azurerm_private_dns_zone.private-dns-zone-acr.resource_group_name +# virtual_network_id = azurerm_virtual_network.vnet-aks.id +# } \ No newline at end of file diff --git a/__411_acr_cache/aks.tf b/__411_acr_cache/aks.tf new file mode 100644 index 0000000..f007912 --- /dev/null +++ b/__411_acr_cache/aks.tf @@ -0,0 +1,47 @@ +# resource "azurerm_kubernetes_cluster" "aks" { +# name = "aks-cluster" +# resource_group_name = azurerm_resource_group.rg.name +# location = azurerm_resource_group.rg.location +# kubernetes_version = "1.30.4" +# dns_prefix = "aks" +# private_cluster_enabled = false + +# network_profile { +# network_plugin = "azure" +# network_plugin_mode = "overlay" +# } + +# default_node_pool { +# name = "systempool" +# vm_size = "Standard_D2s_v2" +# node_count = 3 +# zones = [2, 3] # [1, 2, 3] +# vnet_subnet_id = azurerm_subnet.snet-aks.id +# } + +# identity { +# type = "SystemAssigned" +# } + +# # kubelet_identity { +# # client_id = azurerm_user_assigned_identity.identity-kubelet.client_id +# # object_id = azurerm_user_assigned_identity.identity-kubelet.principal_id # there is no object_id +# # user_assigned_identity_id = azurerm_user_assigned_identity.identity-kubelet.id +# # } + +# lifecycle { +# ignore_changes = [ +# default_node_pool[0].upgrade_settings +# ] +# } +# } + +# resource "terraform_data" "aks-get-crdentials" { +# triggers_replace = [ +# azurerm_kubernetes_cluster.aks.id +# ] + +# provisioner "local-exec" { +# command = "az aks get-credentials --resource-group ${azurerm_resource_group.rg.name} --name ${azurerm_kubernetes_cluster.aks.name} --overwrite-existing" +# } +# } diff --git a/__411_acr_cache/bastion.tf b/__411_acr_cache/bastion.tf new file mode 100644 index 0000000..b367d8a --- /dev/null +++ b/__411_acr_cache/bastion.tf @@ -0,0 +1,25 @@ +resource "azurerm_public_ip" "pip-bastion" { + name = "pip-bastion" + resource_group_name = azurerm_resource_group.rg.name + location = azurerm_resource_group.rg.location + allocation_method = "Static" + sku = "Standard" +} + +resource "azurerm_bastion_host" "bastion" { + name = "bastion" + resource_group_name = azurerm_resource_group.rg.name + location = azurerm_resource_group.rg.location + sku = "Standard" # "Standard" # "Basic", "Developer" + copy_paste_enabled = true + file_copy_enabled = false + shareable_link_enabled = false + tunneling_enabled = true + ip_connect_enabled = false + + ip_configuration { + name = "configuration" + subnet_id = azurerm_subnet.snet-bastion.id + public_ip_address_id = azurerm_public_ip.pip-bastion.id + } +} \ No newline at end of file diff --git a/__411_acr_cache/identity-vm.tf b/__411_acr_cache/identity-vm.tf new file mode 100644 index 0000000..3bff6e2 --- /dev/null +++ b/__411_acr_cache/identity-vm.tf @@ -0,0 +1,13 @@ +resource "azurerm_user_assigned_identity" "identity-vm" { + name = "identity-vm" + resource_group_name = azurerm_resource_group.rg.name + location = azurerm_resource_group.rg.location +} + +resource "azurerm_role_assignment" "vm-contributor" { + scope = data.azurerm_subscription.current.id + role_definition_name = "Contributor" + principal_id = azurerm_user_assigned_identity.identity-vm.principal_id +} + +data "azurerm_subscription" "current" {} \ No newline at end of file diff --git a/__411_acr_cache/install-tools.sh b/__411_acr_cache/install-tools.sh new file mode 100644 index 0000000..5ab52cd --- /dev/null +++ b/__411_acr_cache/install-tools.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +sudo apt -qq update + +# install Azure CLI +curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash + +# install Kubectl CLI +snap install kubectl --classic + +# login to Azure using VM's Managed Identity +# az login --identity + +# az aks list -o table + +# az aks get-credentials -g rg-private-aks-bastion-260 -n aks-private-260 + +# kubectl get nodes \ No newline at end of file diff --git a/__411_acr_cache/provider.tf b/__411_acr_cache/provider.tf new file mode 100644 index 0000000..3442539 --- /dev/null +++ b/__411_acr_cache/provider.tf @@ -0,0 +1,13 @@ +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "4.5.0" + } + } +} + +provider "azurerm" { + subscription_id = "dcef7009-6b94-4382-afdc-17eb160d709a" + features {} +} diff --git a/__411_acr_cache/rg.tf b/__411_acr_cache/rg.tf new file mode 100644 index 0000000..5b71a0b --- /dev/null +++ b/__411_acr_cache/rg.tf @@ -0,0 +1,4 @@ +resource "azurerm_resource_group" "rg" { + name = "rg-acr-aks-411-swc" + location = "swedencentral" +} \ No newline at end of file diff --git a/__411_acr_cache/vm-linux-jumpbox.tf b/__411_acr_cache/vm-linux-jumpbox.tf new file mode 100644 index 0000000..d74cbdc --- /dev/null +++ b/__411_acr_cache/vm-linux-jumpbox.tf @@ -0,0 +1,49 @@ +resource "azurerm_network_interface" "nic-vm" { + name = "nic-vm" + resource_group_name = azurerm_resource_group.rg.name + location = azurerm_resource_group.rg.location + + ip_configuration { + name = "internal" + subnet_id = azurerm_subnet.snet-acr.id + private_ip_address_allocation = "Dynamic" + public_ip_address_id = null + } +} + +resource "azurerm_linux_virtual_machine" "vm-linux" { + name = "vm-linux-jumpbox" + resource_group_name = azurerm_resource_group.rg.name + location = azurerm_resource_group.rg.location + size = "Standard_B2ats_v2" + disable_password_authentication = false + admin_username = "azureuser" + admin_password = "@Aa123456789" + network_interface_ids = [azurerm_network_interface.nic-vm.id] + priority = "Spot" + eviction_policy = "Deallocate" + + custom_data = filebase64("./install-tools.sh") + + identity { + type = "UserAssigned" + identity_ids = [azurerm_user_assigned_identity.identity-vm.id] + } + + os_disk { + name = "os-disk-vm" + caching = "ReadWrite" + storage_account_type = "Standard_LRS" + } + + source_image_reference { + publisher = "canonical" + offer = "0001-com-ubuntu-server-jammy" + sku = "22_04-lts-gen2" + version = "latest" + } + + boot_diagnostics { + storage_account_uri = null + } +} \ No newline at end of file diff --git a/__411_acr_cache/vnet.tf b/__411_acr_cache/vnet.tf new file mode 100644 index 0000000..865d38f --- /dev/null +++ b/__411_acr_cache/vnet.tf @@ -0,0 +1,28 @@ +resource "azurerm_virtual_network" "vnet-aks" { + name = "vnet-aks" + location = azurerm_resource_group.rg.location + resource_group_name = azurerm_resource_group.rg.name + address_space = ["10.224.0.0/22"] +} + +resource "azurerm_subnet" "snet-aks" { + name = "snet-aks" + virtual_network_name = azurerm_virtual_network.vnet-aks.name + resource_group_name = azurerm_virtual_network.vnet-aks.resource_group_name + address_prefixes = ["10.224.0.0/24"] +} + +resource "azurerm_subnet" "snet-acr" { + name = "snet-acr" + virtual_network_name = azurerm_virtual_network.vnet-aks.name + resource_group_name = azurerm_virtual_network.vnet-aks.resource_group_name + address_prefixes = ["10.224.1.0/24"] +} + +resource "azurerm_subnet" "snet-bastion" { + name = "AzureBastionSubnet" + virtual_network_name = azurerm_virtual_network.vnet-aks.name + resource_group_name = azurerm_virtual_network.vnet-aks.resource_group_name + address_prefixes = ["10.224.2.0/24"] +} +