diff --git a/quickstart/101-attestation-provider/main.tf b/quickstart/101-attestation-provider/main.tf new file mode 100644 index 00000000..123d2607 --- /dev/null +++ b/quickstart/101-attestation-provider/main.tf @@ -0,0 +1,28 @@ +terraform { + + required_version = ">=0.12" + + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "~>2.0" + } + } +} + +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "rg" { + name = var.resource_group_name + location = var.resource_group_location +} + +resource "azurerm_attestation_provider" "corpAttestation" { + name = var.attestation_provider_name + resource_group_name = azurerm_resource_group.rg.name + location = azurerm_resource_group.rg.location + + policy_signing_certificate_data = file(var.policy_file) +} \ No newline at end of file diff --git a/quickstart/101-attestation-provider/variables.tf b/quickstart/101-attestation-provider/variables.tf new file mode 100644 index 00000000..2fbd8523 --- /dev/null +++ b/quickstart/101-attestation-provider/variables.tf @@ -0,0 +1,15 @@ +variable "resource_group_name" { + default = "myResourceGroup" +} + +variable "resource_group_location" { + default = "eastus" +} + +variable "policy_file" { + default = "~/.certs/cert.pem" +} + +variable "attestation_provider_name" { + default = "attestationprovider007" +} \ No newline at end of file diff --git a/quickstart/101-resource-group/main.tf b/quickstart/101-resource-group/main.tf new file mode 100644 index 00000000..00e05541 --- /dev/null +++ b/quickstart/101-resource-group/main.tf @@ -0,0 +1,20 @@ +terraform { + + required_version = ">=0.12" + + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "~>2.0" + } + } +} + +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "rg" { + name = var.resource_group_name + location = var.resource_group_location +} \ No newline at end of file diff --git a/quickstart/101-resource-group/readme.md b/quickstart/101-resource-group/readme.md new file mode 100644 index 00000000..339448e3 --- /dev/null +++ b/quickstart/101-resource-group/readme.md @@ -0,0 +1,21 @@ +# Azure resource group + +This template deploys an Azure resource group. + +## Resources + +| Terraform Resource Type | Description | +| - | - | +| `azurerm_resource_group` | The resource group all resources are deployed into | + +## Variables + +| Name | Description | +|-|-| +| `name` | Name of the deployment | +| `environment` | The depolyment environment name (used for postfixing resource names) | +| `location` | The Azure Region to deploy these resources in | + +## Example + +To see how to run this example, see [Create an Azure resource group using Terraform](https://docs.microsoft.com/azure/developer/terraform/create-resource-group). \ No newline at end of file diff --git a/quickstart/101-resource-group/variables.tf b/quickstart/101-resource-group/variables.tf new file mode 100644 index 00000000..82531797 --- /dev/null +++ b/quickstart/101-resource-group/variables.tf @@ -0,0 +1,7 @@ +variable "resource_group_name" { + default = "myResourceGroup" +} + +variable "resource_group_location" { + default = "eastus" +} diff --git a/quickstart/201-k8s-cluster-with-aks-applicationgateway-ingress/main.tf b/quickstart/201-k8s-cluster-with-aks-applicationgateway-ingress/main.tf new file mode 100644 index 00000000..4b953057 --- /dev/null +++ b/quickstart/201-k8s-cluster-with-aks-applicationgateway-ingress/main.tf @@ -0,0 +1,21 @@ +terraform { + + required_version = ">=0.12" + + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "~>2.0" + } + } + backend "azurerm" { + resource_group_name = var.resource_group_name + storage_account_name = var.storage_account_name + container_name = "tfstate" + key = "codelab.microsoft.tfstate" + } + } + + provider "azurerm" { + features {} +} diff --git a/quickstart/201-k8s-cluster-with-aks-applicationgateway-ingress/output.tf b/quickstart/201-k8s-cluster-with-aks-applicationgateway-ingress/output.tf new file mode 100644 index 00000000..6d59e7fb --- /dev/null +++ b/quickstart/201-k8s-cluster-with-aks-applicationgateway-ingress/output.tf @@ -0,0 +1,36 @@ +output "client_key" { + value = azurerm_kubernetes_cluster.k8s.kube_config.0.client_key +} + +output "client_certificate" { + value = azurerm_kubernetes_cluster.k8s.kube_config.0.client_certificate +} + +output "cluster_ca_certificate" { + value = azurerm_kubernetes_cluster.k8s.kube_config.0.cluster_ca_certificate +} + +output "cluster_username" { + value = azurerm_kubernetes_cluster.k8s.kube_config.0.username +} + +output "cluster_password" { + value = azurerm_kubernetes_cluster.k8s.kube_config.0.password +} + +output "kube_config" { + value = azurerm_kubernetes_cluster.k8s.kube_config_raw + sensitive = true +} + +output "host" { + value = azurerm_kubernetes_cluster.k8s.kube_config.0.host +} + +output "identity_resource_id" { + value = azurerm_user_assigned_identity.testIdentity.id +} + +output "identity_client_id" { + value = azurerm_user_assigned_identity.testIdentity.client_id +} diff --git a/quickstart/201-k8s-cluster-with-aks-applicationgateway-ingress/resources.tf b/quickstart/201-k8s-cluster-with-aks-applicationgateway-ingress/resources.tf new file mode 100644 index 00000000..f2ab9f0b --- /dev/null +++ b/quickstart/201-k8s-cluster-with-aks-applicationgateway-ingress/resources.tf @@ -0,0 +1,211 @@ +# # Locals block for hardcoded names. +locals { + backend_address_pool_name = "${azurerm_virtual_network.test.name}-beap" + frontend_port_name = "${azurerm_virtual_network.test.name}-feport" + frontend_ip_configuration_name = "${azurerm_virtual_network.test.name}-feip" + http_setting_name = "${azurerm_virtual_network.test.name}-be-htst" + listener_name = "${azurerm_virtual_network.test.name}-httplstn" + request_routing_rule_name = "${azurerm_virtual_network.test.name}-rqrt" + app_gateway_subnet_name = "appgwsubnet" +} + +data "azurerm_resource_group" "rg" { + name = var.resource_group_name +} + +# User Assigned Identities +resource "azurerm_user_assigned_identity" "testIdentity" { + resource_group_name = data.azurerm_resource_group.rg.name + location = data.azurerm_resource_group.rg.location + + name = "identity1" + + tags = var.tags +} + +resource "azurerm_virtual_network" "test" { + name = var.virtual_network_name + location = data.azurerm_resource_group.rg.location + resource_group_name = data.azurerm_resource_group.rg.name + address_space = [var.virtual_network_address_prefix] + + subnet { + name = var.aks_subnet_name + address_prefix = var.aks_subnet_address_prefix + } + + subnet { + name = "appgwsubnet" + address_prefix = var.app_gateway_subnet_address_prefix + } + + tags = var.tags +} + +data "azurerm_subnet" "kubesubnet" { + name = var.aks_subnet_name + virtual_network_name = azurerm_virtual_network.test.name + resource_group_name = data.azurerm_resource_group.rg.name + depends_on = [azurerm_virtual_network.test] +} + +data "azurerm_subnet" "appgwsubnet" { + name = "appgwsubnet" + virtual_network_name = azurerm_virtual_network.test.name + resource_group_name = data.azurerm_resource_group.rg.name + depends_on = [azurerm_virtual_network.test] +} + +# Public Ip +resource "azurerm_public_ip" "test" { + name = "publicIp1" + location = data.azurerm_resource_group.rg.location + resource_group_name = data.azurerm_resource_group.rg.name + allocation_method = "Static" + sku = "Standard" + + tags = var.tags +} + +resource "azurerm_application_gateway" "network" { + name = var.app_gateway_name + resource_group_name = data.azurerm_resource_group.rg.name + location = data.azurerm_resource_group.rg.location + + sku { + name = var.app_gateway_sku + tier = "Standard_v2" + capacity = 2 + } + + gateway_ip_configuration { + name = "appGatewayIpConfig" + subnet_id = data.azurerm_subnet.appgwsubnet.id + } + + frontend_port { + name = local.frontend_port_name + port = 80 + } + + frontend_port { + name = "httpsPort" + port = 443 + } + + frontend_ip_configuration { + name = local.frontend_ip_configuration_name + public_ip_address_id = azurerm_public_ip.test.id + } + + backend_address_pool { + name = local.backend_address_pool_name + } + + backend_http_settings { + name = local.http_setting_name + cookie_based_affinity = "Disabled" + port = 80 + protocol = "Http" + request_timeout = 1 + } + + http_listener { + name = local.listener_name + frontend_ip_configuration_name = local.frontend_ip_configuration_name + frontend_port_name = local.frontend_port_name + protocol = "Http" + } + + request_routing_rule { + name = local.request_routing_rule_name + rule_type = "Basic" + http_listener_name = local.listener_name + backend_address_pool_name = local.backend_address_pool_name + backend_http_settings_name = local.http_setting_name + } + + tags = var.tags + + depends_on = [azurerm_virtual_network.test, azurerm_public_ip.test] +} + +```hcl +resource "azurerm_role_assignment" "ra1" { + scope = data.azurerm_subnet.kubesubnet.id + role_definition_name = "Network Contributor" + principal_id = var.aks_service_principal_object_id + + depends_on = [azurerm_virtual_network.test] +} + +resource "azurerm_role_assignment" "ra2" { + scope = azurerm_user_assigned_identity.testIdentity.id + role_definition_name = "Managed Identity Operator" + principal_id = var.aks_service_principal_object_id + depends_on = [azurerm_user_assigned_identity.testIdentity] +} + +resource "azurerm_role_assignment" "ra3" { + scope = azurerm_application_gateway.network.id + role_definition_name = "Contributor" + principal_id = azurerm_user_assigned_identity.testIdentity.principal_id + depends_on = [azurerm_user_assigned_identity.testIdentity, azurerm_application_gateway.network] +} + +resource "azurerm_role_assignment" "ra4" { + scope = data.azurerm_resource_group.rg.id + role_definition_name = "Reader" + principal_id = azurerm_user_assigned_identity.testIdentity.principal_id + depends_on = [azurerm_user_assigned_identity.testIdentity, azurerm_application_gateway.network] +} +``` + +resource "azurerm_kubernetes_cluster" "k8s" { + name = var.aks_name + location = data.azurerm_resource_group.rg.location + dns_prefix = var.aks_dns_prefix + + resource_group_name = data.azurerm_resource_group.rg.name + + linux_profile { + admin_username = var.vm_user_name + + ssh_key { + key_data = file(var.public_ssh_key_path) + } + } + + addon_profile { + http_application_routing { + enabled = false + } + } + + default_node_pool { + name = "agentpool" + node_count = var.aks_agent_count + vm_size = var.aks_agent_vm_size + os_disk_size_gb = var.aks_agent_os_disk_size + vnet_subnet_id = data.azurerm_subnet.kubesubnet.id + } + + service_principal { + client_id = var.aks_service_principal_app_id + client_secret = var.aks_service_principal_client_secret + } + + network_profile { + network_plugin = "azure" + dns_service_ip = var.aks_dns_service_ip + docker_bridge_cidr = var.aks_docker_bridge_cidr + service_cidr = var.aks_service_cidr + } + + role_based_access_control { + enabled = var.aks_enable_rbac + } + + depends_on = [azurerm_virtual_network.test, azurerm_application_gateway.network] + tags = var.tags +} diff --git a/quickstart/201-k8s-cluster-with-aks-applicationgateway-ingress/terraform.tfvars b/quickstart/201-k8s-cluster-with-aks-applicationgateway-ingress/terraform.tfvars new file mode 100644 index 00000000..138c0712 --- /dev/null +++ b/quickstart/201-k8s-cluster-with-aks-applicationgateway-ingress/terraform.tfvars @@ -0,0 +1,9 @@ +resource_group_name = "" + +location = "" + +aks_service_principal_app_id = "" + +aks_service_principal_client_secret = "" + +aks_service_principal_object_id = "" diff --git a/quickstart/201-k8s-cluster-with-aks-applicationgateway-ingress/variables.tf b/quickstart/201-k8s-cluster-with-aks-applicationgateway-ingress/variables.tf new file mode 100644 index 00000000..db3d508e --- /dev/null +++ b/quickstart/201-k8s-cluster-with-aks-applicationgateway-ingress/variables.tf @@ -0,0 +1,130 @@ +variable "resource_group_name" { + description = "Name of the resource group." +} + +variable "location" { + description = "Location of the cluster." +} + +variable "aks_service_principal_app_id" { + description = "Application ID/Client ID of the service principal. Used by AKS to manage AKS related resources on Azure like vms, subnets." +} + +variable "aks_service_principal_client_secret" { + description = "Secret of the service principal. Used by AKS to manage Azure." +} + +variable "aks_service_principal_object_id" { + description = "Object ID of the service principal." +} + +variable "virtual_network_name" { + description = "Virtual network name" + default = "aksVirtualNetwork" +} + +variable "virtual_network_address_prefix" { + description = "VNET address prefix" + default = "15.0.0.0/8" +} + +variable "aks_subnet_name" { + description = "Subnet Name." + default = "kubesubnet" +} + +variable "aks_subnet_address_prefix" { + description = "Subnet address prefix." + default = "15.0.0.0/16" +} + +variable "app_gateway_subnet_address_prefix" { + description = "Subnet server IP address." + default = "15.1.0.0/16" +} + +variable "app_gateway_name" { + description = "Name of the Application Gateway" + default = "ApplicationGateway1" +} + +variable "app_gateway_sku" { + description = "Name of the Application Gateway SKU" + default = "Standard_v2" +} + +variable "app_gateway_tier" { + description = "Tier of the Application Gateway tier" + default = "Standard_v2" +} + +variable "aks_name" { + description = "AKS cluster name" + default = "aks-cluster1" +} +variable "aks_dns_prefix" { + description = "Optional DNS prefix to use with hosted Kubernetes API server FQDN." + default = "aks" +} + +variable "aks_agent_os_disk_size" { + description = "Disk size (in GB) to provision for each of the agent pool nodes. This value ranges from 0 to 1023. Specifying 0 applies the default disk size for that agentVMSize." + default = 40 +} + +variable "aks_agent_count" { + description = "The number of agent nodes for the cluster." + default = 3 +} + +variable "aks_agent_vm_size" { + description = "VM size" + default = "Standard_D3_v2" +} + +variable "kubernetes_version" { + description = "Kubernetes version" + default = "1.11.5" +} + +variable "aks_service_cidr" { + description = "CIDR notation IP range from which to assign service cluster IPs" + default = "10.0.0.0/16" +} + +variable "aks_dns_service_ip" { + description = "DNS server IP address" + default = "10.0.0.10" +} + +variable "aks_docker_bridge_cidr" { + description = "CIDR notation IP for Docker bridge." + default = "172.17.0.1/16" +} + +variable "aks_enable_rbac" { + description = "Enable RBAC on the AKS cluster. Defaults to false." + default = "false" +} + +variable "vm_user_name" { + description = "User name for the VM" + default = "vmuser1" +} + +variable "public_ssh_key_path" { + description = "Public key path for SSH." + default = "~/.ssh/id_rsa.pub" +} + +variable "tags" { + type = map(string) + + default = { + source = "terraform" + } +} + +variable "storage_account_name" { + description = "Name of storage account" +} diff --git a/quickstart/201-vmss-appgw-waf/readme.md b/quickstart/201-vmss-appgw-waf/readme.md index 37ca8076..d8a6486e 100644 --- a/quickstart/201-vmss-appgw-waf/readme.md +++ b/quickstart/201-vmss-appgw-waf/readme.md @@ -15,7 +15,7 @@ This template deploys a Virtual Machine Scale Set fronted by an Azure Applicatio | Name | Description | |-|-| | `name` | Name of the deployment | -| `environment` | The depolyment environment name (used for postfixing resource names) | +| `environment` | The deployment environment name (used for postfixing resource names) | | `prefix` | A prefix for globally-unique dns-based resources | | `location` | The Azure Region to deploy these resources in | diff --git a/quickstart/201-vmss-jumpbox/main.tf b/quickstart/201-vmss-jumpbox/main.tf new file mode 100644 index 00000000..15ebf449 --- /dev/null +++ b/quickstart/201-vmss-jumpbox/main.tf @@ -0,0 +1,205 @@ +terraform { + required_version = ">=0.12" + + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "~>2.0" + } + } +} + +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "vmss" { + name = var.resource_group_name + location = var.location + tags = var.tags +} + +resource "random_string" "fqdn" { + length = 6 + special = false + upper = false + number = false +} + +resource "azurerm_virtual_network" "vmss" { + name = "vmss-vnet" + address_space = ["10.0.0.0/16"] + location = var.location + resource_group_name = azurerm_resource_group.vmss.name + tags = var.tags +} + +resource "azurerm_subnet" "vmss" { + name = "vmss-subnet" + resource_group_name = azurerm_resource_group.vmss.name + virtual_network_name = azurerm_virtual_network.vmss.name + address_prefixes = ["10.0.2.0/24"] +} + +resource "azurerm_public_ip" "vmss" { + name = "vmss-public-ip" + location = var.location + resource_group_name = azurerm_resource_group.vmss.name + allocation_method = "Static" + domain_name_label = random_string.fqdn.result + tags = var.tags +} + +resource "azurerm_lb" "vmss" { + name = "vmss-lb" + location = var.location + resource_group_name = azurerm_resource_group.vmss.name + + frontend_ip_configuration { + name = "PublicIPAddress" + public_ip_address_id = azurerm_public_ip.vmss.id + } + + tags = var.tags +} + +resource "azurerm_lb_backend_address_pool" "bpepool" { + loadbalancer_id = azurerm_lb.vmss.id + name = "BackEndAddressPool" +} + +resource "azurerm_lb_probe" "vmss" { + resource_group_name = azurerm_resource_group.vmss.name + loadbalancer_id = azurerm_lb.vmss.id + name = "ssh-running-probe" + port = var.application_port +} + +resource "azurerm_lb_rule" "lbnatrule" { + resource_group_name = azurerm_resource_group.vmss.name + loadbalancer_id = azurerm_lb.vmss.id + name = "http" + protocol = "Tcp" + frontend_port = var.application_port + backend_port = var.application_port + backend_address_pool_id = azurerm_lb_backend_address_pool.bpepool.id + frontend_ip_configuration_name = "PublicIPAddress" + probe_id = azurerm_lb_probe.vmss.id +} + +resource "azurerm_virtual_machine_scale_set" "vmss" { + name = "vmscaleset" + location = var.location + resource_group_name = azurerm_resource_group.vmss.name + upgrade_policy_mode = "Manual" + + sku { + name = "Standard_DS1_v2" + tier = "Standard" + capacity = 2 + } + + storage_profile_image_reference { + publisher = "Canonical" + offer = "UbuntuServer" + sku = "16.04-LTS" + version = "latest" + } + + storage_profile_os_disk { + name = "" + caching = "ReadWrite" + create_option = "FromImage" + managed_disk_type = "Standard_LRS" + } + + storage_profile_data_disk { + lun = 0 + caching = "ReadWrite" + create_option = "Empty" + disk_size_gb = 10 + } + + os_profile { + computer_name_prefix = "vmlab" + admin_username = var.admin_user + admin_password = var.admin_password + custom_data = file("web.conf") + } + + os_profile_linux_config { + disable_password_authentication = false + } + + network_profile { + name = "terraformnetworkprofile" + primary = true + + ip_configuration { + name = "IPConfiguration" + subnet_id = azurerm_subnet.vmss.id + load_balancer_backend_address_pool_ids = [azurerm_lb_backend_address_pool.bpepool.id] + primary = true + } + } + + tags = var.tags +} + +resource "azurerm_public_ip" "jumpbox" { + name = "jumpbox-public-ip" + location = var.location + resource_group_name = azurerm_resource_group.vmss.name + allocation_method = "Static" + domain_name_label = "${random_string.fqdn.result}-ssh" + tags = var.tags +} + +resource "azurerm_network_interface" "jumpbox" { + name = "jumpbox-nic" + location = var.location + resource_group_name = azurerm_resource_group.vmss.name + + ip_configuration { + name = "IPConfiguration" + subnet_id = azurerm_subnet.vmss.id + private_ip_address_allocation = "dynamic" + public_ip_address_id = azurerm_public_ip.jumpbox.id + } + + tags = var.tags +} + +resource "azurerm_virtual_machine" "jumpbox" { + name = "jumpbox" + location = var.location + resource_group_name = azurerm_resource_group.vmss.name + network_interface_ids = [azurerm_network_interface.jumpbox.id] + vm_size = "Standard_DS1_v2" + + storage_image_reference { + publisher = "Canonical" + offer = "UbuntuServer" + sku = "16.04-LTS" + version = "latest" + } + + storage_os_disk { + name = "jumpbox-osdisk" + caching = "ReadWrite" + create_option = "FromImage" + managed_disk_type = "Standard_LRS" + } + + os_profile { + computer_name = "jumpbox" + admin_username = var.admin_user + admin_password = var.admin_password + } + + os_profile_linux_config { + disable_password_authentication = false + } + + tags = var.tags +} \ No newline at end of file diff --git a/quickstart/201-vmss-jumpbox/output.tf b/quickstart/201-vmss-jumpbox/output.tf new file mode 100644 index 00000000..deb5d5fc --- /dev/null +++ b/quickstart/201-vmss-jumpbox/output.tf @@ -0,0 +1,11 @@ +output "vmss_public_ip_fqdn" { + value = azurerm_public_ip.vmss.fqdn +} + +output "jumpbox_public_ip_fqdn" { + value = azurerm_public_ip.jumpbox.fqdn +} + +output "jumpbox_public_ip" { + value = azurerm_public_ip.jumpbox.ip_address +} diff --git a/quickstart/201-vmss-jumpbox/readme.md b/quickstart/201-vmss-jumpbox/readme.md new file mode 100644 index 00000000..df9086d3 --- /dev/null +++ b/quickstart/201-vmss-jumpbox/readme.md @@ -0,0 +1,34 @@ +# Azure virtual machine scale set with jumpbox + +This template deploys an Azure virtual machine scale set with a jumpbox. + +## Resources + +| Terraform Resource Type | Description | +| - | - | +[azurerm_lb](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/lb) | Manages a Load Balancer Resource. | +[azurerm_lb_backend_address_pool](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/lb_backend_address_pool) | Manages a Load Balancer Backend Address Pool. | +[azurerm_lb_probe](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/lb_probe) | Manages a LoadBalancer Probe Resource. | +[azurerm_lb_rule](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/lb_rule) | Manages a Load Balancer Rule. | +[azurerm_network_interface](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/network_interface) | Manages a Network Interface. | +[azurerm_public_ip](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/public_ip) | Manages a Public IP Address. | +[azurerm_resource_group](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) | Manages a Resource Group. | +[azurerm_subnet](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/subnet) | Manages a subnet. Subnets represent network segments within the IP space defined by the virtual network. | +[azurerm_virtual_machine](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_machine) | Manages a Virtual Machine. | +[azurerm_virtual_machine_scale_set](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_machine_scale_set) | Manages a virtual machine scale set. | +[azurerm_virtual_network](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_network) | Manages a virtual network including any configured subnets. Each subnet can optionally be configured with a security group to be associated with the subnet. | + +## Variables + +| Name | Description | +|-|-| +| `resource_group_name` | Name of the resource group in which the resources will be created | +| `location` | Location where resources will be create | +| `tags` | Map of the tags to use for the resources that are deployed | +| `application_port` | Port that you want to expose to the external load balancer | +| `admin_user` | User name to use as the admin account on the VMs that will be part of the VM scale set | +| `admin_password` | Default password for admin account (NOTE: For security reasons, this value is not set in the plaintext variables.tf file.) | + +## Example + +To see how to run this example, see [Create an Azure virtual machine scale set using Terraform](https://docs.microsoft.com/azure/developer/terraform/create-vm-scaleset-network-disks-hcl). diff --git a/quickstart/201-vmss-jumpbox/variables.tf b/quickstart/201-vmss-jumpbox/variables.tf new file mode 100644 index 00000000..574d720c --- /dev/null +++ b/quickstart/201-vmss-jumpbox/variables.tf @@ -0,0 +1,31 @@ +variable "resource_group_name" { + description = "Name of the resource group in which the resources will be created" + default = "myResourceGroup" +} + +variable "location" { + default = "eastus" + description = "Location where resources will be created" +} + +variable "tags" { + description = "Map of the tags to use for the resources that are deployed" + type = map(string) + default = { + environment = "codelab" + } +} + +variable "application_port" { + description = "Port that you want to expose to the external load balancer" + default = 80 +} + +variable "admin_user" { + description = "User name to use as the admin account on the VMs that will be part of the VM scale set" + default = "azureuser" +} + +variable "admin_password" { + description = "Default password for admin account" +} \ No newline at end of file diff --git a/quickstart/201-vmss-jumpbox/web.conf b/quickstart/201-vmss-jumpbox/web.conf new file mode 100644 index 00000000..8fb5f6f2 --- /dev/null +++ b/quickstart/201-vmss-jumpbox/web.conf @@ -0,0 +1,3 @@ +#cloud-config +packages: + - nginx \ No newline at end of file diff --git a/quickstart/201-vmss-packer-jumpbox/main.tf b/quickstart/201-vmss-packer-jumpbox/main.tf new file mode 100644 index 00000000..87377e1d --- /dev/null +++ b/quickstart/201-vmss-packer-jumpbox/main.tf @@ -0,0 +1,222 @@ +terraform { + + required_version = ">=0.12" + + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "~>2.0" + } + } +} + +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "vmss" { + name = var.resource_group_name + location = var.location + tags = var.tags +} + +resource "random_string" "fqdn" { + length = 6 + special = false + upper = false + number = false +} + +resource "azurerm_virtual_network" "vmss" { + name = "vmss-vnet" + address_space = ["10.0.0.0/16"] + location = var.location + resource_group_name = azurerm_resource_group.vmss.name + tags = var.tags +} + +resource "azurerm_subnet" "vmss" { + name = "vmss-subnet" + resource_group_name = azurerm_resource_group.vmss.name + virtual_network_name = azurerm_virtual_network.vmss.name + address_prefixes = ["10.0.2.0/24"] +} + +resource "azurerm_public_ip" "vmss" { + name = "vmss-public-ip" + location = var.location + resource_group_name = azurerm_resource_group.vmss.name + allocation_method = "Static" + domain_name_label = random_string.fqdn.result + tags = var.tags +} + +resource "azurerm_lb" "vmss" { + name = "vmss-lb" + location = var.location + resource_group_name = azurerm_resource_group.vmss.name + + frontend_ip_configuration { + name = "PublicIPAddress" + public_ip_address_id = azurerm_public_ip.vmss.id + } + + tags = var.tags +} + +resource "azurerm_lb_backend_address_pool" "bpepool" { + loadbalancer_id = azurerm_lb.vmss.id + name = "BackEndAddressPool" +} + +resource "azurerm_lb_probe" "vmss" { + resource_group_name = azurerm_resource_group.vmss.name + loadbalancer_id = azurerm_lb.vmss.id + name = "ssh-running-probe" + port = var.application_port +} + +resource "azurerm_lb_rule" "lbnatrule" { + resource_group_name = azurerm_resource_group.vmss.name + loadbalancer_id = azurerm_lb.vmss.id + name = "http" + protocol = "Tcp" + frontend_port = var.application_port + backend_port = var.application_port + backend_address_pool_id = azurerm_lb_backend_address_pool.bpepool.id + frontend_ip_configuration_name = "PublicIPAddress" + probe_id = azurerm_lb_probe.vmss.id +} + +data "azurerm_resource_group" "image" { + name = var.packer_resource_group_name +} + +data "azurerm_image" "image" { + name = var.packer_image_name + resource_group_name = data.azurerm_resource_group.image.name +} + +resource "azurerm_virtual_machine_scale_set" "vmss" { + name = "vmscaleset" + location = var.location + resource_group_name = azurerm_resource_group.vmss.name + upgrade_policy_mode = "Manual" + + sku { + name = "Standard_DS1_v2" + tier = "Standard" + capacity = 2 + } + + storage_profile_image_reference { + id=data.azurerm_image.image.id + } + + storage_profile_os_disk { + name = "" + caching = "ReadWrite" + create_option = "FromImage" + managed_disk_type = "Standard_LRS" + } + + storage_profile_data_disk { + lun = 0 + caching = "ReadWrite" + create_option = "Empty" + disk_size_gb = 10 + } + + os_profile { + computer_name_prefix = "vmlab" + admin_username = var.admin_user + admin_password = var.admin_password + } + + os_profile_linux_config { + disable_password_authentication = true + + ssh_keys { + path = "/home/azureuser/.ssh/authorized_keys" + key_data = file("~/.ssh/id_rsa.pub") + } + } + + network_profile { + name = "terraformnetworkprofile" + primary = true + + ip_configuration { + name = "IPConfiguration" + subnet_id = azurerm_subnet.vmss.id + load_balancer_backend_address_pool_ids = [azurerm_lb_backend_address_pool.bpepool.id] + primary = true + } + } + + tags = var.tags +} + +resource "azurerm_public_ip" "jumpbox" { + name = "jumpbox-public-ip" + location = var.location + resource_group_name = azurerm_resource_group.vmss.name + allocation_method = "Static" + domain_name_label = "${random_string.fqdn.result}-ssh" + tags = var.tags +} + +resource "azurerm_network_interface" "jumpbox" { + name = "jumpbox-nic" + location = var.location + resource_group_name = azurerm_resource_group.vmss.name + + ip_configuration { + name = "IPConfiguration" + subnet_id = azurerm_subnet.vmss.id + private_ip_address_allocation = "dynamic" + public_ip_address_id = azurerm_public_ip.jumpbox.id + } + + tags = var.tags +} + +resource "azurerm_virtual_machine" "jumpbox" { + name = "jumpbox" + location = var.location + resource_group_name = azurerm_resource_group.vmss.name + network_interface_ids = [azurerm_network_interface.jumpbox.id] + vm_size = "Standard_DS1_v2" + + storage_image_reference { + publisher = "Canonical" + offer = "UbuntuServer" + sku = "16.04-LTS" + version = "latest" + } + + storage_os_disk { + name = "jumpbox-osdisk" + caching = "ReadWrite" + create_option = "FromImage" + managed_disk_type = "Standard_LRS" + } + + os_profile { + computer_name = "jumpbox" + admin_username = var.admin_user + admin_password = var.admin_password + } + + os_profile_linux_config { + disable_password_authentication = true + + ssh_keys { + path = "/home/azureuser/.ssh/authorized_keys" + key_data = file("~/.ssh/id_rsa.pub") + } + } + + tags = var.tags +} + diff --git a/quickstart/201-vmss-packer-jumpbox/output.tf b/quickstart/201-vmss-packer-jumpbox/output.tf new file mode 100644 index 00000000..57734ab9 --- /dev/null +++ b/quickstart/201-vmss-packer-jumpbox/output.tf @@ -0,0 +1,11 @@ +output "vmss_public_ip_fqdn" { + value = azurerm_public_ip.vmss.fqdn +} + +output "jumpbox_public_ip_fqdn" { + value = azurerm_public_ip.jumpbox.fqdn +} + +output "jumpbox_public_ip" { + value = azurerm_public_ip.jumpbox.ip_address +} diff --git a/quickstart/201-vmss-packer-jumpbox/readme.md b/quickstart/201-vmss-packer-jumpbox/readme.md new file mode 100644 index 00000000..348009b3 --- /dev/null +++ b/quickstart/201-vmss-packer-jumpbox/readme.md @@ -0,0 +1,36 @@ +# Azure virtual machine scale set with jumpbox from Packer custom image + +This template deploys an Azure virtual machine scale set with a jumpbox from a Packer custom image. + +| Terraform Resource Type | Description | +| - | - | +[azurerm_image](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/shared_image) | Manages a Shared Image within a Shared Image Gallery.| +[azurerm_lb](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/lb) | Manages a Load Balancer Resource. | +[azurerm_lb_backend_address_pool](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/lb_backend_address_pool) | Manages a Load Balancer Backend Address Pool. | +[azurerm_lb_probe](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/lb_probe) | Manages a LoadBalancer Probe Resource. | +[azurerm_lb_rule](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/lb_rule) | Manages a Load Balancer Rule. | +[azurerm_network_interface](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/network_interface) | Manages a Network Interface. | +[azurerm_public_ip](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/public_ip) | Manages a Public IP Address. | +[azurerm_resource_group](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) | Manages a Resource Group. | +[azurerm_subnet](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/subnet) | Manages a subnet. Subnets represent network segments within the IP space defined by the virtual network. | +[azurerm_virtual_machine](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_machine) | Manages a Virtual Machine. | +[azurerm_virtual_machine_scale_set](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_machine_scale_set) | Manages a virtual machine scale set. | +[azurerm_virtual_network](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_network) | Manages a virtual network including any configured subnets. Each subnet can optionally be configured with a security group to be associated with the subnet. | + +## Variables + +| Name | Description | +|-|-| +| `packer_resource_group_name` | Name of the resource group in which the Packer image will be created | +| `packer_image_name` | Name of the Packer image | +| `resource_group_name` | Name of the resource group in which the resources will be created | +| `location` | Location where resources will be create | +| `tags` | Map of the tags to use for the resources that are deployed | +| `application_port` | Port that you want to expose to the external load balancer | +| `admin_user` | User name to use as the admin account on the VMs that will be part of the VM scale set | +| `admin_password` | Default password for admin account (NOTE: For security reasons, this value is not set in the plaintext variables.tf file.) | + +## Example + +To see how to run this example, see [Create an Azure virtual machine scale set from a Packer custom image by using Terraform +](https://docs.microsoft.com/azure/developer/terraform/create-vm-scaleset-network-disks-using-packer-hcl#create-an-azure-image-by-using-packer). diff --git a/quickstart/201-vmss-packer-jumpbox/ubuntu.json b/quickstart/201-vmss-packer-jumpbox/ubuntu.json new file mode 100644 index 00000000..efd4eaf6 --- /dev/null +++ b/quickstart/201-vmss-packer-jumpbox/ubuntu.json @@ -0,0 +1,38 @@ +{ + "builders": [{ + "type": "azure-arm", + + "client_id": "0bfc2293-4d69-49b5-83f7-bf0d60d20c45", + "client_secret": "G3.6ytCh44Kcla~_JRPBDLkzsXLOa3edDL", + "tenant_id": "c3fd441d-b8ad-487e-aa27-453079018fca", + "subscription_id": "b162117f-53fa-4f42-8c77-6a65ca966c40", + + "managed_image_resource_group_name": "myPackerImages", + "managed_image_name": "myPackerImage", + + "os_type": "Linux", + "image_publisher": "Canonical", + "image_offer": "UbuntuServer", + "image_sku": "16.04-LTS", + + "azure_tags": { + "dept": "Engineering", + "task": "Image deployment" + }, + + "location": "East US", + "vm_size": "Standard_DS2_v2" + }], + "provisioners": [{ + "execute_command": "chmod +x {{ .Path }}; {{ .Vars }} sudo -E sh '{{ .Path }}'", + "inline": [ + "apt-get update", + "apt-get upgrade -y", + "apt-get -y install nginx", + + "/usr/sbin/waagent -force -deprovision+user && export HISTSIZE=0 && sync" + ], + "inline_shebang": "/bin/sh -x", + "type": "shell" + }] + } \ No newline at end of file diff --git a/quickstart/201-vmss-packer-jumpbox/variables.tf b/quickstart/201-vmss-packer-jumpbox/variables.tf new file mode 100644 index 00000000..992cfeba --- /dev/null +++ b/quickstart/201-vmss-packer-jumpbox/variables.tf @@ -0,0 +1,46 @@ +variable "packer_resource_group_name" { + description = "Name of the resource group in which the Packer image will be created" + default = "myPackerImages" +} + +variable "packer_image_name" { + description = "Name of the Packer image" + default = "myPackerImage" +} + +variable "resource_group_name" { + description = "Name of the resource group in which the Packer image will be created" + default = "myPackerImages" +} + +variable "resource_group_name" { + description = "Name of the resource group in which the resources will be created" + default = "myResourceGroup" +} + +variable "location" { + default = "eastus" + description = "Location where resources will be created" +} + +variable "tags" { + description = "Map of the tags to use for the resources that are deployed" + type = map(string) + default = { + environment = "codelab" + } +} + +variable "application_port" { + description = "Port that you want to expose to the external load balancer" + default = 80 +} + +variable "admin_user" { + description = "User name to use as the admin account on the VMs that will be part of the VM scale set" + default = "azureuser" +} + +variable "admin_password" { + description = "Default password for admin account" +} \ No newline at end of file diff --git a/quickstart/301-hub-spoke/hub-nva.tf b/quickstart/301-hub-spoke/hub-nva.tf new file mode 100644 index 00000000..31c8ff30 --- /dev/null +++ b/quickstart/301-hub-spoke/hub-nva.tf @@ -0,0 +1,199 @@ +locals { + prefix-hub-nva = "hub-nva" + hub-nva-location = "eastus" + hub-nva-resource-group = "hub-nva-rg" +} + +resource "azurerm_resource_group" "hub-nva-rg" { + name = "${local.prefix-hub-nva}-rg" + location = local.hub-nva-location + + tags = { + environment = local.prefix-hub-nva + } +} + +resource "azurerm_network_interface" "hub-nva-nic" { + name = "${local.prefix-hub-nva}-nic" + location = azurerm_resource_group.hub-nva-rg.location + resource_group_name = azurerm_resource_group.hub-nva-rg.name + enable_ip_forwarding = true + + ip_configuration { + name = local.prefix-hub-nva + subnet_id = azurerm_subnet.hub-dmz.id + private_ip_address_allocation = "Static" + private_ip_address = "10.0.0.36" + } + + tags = { + environment = local.prefix-hub-nva + } +} + +resource "azurerm_virtual_machine" "hub-nva-vm" { + name = "${local.prefix-hub-nva}-vm" + location = azurerm_resource_group.hub-nva-rg.location + resource_group_name = azurerm_resource_group.hub-nva-rg.name + network_interface_ids = [azurerm_network_interface.hub-nva-nic.id] + vm_size = var.vmsize + + storage_image_reference { + publisher = "Canonical" + offer = "UbuntuServer" + sku = "16.04-LTS" + version = "latest" + } + + storage_os_disk { + name = "myosdisk1" + caching = "ReadWrite" + create_option = "FromImage" + managed_disk_type = "Standard_LRS" + } + + os_profile { + computer_name = "${local.prefix-hub-nva}-vm" + admin_username = var.username + admin_password = var.password + } + + os_profile_linux_config { + disable_password_authentication = false + } + + tags = { + environment = local.prefix-hub-nva + } +} + +resource "azurerm_virtual_machine_extension" "enable-routes" { + name = "enable-iptables-routes" + virtual_machine_id = azurerm_virtual_machine.hub-nva-vm.id + publisher = "Microsoft.Azure.Extensions" + type = "CustomScript" + type_handler_version = "2.0" + + + settings = <