diff --git a/azurerm/internal/features/beta_features_opt_in.go b/azurerm/internal/features/beta_features_opt_in.go new file mode 100644 index 000000000000..4b9f4f5c58c1 --- /dev/null +++ b/azurerm/internal/features/beta_features_opt_in.go @@ -0,0 +1,14 @@ +package features + +import ( + "os" + "strings" +) + +// VMSSExtensionsBeta returns whether or not the beta for VMSS Extensions for Linux and Windows VMSS resources is +// enabled. +// +// Set the Environment Variable `ARM_PROVIDER_VMSS_EXTENSIONS_BETA` to `true` +func VMSSExtensionsBeta() bool { + return strings.EqualFold(os.Getenv("ARM_PROVIDER_VMSS_EXTENSIONS_BETA"), "true") +} diff --git a/azurerm/internal/services/compute/linux_virtual_machine_scale_set_resource.go b/azurerm/internal/services/compute/linux_virtual_machine_scale_set_resource.go index 2ee11e4e6b7b..acd9bd4d0288 100644 --- a/azurerm/internal/services/compute/linux_virtual_machine_scale_set_resource.go +++ b/azurerm/internal/services/compute/linux_virtual_machine_scale_set_resource.go @@ -12,6 +12,7 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/compute/parse" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/compute/validate" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" @@ -136,6 +137,8 @@ func resourceArmLinuxVirtualMachineScaleSet() *schema.Resource { }, false), }, + "extension": VirtualMachineScaleSetExtensionsSchema(), + "health_probe_id": { Type: schema.TypeString, Optional: true, @@ -262,15 +265,15 @@ func resourceArmLinuxVirtualMachineScaleSetCreate(d *schema.ResourceData, meta i resourceGroup := d.Get("resource_group_name").(string) name := d.Get("name").(string) - resp, err := client.Get(ctx, resourceGroup, name) + exists, err := client.Get(ctx, resourceGroup, name) if err != nil { - if !utils.ResponseWasNotFound(resp.Response) { - return fmt.Errorf("Error checking for existing Linux Virtual Machine Scale Set %q (Resource Group %q): %+v", name, resourceGroup, err) + if !utils.ResponseWasNotFound(exists.Response) { + return fmt.Errorf("checking for existing Linux Virtual Machine Scale Set %q (Resource Group %q): %+v", name, resourceGroup, err) } } - if !utils.ResponseWasNotFound(resp.Response) { - return tf.ImportAsExistsError("azurerm_linux_virtual_machine_scale_set", *resp.ID) + if !utils.ResponseWasNotFound(exists.Response) { + return tf.ImportAsExistsError("azurerm_linux_virtual_machine_scale_set", *exists.ID) } location := azure.NormalizeLocation(d.Get("location").(string)) @@ -394,6 +397,15 @@ func resourceArmLinuxVirtualMachineScaleSetCreate(d *schema.ResourceData, meta i }, } + if features.VMSSExtensionsBeta() { + if vmExtensionsRaw, ok := d.GetOk("extension"); ok { + virtualMachineProfile.ExtensionProfile, err = expandVirtualMachineScaleSetExtensions(vmExtensionsRaw.([]interface{})) + if err != nil { + return err + } + } + } + if adminPassword, ok := d.GetOk("admin_password"); ok { virtualMachineProfile.OsProfile.AdminPassword = utils.String(adminPassword.(string)) } @@ -488,7 +500,7 @@ func resourceArmLinuxVirtualMachineScaleSetCreate(d *schema.ResourceData, meta i log.Printf("[DEBUG] Virtual Machine Scale Set %q (Resource Group %q) was created", name, resourceGroup) log.Printf("[DEBUG] Retrieving Virtual Machine Scale Set %q (Resource Group %q)..", name, resourceGroup) - resp, err = client.Get(ctx, resourceGroup, name) + resp, err := client.Get(ctx, resourceGroup, name) if err != nil { return fmt.Errorf("Error retrieving Linux Virtual Machine Scale Set %q (Resource Group %q): %+v", name, resourceGroup, err) } @@ -728,6 +740,18 @@ func resourceArmLinuxVirtualMachineScaleSetUpdate(d *schema.ResourceData, meta i update.Sku = sku } + if features.VMSSExtensionsBeta() { + if d.HasChange("extension") { + updateInstances = true + + extensionProfile, err := expandVirtualMachineScaleSetExtensions(d.Get("extension").([]interface{})) + if err != nil { + return err + } + updateProps.VirtualMachineProfile.ExtensionProfile = extensionProfile + } + } + if d.HasChange("tags") { update.Tags = tags.Expand(d.Get("tags").(map[string]interface{})) } @@ -905,6 +929,14 @@ func resourceArmLinuxVirtualMachineScaleSetRead(d *schema.ResourceData, meta int return fmt.Errorf("Error setting `terminate_notification`: %+v", err) } } + + if features.VMSSExtensionsBeta() { + extensionProfile, err := flattenVirtualMachineScaleSetExtensions(profile.ExtensionProfile, d) + if err != nil { + return fmt.Errorf("failed flattening `extension`: %+v", err) + } + d.Set("extension", extensionProfile) + } } if policy := props.UpgradePolicy; policy != nil { diff --git a/azurerm/internal/services/compute/tests/linux_virtual_machine_scale_set_other_resource_test.go b/azurerm/internal/services/compute/tests/linux_virtual_machine_scale_set_other_resource_test.go index 08b8b47e8591..c8f5ba8b763c 100644 --- a/azurerm/internal/services/compute/tests/linux_virtual_machine_scale_set_other_resource_test.go +++ b/azurerm/internal/services/compute/tests/linux_virtual_machine_scale_set_other_resource_test.go @@ -589,6 +589,103 @@ func TestAccAzureRMLinuxVirtualMachineScaleSet_otherUpgradeMode(t *testing.T) { }) } +func TestAccAzureRMLinuxVirtualMachineScaleSet_otherVmExtensions(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_linux_virtual_machine_scale_set", "test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMLinuxVirtualMachineScaleSetDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMLinuxVirtualMachineScaleSet_otherVmExtensions(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMLinuxVirtualMachineScaleSetExists(data.ResourceName)), + }, + // TODO - extension should be changed to extension.0.protected_settings when either binary testing is available or this feature is promoted from beta + data.ImportStep("admin_password", "extension"), + }, + }) +} + +func TestAccAzureRMLinuxVirtualMachineScaleSet_otherVmExtensionsForceUpdateTag(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_linux_virtual_machine_scale_set", "test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMLinuxVirtualMachineScaleSetDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMLinuxVirtualMachineScaleSet_otherVmExtensionsForceUpdateTag(data, "first"), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMLinuxVirtualMachineScaleSetExists(data.ResourceName)), + }, + // TODO - extension should be changed to extension.0.protected_settings when either binary testing is available or this feature is promoted from beta + data.ImportStep("admin_password", "extension"), + { + Config: testAccAzureRMLinuxVirtualMachineScaleSet_otherVmExtensionsForceUpdateTag(data, "second"), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMLinuxVirtualMachineScaleSetExists(data.ResourceName)), + }, + // TODO - extension should be changed to extension.0.protected_settings when either binary testing is available or this feature is promoted from beta + data.ImportStep("admin_password", "extension"), + }, + }) +} + +func TestAccAzureRMLinuxVirtualMachineScaleSet_otherVmExtensionsMultiple(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_linux_virtual_machine_scale_set", "test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMLinuxVirtualMachineScaleSetDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMLinuxVirtualMachineScaleSet_otherVmExtensionsMultiple(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMLinuxVirtualMachineScaleSetExists(data.ResourceName)), + }, + // TODO - extension should be changed to extension.0.protected_settings when either binary testing is available or this feature is promoted from beta + data.ImportStep("admin_password", "extension"), + }, + }) +} + +func TestAccAzureRMLinuxVirtualMachineScaleSet_otherVmExtensionsUpdate(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_linux_virtual_machine_scale_set", "test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMLinuxVirtualMachineScaleSetDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMLinuxVirtualMachineScaleSet_otherVmExtensions(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMLinuxVirtualMachineScaleSetExists(data.ResourceName)), + }, + // TODO - extension should be changed to extension.0.protected_settings when either binary testing is available or this feature is promoted from beta + data.ImportStep("admin_password", "extension"), + { + Config: testAccAzureRMLinuxVirtualMachineScaleSet_otherVmExtensionsUpdate(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMLinuxVirtualMachineScaleSetExists(data.ResourceName)), + }, + // TODO - extension should be changed to extension.0.protected_settings when either binary testing is available or this feature is promoted from beta + data.ImportStep("admin_password", "extension"), + { + Config: testAccAzureRMLinuxVirtualMachineScaleSet_otherVmExtensions(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMLinuxVirtualMachineScaleSetExists(data.ResourceName)), + }, + // TODO - extension should be changed to extension.0.protected_settings when either binary testing is available or this feature is promoted from beta + data.ImportStep("admin_password", "extension"), + }, + }) +} + func testAccAzureRMLinuxVirtualMachineScaleSet_otherBootDiagnostics(data acceptance.TestData) string { template := testAccAzureRMLinuxVirtualMachineScaleSet_template(data) return fmt.Sprintf(` @@ -1933,3 +2030,281 @@ resource "azurerm_linux_virtual_machine_scale_set" "test" { } `, template, data.RandomInteger, enabled) } + +func testAccAzureRMLinuxVirtualMachineScaleSet_otherVmExtensions(data acceptance.TestData) string { + template := testAccAzureRMLinuxVirtualMachineScaleSet_template(data) + return fmt.Sprintf(` +%[1]s + +provider "azurerm" { + features {} +} + +resource "azurerm_linux_virtual_machine_scale_set" "test" { + name = "acctestvmss-%d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + sku = "Standard_F2" + instances = 1 + admin_username = "adminuser" + admin_password = "P@ssword1234!" + + disable_password_authentication = false + + source_image_reference { + publisher = "Canonical" + offer = "UbuntuServer" + sku = "16.04-LTS" + version = "latest" + } + + os_disk { + storage_account_type = "Standard_LRS" + caching = "ReadWrite" + } + + network_interface { + name = "example" + primary = true + + ip_configuration { + name = "internal" + primary = true + subnet_id = azurerm_subnet.test.id + } + } + + extension { + name = "CustomScript" + publisher = "Microsoft.Azure.Extensions" + type = "CustomScript" + type_handler_version = "2.0" + auto_upgrade_minor_version = true + + settings = jsonencode({ + "commandToExecute" = "echo $HOSTNAME" + }) + + protected_settings = jsonencode({ + "managedIdentity" = {} + }) + + } + + tags = { + accTest = "true" + } +} +`, template, data.RandomInteger) +} + +func testAccAzureRMLinuxVirtualMachineScaleSet_otherVmExtensionsForceUpdateTag(data acceptance.TestData, updateTag string) string { + template := testAccAzureRMLinuxVirtualMachineScaleSet_template(data) + return fmt.Sprintf(` +%[1]s + +provider "azurerm" { + features {} +} + +resource "azurerm_linux_virtual_machine_scale_set" "test" { + name = "acctestvmss-%d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + sku = "Standard_F2" + instances = 1 + admin_username = "adminuser" + admin_password = "P@ssword1234!" + + disable_password_authentication = false + + source_image_reference { + publisher = "Canonical" + offer = "UbuntuServer" + sku = "16.04-LTS" + version = "latest" + } + + os_disk { + storage_account_type = "Standard_LRS" + caching = "ReadWrite" + } + + network_interface { + name = "example" + primary = true + + ip_configuration { + name = "internal" + primary = true + subnet_id = azurerm_subnet.test.id + } + } + + extension { + name = "CustomScript" + publisher = "Microsoft.Azure.Extensions" + type = "CustomScript" + type_handler_version = "2.0" + auto_upgrade_minor_version = true + force_update_tag = %q + + settings = jsonencode({ + "commandToExecute" = "echo $HOSTNAME" + }) + + protected_settings = jsonencode({ + "managedIdentity" = {} + }) + } + + tags = { + accTest = "true" + } +} +`, template, data.RandomInteger, updateTag) +} + +func testAccAzureRMLinuxVirtualMachineScaleSet_otherVmExtensionsMultiple(data acceptance.TestData) string { + template := testAccAzureRMLinuxVirtualMachineScaleSet_template(data) + return fmt.Sprintf(` +%[1]s + +provider "azurerm" { + features {} +} + +resource "azurerm_linux_virtual_machine_scale_set" "test" { + name = "acctestvmss-%d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + sku = "Standard_F2" + instances = 1 + admin_username = "adminuser" + admin_password = "P@ssword1234!" + + disable_password_authentication = false + + source_image_reference { + publisher = "Canonical" + offer = "UbuntuServer" + sku = "16.04-LTS" + version = "latest" + } + + os_disk { + storage_account_type = "Standard_LRS" + caching = "ReadWrite" + } + + network_interface { + name = "example" + primary = true + + ip_configuration { + name = "internal" + primary = true + subnet_id = azurerm_subnet.test.id + } + } + + extension { + name = "CustomScript" + publisher = "Microsoft.Azure.Extensions" + type = "CustomScript" + type_handler_version = "2.0" + auto_upgrade_minor_version = true + + provision_after_extensions = ["VMAccessForLinux"] + + settings = jsonencode({ + "commandToExecute" = "echo $HOSTNAME" + }) + + protected_settings = jsonencode({ + "managedIdentity" = {} + }) + + } + + extension { + name = "VMAccessForLinux" + publisher = "Microsoft.OSTCExtensions" + type = "VMAccessForLinux" + type_handler_version = "1.5" + auto_upgrade_minor_version = true + + protected_settings = jsonencode({ + "reset_ssh" = "True" + }) + + } + + tags = { + accTest = "true" + } +} +`, template, data.RandomInteger) +} + +func testAccAzureRMLinuxVirtualMachineScaleSet_otherVmExtensionsUpdate(data acceptance.TestData) string { + template := testAccAzureRMLinuxVirtualMachineScaleSet_template(data) + return fmt.Sprintf(` +%[1]s + +provider "azurerm" { + features {} +} + +resource "azurerm_linux_virtual_machine_scale_set" "test" { + name = "acctestvmss-%d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + sku = "Standard_F2" + instances = 1 + admin_username = "adminuser" + admin_password = "P@ssword1234!" + + disable_password_authentication = false + + source_image_reference { + publisher = "Canonical" + offer = "UbuntuServer" + sku = "16.04-LTS" + version = "latest" + } + + os_disk { + storage_account_type = "Standard_LRS" + caching = "ReadWrite" + } + + network_interface { + name = "example" + primary = true + + ip_configuration { + name = "internal" + primary = true + subnet_id = azurerm_subnet.test.id + } + } + + extension { + name = "CustomScript" + publisher = "Microsoft.Azure.Extensions" + type = "CustomScript" + type_handler_version = "2.0" + auto_upgrade_minor_version = true + + settings = jsonencode({ + "commandToExecute" = "echo $(date)" + }) + } + + tags = { + accTest = "true" + } +} +`, template, data.RandomInteger) +} diff --git a/azurerm/internal/services/compute/tests/windows_virtual_machine_scale_set_other_resource_test.go b/azurerm/internal/services/compute/tests/windows_virtual_machine_scale_set_other_resource_test.go index ef59db03fda0..39f112aa69af 100644 --- a/azurerm/internal/services/compute/tests/windows_virtual_machine_scale_set_other_resource_test.go +++ b/azurerm/internal/services/compute/tests/windows_virtual_machine_scale_set_other_resource_test.go @@ -659,7 +659,7 @@ func TestAccAzureRMWindowsVirtualMachineScaleSet_otherScaleInPolicy(t *testing.T { Config: testAccAzureRMWindowsVirtualMachineScaleSet_otherScaleInPolicy(data), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMLinuxVirtualMachineScaleSetExists(data.ResourceName), + testCheckAzureRMWindowsVirtualMachineScaleSetExists(data.ResourceName), resource.TestCheckResourceAttr(data.ResourceName, "scale_in_policy", "Default"), ), }, @@ -682,7 +682,7 @@ func TestAccAzureRMWindowsVirtualMachineScaleSet_otherTerminateNotification(t *t { Config: testAccAzureRMWindowsVirtualMachineScaleSet_otherTerminateNotification(data, true), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMLinuxVirtualMachineScaleSetExists(data.ResourceName), + testCheckAzureRMWindowsVirtualMachineScaleSetExists(data.ResourceName), resource.TestCheckResourceAttr(data.ResourceName, "terminate_notification.#", "1"), resource.TestCheckResourceAttr(data.ResourceName, "terminate_notification.0.enabled", "true"), ), @@ -694,7 +694,7 @@ func TestAccAzureRMWindowsVirtualMachineScaleSet_otherTerminateNotification(t *t { Config: testAccAzureRMWindowsVirtualMachineScaleSet_otherTerminateNotification(data, false), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMLinuxVirtualMachineScaleSetExists(data.ResourceName), + testCheckAzureRMWindowsVirtualMachineScaleSetExists(data.ResourceName), resource.TestCheckResourceAttr(data.ResourceName, "terminate_notification.#", "1"), resource.TestCheckResourceAttr(data.ResourceName, "terminate_notification.0.enabled", "false"), ), @@ -706,7 +706,7 @@ func TestAccAzureRMWindowsVirtualMachineScaleSet_otherTerminateNotification(t *t { Config: testAccAzureRMWindowsVirtualMachineScaleSet_otherTerminateNotification(data, true), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMLinuxVirtualMachineScaleSetExists(data.ResourceName), + testCheckAzureRMWindowsVirtualMachineScaleSetExists(data.ResourceName), resource.TestCheckResourceAttr(data.ResourceName, "terminate_notification.#", "1"), resource.TestCheckResourceAttr(data.ResourceName, "terminate_notification.0.enabled", "true"), ), @@ -730,7 +730,7 @@ func TestAccAzureRMWindowsVirtualMachineScaleSet_otherAutomaticRepairsPolicy(t * { Config: testAccAzureRMWindowsVirtualMachineScaleSet_otherAutomaticRepairsPolicy(data, true), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMLinuxVirtualMachineScaleSetExists(data.ResourceName), + testCheckAzureRMWindowsVirtualMachineScaleSetExists(data.ResourceName), ), }, data.ImportStep( @@ -740,7 +740,7 @@ func TestAccAzureRMWindowsVirtualMachineScaleSet_otherAutomaticRepairsPolicy(t * { Config: testAccAzureRMWindowsVirtualMachineScaleSet_otherAutomaticRepairsPolicy(data, false), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMLinuxVirtualMachineScaleSetExists(data.ResourceName), + testCheckAzureRMWindowsVirtualMachineScaleSetExists(data.ResourceName), ), }, data.ImportStep( @@ -750,7 +750,7 @@ func TestAccAzureRMWindowsVirtualMachineScaleSet_otherAutomaticRepairsPolicy(t * { Config: testAccAzureRMWindowsVirtualMachineScaleSet_otherAutomaticRepairsPolicy(data, true), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMLinuxVirtualMachineScaleSetExists(data.ResourceName), + testCheckAzureRMWindowsVirtualMachineScaleSetExists(data.ResourceName), ), }, data.ImportStep( @@ -760,6 +760,110 @@ func TestAccAzureRMWindowsVirtualMachineScaleSet_otherAutomaticRepairsPolicy(t * }) } +func TestAccAzureRMWindowsVirtualMachineScaleSet_otherVmExtension(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_windows_virtual_machine_scale_set", "test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMWindowsVirtualMachineScaleSetDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMWindowsVirtualMachineScaleSet_otherVmExtensions(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMWindowsVirtualMachineScaleSetExists(data.ResourceName), + ), + }, + // TODO - extension should be changed to extension.0.protected_settings when either binary testing is available or this feature is promoted from beta + data.ImportStep("admin_password", "extension"), + }, + }) +} + +func TestAccAzureRMWindowsVirtualMachineScaleSet_otherVmExtensionForceUpdateTag(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_windows_virtual_machine_scale_set", "test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMWindowsVirtualMachineScaleSetDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMWindowsVirtualMachineScaleSet_otherVmExtensionsForceUpdateTag(data, "first"), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMWindowsVirtualMachineScaleSetExists(data.ResourceName), + ), + }, + // TODO - extension should be changed to extension.0.protected_settings when either binary testing is available or this feature is promoted from beta + data.ImportStep("admin_password", "extension"), + { + Config: testAccAzureRMWindowsVirtualMachineScaleSet_otherVmExtensionsForceUpdateTag(data, "second"), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMWindowsVirtualMachineScaleSetExists(data.ResourceName), + ), + }, + // TODO - extension should be changed to extension.0.protected_settings when either binary testing is available or this feature is promoted from beta + data.ImportStep("admin_password", "extension"), + }, + }) +} + +func TestAccAzureRMWindowsVirtualMachineScaleSet_otherVmExtensionMultiple(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_windows_virtual_machine_scale_set", "test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMWindowsVirtualMachineScaleSetDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMWindowsVirtualMachineScaleSet_otherVmExtensionsMultiple(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMWindowsVirtualMachineScaleSetExists(data.ResourceName), + ), + }, + // TODO - extension should be changed to extension.0.protected_settings when either binary testing is available or this feature is promoted from beta + data.ImportStep("admin_password", "extension"), + }, + }) +} + +func TestAccAzureRMWindowsVirtualMachineScaleSet_otherVmExtensionUpdate(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_windows_virtual_machine_scale_set", "test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMWindowsVirtualMachineScaleSetDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMWindowsVirtualMachineScaleSet_otherVmExtensions(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMWindowsVirtualMachineScaleSetExists(data.ResourceName), + ), + }, + // TODO - extension should be changed to extension.0.protected_settings when either binary testing is available or this feature is promoted from beta + data.ImportStep("admin_password", "extension"), + { + Config: testAccAzureRMWindowsVirtualMachineScaleSet_otherVmExtensionsUpdate(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMWindowsVirtualMachineScaleSetExists(data.ResourceName), + ), + }, + // TODO - extension should be changed to extension.0.protected_settings when either binary testing is available or this feature is promoted from beta + data.ImportStep("admin_password", "extension"), + { + Config: testAccAzureRMWindowsVirtualMachineScaleSet_otherVmExtensions(data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMWindowsVirtualMachineScaleSetExists(data.ResourceName), + ), + }, + // TODO - extension should be changed to extension.0.protected_settings when either binary testing is available or this feature is promoted from beta + data.ImportStep("admin_password", "extension"), + }, + }) +} + func testAccAzureRMWindowsVirtualMachineScaleSet_otherBootDiagnostics(data acceptance.TestData) string { template := testAccAzureRMWindowsVirtualMachineScaleSet_template(data) return fmt.Sprintf(` @@ -2313,6 +2417,253 @@ resource "azurerm_windows_virtual_machine_scale_set" "test" { `, template, data.RandomInteger, enabled) } +func testAccAzureRMWindowsVirtualMachineScaleSet_otherVmExtensions(data acceptance.TestData) string { + template := testAccAzureRMWindowsVirtualMachineScaleSet_template(data) + return fmt.Sprintf(` +%s + +provider "azurerm" { + features {} +} + +resource "azurerm_windows_virtual_machine_scale_set" "test" { + name = local.vm_name + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + sku = "Standard_F2" + instances = 1 + admin_username = "adminuser" + admin_password = "P@ssword1234!" + + source_image_reference { + publisher = "MicrosoftWindowsServer" + offer = "WindowsServer" + sku = "2019-Datacenter" + version = "latest" + } + + os_disk { + storage_account_type = "Standard_LRS" + caching = "ReadWrite" + } + + network_interface { + name = "example" + primary = true + + ip_configuration { + name = "internal" + primary = true + subnet_id = azurerm_subnet.test.id + } + } + + extension { + name = "CustomScript" + publisher = "Microsoft.Compute" + type = "CustomScriptExtension" + type_handler_version = "1.10" + auto_upgrade_minor_version = true + + settings = jsonencode({ + "commandToExecute" = "powershell.exe -c \"Get-Content env:computername\"" + }) + + protected_settings = jsonencode({ + "managedIdentity" = {} + }) + } +} +`, template) +} + +func testAccAzureRMWindowsVirtualMachineScaleSet_otherVmExtensionsForceUpdateTag(data acceptance.TestData, updateTag string) string { + template := testAccAzureRMWindowsVirtualMachineScaleSet_template(data) + return fmt.Sprintf(` +%s + +provider "azurerm" { + features {} +} + +resource "azurerm_windows_virtual_machine_scale_set" "test" { + name = local.vm_name + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + sku = "Standard_F2" + instances = 1 + admin_username = "adminuser" + admin_password = "P@ssword1234!" + + source_image_reference { + publisher = "MicrosoftWindowsServer" + offer = "WindowsServer" + sku = "2019-Datacenter" + version = "latest" + } + + os_disk { + storage_account_type = "Standard_LRS" + caching = "ReadWrite" + } + + network_interface { + name = "example" + primary = true + + ip_configuration { + name = "internal" + primary = true + subnet_id = azurerm_subnet.test.id + } + } + + extension { + name = "CustomScript" + publisher = "Microsoft.Compute" + type = "CustomScriptExtension" + type_handler_version = "1.10" + auto_upgrade_minor_version = true + force_update_tag = %q + + settings = jsonencode({ + "commandToExecute" = "powershell.exe -c \"Get-Content env:computername\"" + }) + + protected_settings = jsonencode({ + "managedIdentity" = {} + }) + } +} +`, template, updateTag) +} + +func testAccAzureRMWindowsVirtualMachineScaleSet_otherVmExtensionsMultiple(data acceptance.TestData) string { + template := testAccAzureRMWindowsVirtualMachineScaleSet_template(data) + return fmt.Sprintf(` +%s + +provider "azurerm" { + features {} +} + +resource "azurerm_windows_virtual_machine_scale_set" "test" { + name = local.vm_name + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + sku = "Standard_F2" + instances = 1 + admin_username = "adminuser" + admin_password = "P@ssword1234!" + + source_image_reference { + publisher = "MicrosoftWindowsServer" + offer = "WindowsServer" + sku = "2019-Datacenter" + version = "latest" + } + + os_disk { + storage_account_type = "Standard_LRS" + caching = "ReadWrite" + } + + network_interface { + name = "example" + primary = true + + ip_configuration { + name = "internal" + primary = true + subnet_id = azurerm_subnet.test.id + } + } + + extension { + name = "CustomScript" + publisher = "Microsoft.Compute" + type = "CustomScriptExtension" + type_handler_version = "1.10" + auto_upgrade_minor_version = true + + provision_after_extensions = ["AADLoginForWindows"] + + settings = jsonencode({ + "commandToExecute" = "powershell.exe -c \"Get-Content env:computername\"" + }) + + protected_settings = jsonencode({ + "managedIdentity" = {} + }) + } + + extension { + name = "AADLoginForWindows" + publisher = "Microsoft.Azure.ActiveDirectory" + type = "AADLoginForWindows" + type_handler_version = "1.0" + auto_upgrade_minor_version = true + } +} +`, template) +} + +func testAccAzureRMWindowsVirtualMachineScaleSet_otherVmExtensionsUpdate(data acceptance.TestData) string { + template := testAccAzureRMWindowsVirtualMachineScaleSet_template(data) + return fmt.Sprintf(` +%s + +provider "azurerm" { + features {} +} + +resource "azurerm_windows_virtual_machine_scale_set" "test" { + name = local.vm_name + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + sku = "Standard_F2" + instances = 1 + admin_username = "adminuser" + admin_password = "P@ssword1234!" + + source_image_reference { + publisher = "MicrosoftWindowsServer" + offer = "WindowsServer" + sku = "2019-Datacenter" + version = "latest" + } + + os_disk { + storage_account_type = "Standard_LRS" + caching = "ReadWrite" + } + + network_interface { + name = "example" + primary = true + + ip_configuration { + name = "internal" + primary = true + subnet_id = azurerm_subnet.test.id + } + } + + extension { + name = "CustomScript" + publisher = "Microsoft.Compute" + type = "CustomScriptExtension" + type_handler_version = "1.10" + auto_upgrade_minor_version = true + + settings = jsonencode({ + "commandToExecute" = "powershell.exe -c \"Get-Process | Where-Object { $_.CPU -gt 10000 }\"" + }) + } +} +`, template) +} + func testAccAzureRMWindowsVirtualMachineScaleSet_otherUpgradeMode(data acceptance.TestData, enabled bool) string { template := testAccAzureRMWindowsVirtualMachineScaleSet_template(data) return fmt.Sprintf(` diff --git a/azurerm/internal/services/compute/virtual_machine_scale_set.go b/azurerm/internal/services/compute/virtual_machine_scale_set.go index cbfc26451718..6e4065e8b116 100644 --- a/azurerm/internal/services/compute/virtual_machine_scale_set.go +++ b/azurerm/internal/services/compute/virtual_machine_scale_set.go @@ -3,6 +3,8 @@ package compute import ( "fmt" + "github.com/hashicorp/terraform-plugin-sdk/helper/structure" + "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-12-01/compute" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/helper/validation" @@ -1297,3 +1299,193 @@ func FlattenVirtualMachineScaleSetAutomaticRepairsPolicy(input *compute.Automati }, } } + +func VirtualMachineScaleSetExtensionsSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "publisher": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "type": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "type_handler_version": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "auto_upgrade_minor_version": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + + "force_update_tag": { + Type: schema.TypeString, + Optional: true, + }, + + "protected_settings": { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + ValidateFunc: validation.StringIsJSON, + }, + + "provision_after_extensions": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + + "settings": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringIsJSON, + DiffSuppressFunc: structure.SuppressJsonDiff, + }, + }, + }, + } +} + +func expandVirtualMachineScaleSetExtensions(input []interface{}) (*compute.VirtualMachineScaleSetExtensionProfile, error) { + result := &compute.VirtualMachineScaleSetExtensionProfile{} + if len(input) == 0 { + return result, nil + } + + extensions := make([]compute.VirtualMachineScaleSetExtension, 0) + for _, v := range input { + extensionRaw := v.(map[string]interface{}) + extension := compute.VirtualMachineScaleSetExtension{ + Name: utils.String(extensionRaw["name"].(string)), + } + + extensionProps := compute.VirtualMachineScaleSetExtensionProperties{ + Publisher: utils.String(extensionRaw["publisher"].(string)), + Type: utils.String(extensionRaw["type"].(string)), + TypeHandlerVersion: utils.String(extensionRaw["type_handler_version"].(string)), + AutoUpgradeMinorVersion: utils.Bool(extensionRaw["auto_upgrade_minor_version"].(bool)), + ProvisionAfterExtensions: utils.ExpandStringSlice(extensionRaw["provision_after_extensions"].([]interface{})), + } + + if forceUpdateTag := extensionRaw["force_update_tag"]; forceUpdateTag != nil { + extensionProps.ForceUpdateTag = utils.String(forceUpdateTag.(string)) + } + + settings, err := structure.ExpandJsonFromString(extensionRaw["settings"].(string)) + if err != nil { + return nil, fmt.Errorf("failed to parse JSON from `settings`: %+v", err) + } + extensionProps.Settings = settings + + protectedSettings, err := structure.ExpandJsonFromString(extensionRaw["protected_settings"].(string)) + if err != nil { + return nil, fmt.Errorf("failed to parse JSON from `settings`: %+v", err) + } + + extensionProps.ProtectedSettings = protectedSettings + + extension.VirtualMachineScaleSetExtensionProperties = &extensionProps + extensions = append(extensions, extension) + } + result.Extensions = &extensions + + return result, nil +} + +func flattenVirtualMachineScaleSetExtensions(input *compute.VirtualMachineScaleSetExtensionProfile, d *schema.ResourceData) ([]map[string]interface{}, error) { + result := make([]map[string]interface{}, 0) + if input == nil || input.Extensions == nil { + return result, nil + } + + for k, v := range *input.Extensions { + name := "" + if v.Name != nil { + name = *v.Name + } + + autoUpgradeMinorVersion := false + forceUpdateTag := "" + provisionAfterExtension := make([]interface{}, 0) + protectedSettings := "" + extPublisher := "" + extSettings := "" + extType := "" + extTypeVersion := "" + + if props := v.VirtualMachineScaleSetExtensionProperties; props != nil { + if props.Publisher != nil { + extPublisher = *props.Publisher + } + + if props.Type != nil { + extType = *props.Type + } + + if props.TypeHandlerVersion != nil { + extTypeVersion = *props.TypeHandlerVersion + } + + if props.AutoUpgradeMinorVersion != nil { + autoUpgradeMinorVersion = *props.AutoUpgradeMinorVersion + } + + if props.ForceUpdateTag != nil { + forceUpdateTag = *props.ForceUpdateTag + } + + if props.ProvisionAfterExtensions != nil { + provisionAfterExtension = utils.FlattenStringSlice(props.ProvisionAfterExtensions) + } + + if props.Settings != nil { + extSettingsRaw, err := structure.FlattenJsonToString(props.Settings.(map[string]interface{})) + if err != nil { + return nil, err + } + extSettings = extSettingsRaw + } + } + // protected_settings isn't returned, so we attempt to get it from config otherwise set to empty string + if protectedSettingsFromConfig, ok := d.GetOk(fmt.Sprintf("extension.%d.protected_settings", k)); ok { + if protectedSettingsFromConfig.(string) != "" && protectedSettingsFromConfig.(string) != "{}" { + protectedSettings = protectedSettingsFromConfig.(string) + } + } + + result = append(result, map[string]interface{}{ + "name": name, + "auto_upgrade_minor_version": autoUpgradeMinorVersion, + "force_update_tag": forceUpdateTag, + "provision_after_extensions": provisionAfterExtension, + "protected_settings": protectedSettings, + "publisher": extPublisher, + "settings": extSettings, + "type": extType, + "type_handler_version": extTypeVersion, + }) + } + return result, nil +} diff --git a/azurerm/internal/services/compute/virtual_machine_scale_set_import.go b/azurerm/internal/services/compute/virtual_machine_scale_set_import.go index 84226d320b17..28fe5be68943 100644 --- a/azurerm/internal/services/compute/virtual_machine_scale_set_import.go +++ b/azurerm/internal/services/compute/virtual_machine_scale_set_import.go @@ -3,6 +3,8 @@ package compute import ( "fmt" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2019-12-01/compute" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients" @@ -96,6 +98,23 @@ func importVirtualMachineScaleSet(osType compute.OperatingSystemTypes, resourceT d.Set("admin_password", "ignored-as-imported") } + if features.VMSSExtensionsBeta() { + if vm.VirtualMachineScaleSetProperties.VirtualMachineProfile.ExtensionProfile != nil { + if extensionsProfile := vm.VirtualMachineScaleSetProperties.VirtualMachineProfile.ExtensionProfile; extensionsProfile != nil { + for _, v := range *extensionsProfile.Extensions { + v.ProtectedSettings = "" + } + updatedExtensions, err := flattenVirtualMachineScaleSetExtensions(extensionsProfile, d) + if err != nil { + return []*schema.ResourceData{}, fmt.Errorf("could not read VMSS extensions data for %q (resource group %q)", id.Name, id.ResourceGroup) + } + d.Set("extension", updatedExtensions) + } + } + } else { + d.Set("extension", []map[string]interface{}{}) + } + return []*schema.ResourceData{d}, nil } } diff --git a/azurerm/internal/services/compute/windows_virtual_machine_scale_set_resource.go b/azurerm/internal/services/compute/windows_virtual_machine_scale_set_resource.go index e38080834dec..b76869e3e4b7 100644 --- a/azurerm/internal/services/compute/windows_virtual_machine_scale_set_resource.go +++ b/azurerm/internal/services/compute/windows_virtual_machine_scale_set_resource.go @@ -13,6 +13,7 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/compute/parse" computeValidate "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/compute/validate" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" @@ -138,6 +139,8 @@ func resourceArmWindowsVirtualMachineScaleSet() *schema.Resource { }, false), }, + "extension": VirtualMachineScaleSetExtensionsSchema(), + "health_probe_id": { Type: schema.TypeString, Optional: true, @@ -279,15 +282,15 @@ func resourceArmWindowsVirtualMachineScaleSetCreate(d *schema.ResourceData, meta resourceGroup := d.Get("resource_group_name").(string) name := d.Get("name").(string) - resp, err := client.Get(ctx, resourceGroup, name) + exists, err := client.Get(ctx, resourceGroup, name) if err != nil { - if !utils.ResponseWasNotFound(resp.Response) { + if !utils.ResponseWasNotFound(exists.Response) { return fmt.Errorf("Error checking for existing Windows Virtual Machine Scale Set %q (Resource Group %q): %+v", name, resourceGroup, err) } } - if !utils.ResponseWasNotFound(resp.Response) { - return tf.ImportAsExistsError("azurerm_windows_virtual_machine_scale_set", *resp.ID) + if !utils.ResponseWasNotFound(exists.Response) { + return tf.ImportAsExistsError("azurerm_windows_virtual_machine_scale_set", *exists.ID) } location := azure.NormalizeLocation(d.Get("location").(string)) @@ -411,6 +414,15 @@ func resourceArmWindowsVirtualMachineScaleSetCreate(d *schema.ResourceData, meta }, } + if features.VMSSExtensionsBeta() { + if vmExtensionsRaw, ok := d.GetOk("extension"); ok { + virtualMachineProfile.ExtensionProfile, err = expandVirtualMachineScaleSetExtensions(vmExtensionsRaw.([]interface{})) + if err != nil { + return err + } + } + } + enableAutomaticUpdates := d.Get("enable_automatic_updates").(bool) if upgradeMode != compute.Automatic { virtualMachineProfile.OsProfile.WindowsConfiguration.EnableAutomaticUpdates = utils.Bool(enableAutomaticUpdates) @@ -515,7 +527,7 @@ func resourceArmWindowsVirtualMachineScaleSetCreate(d *schema.ResourceData, meta log.Printf("[DEBUG] Virtual Machine Scale Set %q (Resource Group %q) was created", name, resourceGroup) log.Printf("[DEBUG] Retrieving Virtual Machine Scale Set %q (Resource Group %q)..", name, resourceGroup) - resp, err = client.Get(ctx, resourceGroup, name) + resp, err := client.Get(ctx, resourceGroup, name) if err != nil { return fmt.Errorf("Error retrieving Windows Virtual Machine Scale Set %q (Resource Group %q): %+v", name, resourceGroup, err) } @@ -760,6 +772,16 @@ func resourceArmWindowsVirtualMachineScaleSetUpdate(d *schema.ResourceData, meta update.Sku = sku } + if features.VMSSExtensionsBeta() { + if d.HasChange("extension") { + extensionProfile, err := expandVirtualMachineScaleSetExtensions(d.Get("extension").([]interface{})) + if err != nil { + return err + } + updateProps.VirtualMachineProfile.ExtensionProfile = extensionProfile + } + } + if d.HasChange("tags") { update.Tags = tags.Expand(d.Get("tags").(map[string]interface{})) } @@ -966,6 +988,14 @@ func resourceArmWindowsVirtualMachineScaleSetRead(d *schema.ResourceData, meta i return fmt.Errorf("Error setting `terminate_notification`: %+v", err) } } + + if features.VMSSExtensionsBeta() { + extensionProfile, err := flattenVirtualMachineScaleSetExtensions(profile.ExtensionProfile, d) + if err != nil { + return fmt.Errorf("failed flattening `extension`: %+v", err) + } + d.Set("extension", extensionProfile) + } } if err := d.Set("zones", resp.Zones); err != nil { diff --git a/examples/service-fabric/windows-vmss-self-signed-certs/0-base.tf b/examples/service-fabric/windows-vmss-self-signed-certs/0-base.tf new file mode 100644 index 000000000000..44cee7b49364 --- /dev/null +++ b/examples/service-fabric/windows-vmss-self-signed-certs/0-base.tf @@ -0,0 +1,37 @@ +provider "azurerm" { + features {} +} + +data "azurerm_client_config" "current" { +} + +resource "azurerm_resource_group" "example" { + name = "${var.prefix}-resources" + location = var.location +} + +resource "azurerm_virtual_network" "example" { + name = "${var.prefix}-sf-network" + address_space = ["10.0.0.0/16"] + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name +} + +resource "azurerm_subnet" "example" { + name = "${var.prefix}-subnet" + resource_group_name = azurerm_resource_group.example.name + virtual_network_name = azurerm_virtual_network.example.name + address_prefixes = ["10.0.2.0/24"] +} + +resource "azurerm_storage_account" "example" { + name = "${var.prefix}sfexamplesa" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + account_tier = "Standard" + account_replication_type = "GRS" + + tags = { + environment = "example" + } +} \ No newline at end of file diff --git a/examples/service-fabric/windows-vmss-self-signed-certs/1-keyvault.tf b/examples/service-fabric/windows-vmss-self-signed-certs/1-keyvault.tf new file mode 100644 index 000000000000..30e85bba5d32 --- /dev/null +++ b/examples/service-fabric/windows-vmss-self-signed-certs/1-keyvault.tf @@ -0,0 +1,86 @@ +resource "azurerm_key_vault" "example" { + name = "${var.prefix}examplekv" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + tenant_id = data.azurerm_client_config.current.tenant_id + + sku_name = "standard" + + enabled_for_deployment = true + + access_policy { + tenant_id = data.azurerm_client_config.current.tenant_id + object_id = data.azurerm_client_config.current.object_id + + certificate_permissions = [ + "create", + "delete", + "get", + "update", + "list", + ] + + key_permissions = [ + "create", + ] + + secret_permissions = [ + "set", + ] + + storage_permissions = [ + "set", + ] + } +} + +resource "azurerm_key_vault_certificate" "example" { + name = "${var.prefix}acctestcert" + key_vault_id = azurerm_key_vault.example.id + + certificate_policy { + issuer_parameters { + name = "Self" + } + + key_properties { + exportable = true + key_size = 2048 + key_type = "RSA" + reuse_key = true + } + + lifetime_action { + action { + action_type = "AutoRenew" + } + + trigger { + days_before_expiry = 30 + } + } + + secret_properties { + content_type = "application/x-pkcs12" + } + + x509_certificate_properties { + extended_key_usage = [ + "1.3.6.1.5.5.7.3.1", + "1.3.6.1.5.5.7.3.2", + ] + + key_usage = [ + "cRLSign", + "dataEncipherment", + "digitalSignature", + "keyAgreement", + "keyCertSign", + "keyEncipherment", + ] + + subject = "CN=${var.prefix}servicefabric.${var.location}.cloudapp.azure.com" + validity_in_months = 12 + } + } +} diff --git a/examples/service-fabric/windows-vmss-self-signed-certs/2-loadbalancer.tf b/examples/service-fabric/windows-vmss-self-signed-certs/2-loadbalancer.tf new file mode 100644 index 000000000000..a7127553243b --- /dev/null +++ b/examples/service-fabric/windows-vmss-self-signed-certs/2-loadbalancer.tf @@ -0,0 +1,72 @@ +resource "azurerm_public_ip" "example" { + name = "${var.prefix}PIPForLB" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + allocation_method = "Dynamic" + domain_name_label = "exampleservicefabric" +} + +resource "azurerm_lb" "example" { + name = "${var.prefix}LoadBalancer" + location = azurerm_resource_group.example.location + resource_group_name = azurerm_resource_group.example.name + + frontend_ip_configuration { + name = "PublicIPAddress" + public_ip_address_id = azurerm_public_ip.example.id + } +} + +resource "azurerm_lb_backend_address_pool" "example" { + resource_group_name = azurerm_resource_group.example.name + loadbalancer_id = azurerm_lb.example.id + name = "${var.prefix}BEAPool" +} + +resource "azurerm_lb_nat_pool" "example" { + resource_group_name = azurerm_resource_group.example.name + loadbalancer_id = azurerm_lb.example.id + name = "${var.prefix}SFApplicationPool" + protocol = "Tcp" + frontend_port_start = 3389 + frontend_port_end = 4500 + backend_port = 3389 + frontend_ip_configuration_name = azurerm_lb.example.frontend_ip_configuration[0].name +} + +resource "azurerm_lb_rule" "example_tcp" { + resource_group_name = azurerm_resource_group.example.name + loadbalancer_id = azurerm_lb.example.id + name = "${var.prefix}LBRuleTcp" + protocol = "Tcp" + frontend_port = 19000 + backend_port = 19000 + frontend_ip_configuration_name = azurerm_lb.example.frontend_ip_configuration[0].name + backend_address_pool_id = azurerm_lb_backend_address_pool.example.id +} + +resource "azurerm_lb_rule" "example_http" { + resource_group_name = azurerm_resource_group.example.name + loadbalancer_id = azurerm_lb.example.id + name = "${var.prefix}LBRuleHttp" + protocol = "Tcp" + frontend_port = 19080 + backend_port = 19080 + frontend_ip_configuration_name = azurerm_lb.example.frontend_ip_configuration[0].name + backend_address_pool_id = azurerm_lb_backend_address_pool.example.id +} + +resource "azurerm_lb_probe" "example_tcp" { + resource_group_name = azurerm_resource_group.example.name + loadbalancer_id = azurerm_lb.example.id + name = "${var.prefix}SFTcpGatewayProbe" + port = 19000 +} + +resource "azurerm_lb_probe" "example_http" { + resource_group_name = azurerm_resource_group.example.name + loadbalancer_id = azurerm_lb.example.id + name = "${var.prefix}SFHttpGatewayProbe" + port = 19080 +} + diff --git a/examples/service-fabric/windows-vmss-self-signed-certs/3-servicefabric.tf b/examples/service-fabric/windows-vmss-self-signed-certs/3-servicefabric.tf new file mode 100644 index 000000000000..d82c3b5d203d --- /dev/null +++ b/examples/service-fabric/windows-vmss-self-signed-certs/3-servicefabric.tf @@ -0,0 +1,113 @@ + +resource "azurerm_service_fabric_cluster" "example" { + name = "${var.prefix}servicefabric" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + reliability_level = "Bronze" + upgrade_mode = "Automatic" + vm_image = "Windows" + management_endpoint = "https://${var.prefix}servicefabric.${var.location}.cloudapp.azure.com:19080" + + node_type { + name = "Windows" + instance_count = 3 + is_primary = true + client_endpoint_port = 19000 + http_endpoint_port = 19080 + } + + + reverse_proxy_certificate { + thumbprint = azurerm_key_vault_certificate.example.thumbprint + x509_store_name = "My" + } + + certificate { + thumbprint = azurerm_key_vault_certificate.example.thumbprint + x509_store_name = "My" + } + + client_certificate_thumbprint { + thumbprint = azurerm_key_vault_certificate.example.thumbprint + is_admin = true + } +} + +resource "azurerm_windows_virtual_machine_scale_set" "example" { + name = "${var.prefix}examplesf" + computer_name_prefix = var.prefix + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + sku = "Standard_D1_v2" + instances = azurerm_service_fabric_cluster.example.node_type[0].instance_count + admin_password = "P@55w0rd1234!" + admin_username = "adminuser" + overprovision = false + upgrade_mode = "Automatic" + + + source_image_reference { + publisher = "MicrosoftWindowsServer" + offer = "WindowsServer" + sku = "2016-Datacenter-with-Containers" + version = "latest" + } + + os_disk { + storage_account_type = "Standard_LRS" + caching = "ReadWrite" + } + + network_interface { + name = "example" + primary = true + + ip_configuration { + name = "internal" + primary = true + subnet_id = azurerm_subnet.example.id + load_balancer_backend_address_pool_ids = [ + azurerm_lb_backend_address_pool.example.id + ] + load_balancer_inbound_nat_rules_ids = [ + azurerm_lb_nat_pool.example.id + ] + } + } + + secret { + certificate { + store = "My" + url = azurerm_key_vault_certificate.example.secret_id + } + key_vault_id = azurerm_key_vault.example.id + } + + extension { + name = "${var.prefix}ServiceFabricNode" + publisher = "Microsoft.Azure.ServiceFabric" + type = "ServiceFabricNode" + type_handler_version = "1.1" + auto_upgrade_minor_version = false + + settings = jsonencode({ + "clusterEndpoint" = azurerm_service_fabric_cluster.example.cluster_endpoint + "nodeTypeRef" = azurerm_service_fabric_cluster.example.node_type[0].name + "durabilityLevel" = "bronze" + "nicPrefixOverride" = azurerm_subnet.example.address_prefixes[0] + "enableParallelJobs" = true + "certificate" = { + "commonNames" = [ + "${var.prefix}servicefabric.${var.location}.cloudapp.azure.com", + ] + "x509StoreName" = "My" + } + }) + + protected_settings = jsonencode({ + "StorageAccountKey1" = azurerm_storage_account.example.primary_access_key + "StorageAccountKey2" = azurerm_storage_account.example.secondary_access_key + }) + } + +} diff --git a/examples/service-fabric/windows-vmss-self-signed-certs/README.md b/examples/service-fabric/windows-vmss-self-signed-certs/README.md new file mode 100644 index 000000000000..84616df09cb5 --- /dev/null +++ b/examples/service-fabric/windows-vmss-self-signed-certs/README.md @@ -0,0 +1,4 @@ +## Example: Service Fabric using Windows VMSS and Self Signed Certificate + +### Notes: +* This example requires the use of the VMSS Extensions beta functionality, set `ARM_PROVIDER_VMSS_EXTENSIONS_BETA=true` to enable. \ No newline at end of file diff --git a/examples/service-fabric/windows-vmss-self-signed-certs/variables.tf b/examples/service-fabric/windows-vmss-self-signed-certs/variables.tf new file mode 100644 index 000000000000..01c706e19358 --- /dev/null +++ b/examples/service-fabric/windows-vmss-self-signed-certs/variables.tf @@ -0,0 +1,8 @@ +variable "prefix" { + description = "The prefix which should be used for all resources in this example" +} + +variable "location" { + description = "The Azure Region in which all resources in this example should be created. Use the `Name` value from `az account list-locations -otable` for your chosen region" + default = "westeurope" +} diff --git a/examples/vm-scale-set/linux/basic/main.tf b/examples/vm-scale-set/linux/basic/main.tf index 9cbea0284f3c..5578d542b33c 100644 --- a/examples/vm-scale-set/linux/basic/main.tf +++ b/examples/vm-scale-set/linux/basic/main.tf @@ -4,20 +4,20 @@ provider "azurerm" { resource "azurerm_resource_group" "main" { name = "${var.prefix}-resources" - location = var.location + location = "${var.location}" } resource "azurerm_virtual_network" "main" { name = "${var.prefix}-network" address_space = ["10.0.0.0/16"] - location = "${azurerm_resource_group.main.location}" - resource_group_name = "${azurerm_resource_group.main.name}" + location = azurerm_resource_group.main.location + resource_group_name = azurerm_resource_group.main.name } resource "azurerm_subnet" "internal" { name = "internal" - resource_group_name = "${azurerm_resource_group.main.name}" - virtual_network_name = "${azurerm_virtual_network.main.name}" + resource_group_name = azurerm_resource_group.main.name + virtual_network_name = azurerm_virtual_network.main.name address_prefixes = ["10.0.2.0/24"] } diff --git a/examples/vm-scale-set/linux/boot-diagnostics/main.tf b/examples/vm-scale-set/linux/boot-diagnostics/main.tf index 29ff7b19820a..3276487512cc 100644 --- a/examples/vm-scale-set/linux/boot-diagnostics/main.tf +++ b/examples/vm-scale-set/linux/boot-diagnostics/main.tf @@ -10,14 +10,14 @@ resource "azurerm_resource_group" "main" { resource "azurerm_virtual_network" "main" { name = "${var.prefix}-network" address_space = ["10.0.0.0/16"] - location = "${azurerm_resource_group.main.location}" - resource_group_name = "${azurerm_resource_group.main.name}" + location = azurerm_resource_group.main.location + resource_group_name = azurerm_resource_group.main.name } resource "azurerm_subnet" "internal" { name = "internal" - resource_group_name = "${azurerm_resource_group.main.name}" - virtual_network_name = "${azurerm_virtual_network.main.name}" + resource_group_name = azurerm_resource_group.main.name + virtual_network_name = azurerm_virtual_network.main.name address_prefixes = ["10.0.2.0/24"] } @@ -63,6 +63,6 @@ resource "azurerm_linux_virtual_machine_scale_set" "main" { } boot_diagnostics { - storage_account_uri = azurerm_storage_account.test.primary_blob_endpoint + storage_account_uri = azurerm_storage_account.main.primary_blob_endpoint } } diff --git a/examples/vm-scale-set/linux/custom-data/main.tf b/examples/vm-scale-set/linux/custom-data/main.tf index 940430044256..9a642c157dc9 100644 --- a/examples/vm-scale-set/linux/custom-data/main.tf +++ b/examples/vm-scale-set/linux/custom-data/main.tf @@ -10,14 +10,14 @@ resource "azurerm_resource_group" "main" { resource "azurerm_virtual_network" "main" { name = "${var.prefix}-network" address_space = ["10.0.0.0/16"] - location = "${azurerm_resource_group.main.location}" - resource_group_name = "${azurerm_resource_group.main.name}" + location = azurerm_resource_group.main.location + resource_group_name = azurerm_resource_group.main.name } resource "azurerm_subnet" "internal" { name = "internal" - resource_group_name = "${azurerm_resource_group.main.name}" - virtual_network_name = "${azurerm_virtual_network.main.name}" + resource_group_name = azurerm_resource_group.main.name + virtual_network_name = azurerm_virtual_network.main.name address_prefixes = ["10.0.2.0/24"] } diff --git a/examples/vm-scale-set/linux/data-disks/main.tf b/examples/vm-scale-set/linux/data-disks/main.tf index 598491d17409..14860fd6c61d 100644 --- a/examples/vm-scale-set/linux/data-disks/main.tf +++ b/examples/vm-scale-set/linux/data-disks/main.tf @@ -10,14 +10,14 @@ resource "azurerm_resource_group" "main" { resource "azurerm_virtual_network" "main" { name = "${var.prefix}-network" address_space = ["10.0.0.0/16"] - location = "${azurerm_resource_group.main.location}" - resource_group_name = "${azurerm_resource_group.main.name}" + location = azurerm_resource_group.main.location + resource_group_name = azurerm_resource_group.main.name } resource "azurerm_subnet" "internal" { name = "internal" - resource_group_name = "${azurerm_resource_group.main.name}" - virtual_network_name = "${azurerm_virtual_network.main.name}" + resource_group_name = azurerm_resource_group.main.name + virtual_network_name = azurerm_virtual_network.main.name address_prefixes = ["10.0.2.0/24"] } diff --git a/examples/vm-scale-set/linux/ephemeral-os-disk/main.tf b/examples/vm-scale-set/linux/ephemeral-os-disk/main.tf index e42a3e251e39..6a9713712267 100644 --- a/examples/vm-scale-set/linux/ephemeral-os-disk/main.tf +++ b/examples/vm-scale-set/linux/ephemeral-os-disk/main.tf @@ -10,14 +10,14 @@ resource "azurerm_resource_group" "main" { resource "azurerm_virtual_network" "main" { name = "${var.prefix}-network" address_space = ["10.0.0.0/16"] - location = "${azurerm_resource_group.main.location}" - resource_group_name = "${azurerm_resource_group.main.name}" + location = azurerm_resource_group.main.location + resource_group_name = azurerm_resource_group.main.name } resource "azurerm_subnet" "internal" { name = "internal" - resource_group_name = "${azurerm_resource_group.main.name}" - virtual_network_name = "${azurerm_virtual_network.main.name}" + resource_group_name = azurerm_resource_group.main.name + virtual_network_name = azurerm_virtual_network.main.name address_prefixes = ["10.0.2.0/24"] } diff --git a/examples/vm-scale-set/linux/extensions/README.md b/examples/vm-scale-set/linux/extensions/README.md new file mode 100644 index 000000000000..6190d20d0c82 --- /dev/null +++ b/examples/vm-scale-set/linux/extensions/README.md @@ -0,0 +1,3 @@ +## Example: Linux Virtual Machine Scale Set with VM Extensions + +This example provisions a basic Linux Virtual Machine Scale Set using a password for authentication and a `CustomScript` extension. diff --git a/examples/vm-scale-set/linux/extensions/main.tf b/examples/vm-scale-set/linux/extensions/main.tf new file mode 100644 index 000000000000..41b974e2c197 --- /dev/null +++ b/examples/vm-scale-set/linux/extensions/main.tf @@ -0,0 +1,72 @@ +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "main" { + name = "${var.prefix}-resources" + location = var.location +} + +resource "azurerm_virtual_network" "main" { + name = "${var.prefix}-network" + address_space = ["10.0.0.0/16"] + location = azurerm_resource_group.main.location + resource_group_name = azurerm_resource_group.main.name +} + +resource "azurerm_subnet" "internal" { + name = "internal" + resource_group_name = azurerm_resource_group.main.name + virtual_network_name = azurerm_virtual_network.main.name + address_prefixes = ["10.0.2.0/24"] +} + +resource "azurerm_linux_virtual_machine_scale_set" "main" { + name = "${var.prefix}-vmss" + resource_group_name = azurerm_resource_group.main.name + location = azurerm_resource_group.main.location + sku = "Standard_F2" + instances = 3 + admin_username = "adminuser" + admin_password = "P@ssw0rd1234!" + disable_password_authentication = false + + source_image_reference { + publisher = "Canonical" + offer = "UbuntuServer" + sku = "16.04-LTS" + version = "latest" + } + + network_interface { + name = "example" + primary = true + + ip_configuration { + name = "internal" + primary = true + subnet_id = azurerm_subnet.internal.id + } + } + + os_disk { + storage_account_type = "Standard_LRS" + caching = "ReadWrite" + } + + extension { + name = "CustomScript" + publisher = "Microsoft.Azure.Extensions" + type = "CustomScript" + type_handler_version = "2.0" + auto_upgrade_minor_version = true + + settings = jsonencode({ + "commandToExecute" = "echo $HOSTNAME" + }) + + protected_settings = jsonencode({ + "managedIdentity" = {} + }) + } +} \ No newline at end of file diff --git a/examples/vm-scale-set/linux/extensions/variables.tf b/examples/vm-scale-set/linux/extensions/variables.tf new file mode 100644 index 000000000000..68babb00b91a --- /dev/null +++ b/examples/vm-scale-set/linux/extensions/variables.tf @@ -0,0 +1,7 @@ +variable "prefix" { + description = "The prefix which should be used for all resources in this example" +} + +variable "location" { + description = "The Azure Region in which all resources in this example should be created." +} diff --git a/examples/vm-scale-set/linux/multiple-nics/main.tf b/examples/vm-scale-set/linux/multiple-nics/main.tf index 6c74d1f0270a..41247985b03d 100644 --- a/examples/vm-scale-set/linux/multiple-nics/main.tf +++ b/examples/vm-scale-set/linux/multiple-nics/main.tf @@ -10,14 +10,14 @@ resource "azurerm_resource_group" "main" { resource "azurerm_virtual_network" "main" { name = "${var.prefix}-network" address_space = ["10.0.0.0/16"] - location = "${azurerm_resource_group.main.location}" - resource_group_name = "${azurerm_resource_group.main.name}" + location = azurerm_resource_group.main.location + resource_group_name = azurerm_resource_group.main.name } resource "azurerm_subnet" "internal" { name = "internal" - resource_group_name = "${azurerm_resource_group.main.name}" - virtual_network_name = "${azurerm_virtual_network.main.name}" + resource_group_name = azurerm_resource_group.main.name + virtual_network_name = azurerm_virtual_network.main.name address_prefixes = ["10.0.2.0/24"] } diff --git a/examples/vm-scale-set/linux/public-ip-per-instance/main.tf b/examples/vm-scale-set/linux/public-ip-per-instance/main.tf index 24fc316198ba..b526332c6606 100644 --- a/examples/vm-scale-set/linux/public-ip-per-instance/main.tf +++ b/examples/vm-scale-set/linux/public-ip-per-instance/main.tf @@ -10,21 +10,21 @@ resource "azurerm_resource_group" "main" { resource "azurerm_virtual_network" "main" { name = "${var.prefix}-network" address_space = ["10.0.0.0/16"] - location = "${azurerm_resource_group.main.location}" - resource_group_name = "${azurerm_resource_group.main.name}" + location = azurerm_resource_group.main.location + resource_group_name = azurerm_resource_group.main.name } resource "azurerm_subnet" "internal" { name = "internal" - resource_group_name = "${azurerm_resource_group.main.name}" - virtual_network_name = "${azurerm_virtual_network.main.name}" + resource_group_name = azurerm_resource_group.main.name + virtual_network_name = azurerm_virtual_network.main.name address_prefixes = ["10.0.2.0/24"] } resource "azurerm_public_ip_prefix" "main" { name = "${var.prefix}-pip" - location = azurerm_resource_group.test.location - resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.main.location + resource_group_name = azurerm_resource_group.main.name } resource "azurerm_linux_virtual_machine_scale_set" "main" { diff --git a/examples/vm-scale-set/linux/secrets/main.tf b/examples/vm-scale-set/linux/secrets/main.tf index d277eca04067..a85d257be734 100644 --- a/examples/vm-scale-set/linux/secrets/main.tf +++ b/examples/vm-scale-set/linux/secrets/main.tf @@ -10,14 +10,14 @@ resource "azurerm_resource_group" "main" { resource "azurerm_virtual_network" "main" { name = "${var.prefix}-network" address_space = ["10.0.0.0/16"] - location = "${azurerm_resource_group.main.location}" - resource_group_name = "${azurerm_resource_group.main.name}" + location = azurerm_resource_group.main.location + resource_group_name = azurerm_resource_group.main.name } resource "azurerm_subnet" "internal" { name = "internal" - resource_group_name = "${azurerm_resource_group.main.name}" - virtual_network_name = "${azurerm_virtual_network.main.name}" + resource_group_name = azurerm_resource_group.main.name + virtual_network_name = azurerm_virtual_network.main.name address_prefixes = ["10.0.2.0/24"] } diff --git a/examples/vm-scale-set/linux/spot/main.tf b/examples/vm-scale-set/linux/spot/main.tf index 49f40d097d30..d33b2122be55 100644 --- a/examples/vm-scale-set/linux/spot/main.tf +++ b/examples/vm-scale-set/linux/spot/main.tf @@ -10,14 +10,14 @@ resource "azurerm_resource_group" "main" { resource "azurerm_virtual_network" "main" { name = "${var.prefix}-network" address_space = ["10.0.0.0/16"] - location = "${azurerm_resource_group.main.location}" - resource_group_name = "${azurerm_resource_group.main.name}" + location = azurerm_resource_group.main.location + resource_group_name = azurerm_resource_group.main.name } resource "azurerm_subnet" "internal" { name = "internal" - resource_group_name = "${azurerm_resource_group.main.name}" - virtual_network_name = "${azurerm_virtual_network.main.name}" + resource_group_name = azurerm_resource_group.main.name + virtual_network_name = azurerm_virtual_network.main.name address_prefixes = ["10.0.2.0/24"] } diff --git a/examples/vm-scale-set/linux/ssh-keys/main.tf b/examples/vm-scale-set/linux/ssh-keys/main.tf index d89cf1b50851..7a97bf6e1d25 100644 --- a/examples/vm-scale-set/linux/ssh-keys/main.tf +++ b/examples/vm-scale-set/linux/ssh-keys/main.tf @@ -10,14 +10,14 @@ resource "azurerm_resource_group" "main" { resource "azurerm_virtual_network" "main" { name = "${var.prefix}-network" address_space = ["10.0.0.0/16"] - location = "${azurerm_resource_group.main.location}" - resource_group_name = "${azurerm_resource_group.main.name}" + location = azurerm_resource_group.main.location + resource_group_name = azurerm_resource_group.main.name } resource "azurerm_subnet" "internal" { name = "internal" - resource_group_name = "${azurerm_resource_group.main.name}" - virtual_network_name = "${azurerm_virtual_network.main.name}" + resource_group_name = azurerm_resource_group.main.name + virtual_network_name = azurerm_virtual_network.main.name address_prefixes = ["10.0.2.0/24"] } diff --git a/examples/vm-scale-set/linux/system-assigned-identity/main.tf b/examples/vm-scale-set/linux/system-assigned-identity/main.tf index 31ba3692687c..5f5031b813d2 100644 --- a/examples/vm-scale-set/linux/system-assigned-identity/main.tf +++ b/examples/vm-scale-set/linux/system-assigned-identity/main.tf @@ -10,14 +10,14 @@ resource "azurerm_resource_group" "main" { resource "azurerm_virtual_network" "main" { name = "${var.prefix}-network" address_space = ["10.0.0.0/16"] - location = "${azurerm_resource_group.main.location}" - resource_group_name = "${azurerm_resource_group.main.name}" + location = azurerm_resource_group.main.location + resource_group_name = azurerm_resource_group.main.name } resource "azurerm_subnet" "internal" { name = "internal" - resource_group_name = "${azurerm_resource_group.main.name}" - virtual_network_name = "${azurerm_virtual_network.main.name}" + resource_group_name = azurerm_resource_group.main.name + virtual_network_name = azurerm_virtual_network.main.name address_prefixes = ["10.0.2.0/24"] } diff --git a/examples/vm-scale-set/linux/user-assigned-identity/main.tf b/examples/vm-scale-set/linux/user-assigned-identity/main.tf index 19674e1acbd1..5d36f7c81132 100644 --- a/examples/vm-scale-set/linux/user-assigned-identity/main.tf +++ b/examples/vm-scale-set/linux/user-assigned-identity/main.tf @@ -10,14 +10,14 @@ resource "azurerm_resource_group" "main" { resource "azurerm_virtual_network" "main" { name = "${var.prefix}-network" address_space = ["10.0.0.0/16"] - location = "${azurerm_resource_group.main.location}" - resource_group_name = "${azurerm_resource_group.main.name}" + location = azurerm_resource_group.main.location + resource_group_name = azurerm_resource_group.main.name } resource "azurerm_subnet" "internal" { name = "internal" - resource_group_name = "${azurerm_resource_group.main.name}" - virtual_network_name = "${azurerm_virtual_network.main.name}" + resource_group_name = azurerm_resource_group.main.name + virtual_network_name = azurerm_virtual_network.main.name address_prefixes = ["10.0.2.0/24"] } diff --git a/examples/vm-scale-set/linux/zones/main.tf b/examples/vm-scale-set/linux/zones/main.tf index 70601f615f94..f29a29e94c2b 100644 --- a/examples/vm-scale-set/linux/zones/main.tf +++ b/examples/vm-scale-set/linux/zones/main.tf @@ -10,14 +10,14 @@ resource "azurerm_resource_group" "main" { resource "azurerm_virtual_network" "main" { name = "${var.prefix}-network" address_space = ["10.0.0.0/16"] - location = "${azurerm_resource_group.main.location}" - resource_group_name = "${azurerm_resource_group.main.name}" + location = azurerm_resource_group.main.location + resource_group_name = azurerm_resource_group.main.name } resource "azurerm_subnet" "internal" { name = "internal" - resource_group_name = "${azurerm_resource_group.main.name}" - virtual_network_name = "${azurerm_virtual_network.main.name}" + resource_group_name = azurerm_resource_group.main.name + virtual_network_name = azurerm_virtual_network.main.name address_prefixes = ["10.0.2.0/24"] } diff --git a/examples/vm-scale-set/windows/basic/main.tf b/examples/vm-scale-set/windows/basic/main.tf index 9e94b1c230e8..e48820f3f284 100644 --- a/examples/vm-scale-set/windows/basic/main.tf +++ b/examples/vm-scale-set/windows/basic/main.tf @@ -10,14 +10,14 @@ resource "azurerm_resource_group" "main" { resource "azurerm_virtual_network" "main" { name = "${var.prefix}-network" address_space = ["10.0.0.0/16"] - location = "${azurerm_resource_group.main.location}" - resource_group_name = "${azurerm_resource_group.main.name}" + location = azurerm_resource_group.main.location + resource_group_name = azurerm_resource_group.main.name } resource "azurerm_subnet" "internal" { name = "internal" - resource_group_name = "${azurerm_resource_group.main.name}" - virtual_network_name = "${azurerm_virtual_network.main.name}" + resource_group_name = azurerm_resource_group.main.name + virtual_network_name = azurerm_virtual_network.main.name address_prefixes = ["10.0.2.0/24"] } diff --git a/examples/vm-scale-set/windows/boot-diagnostics/main.tf b/examples/vm-scale-set/windows/boot-diagnostics/main.tf index 3cc843bdaa7b..c144559f4096 100644 --- a/examples/vm-scale-set/windows/boot-diagnostics/main.tf +++ b/examples/vm-scale-set/windows/boot-diagnostics/main.tf @@ -10,14 +10,14 @@ resource "azurerm_resource_group" "main" { resource "azurerm_virtual_network" "main" { name = "${var.prefix}-network" address_space = ["10.0.0.0/16"] - location = "${azurerm_resource_group.main.location}" - resource_group_name = "${azurerm_resource_group.main.name}" + location = azurerm_resource_group.main.location + resource_group_name = azurerm_resource_group.main.name } resource "azurerm_subnet" "internal" { name = "internal" - resource_group_name = "${azurerm_resource_group.main.name}" - virtual_network_name = "${azurerm_virtual_network.main.name}" + resource_group_name = azurerm_resource_group.main.name + virtual_network_name = azurerm_virtual_network.main.name address_prefixes = ["10.0.2.0/24"] } @@ -62,6 +62,6 @@ resource "azurerm_windows_virtual_machine_scale_set" "main" { } boot_diagnostics { - storage_account_uri = azurerm_storage_account.test.primary_blob_endpoint + storage_account_uri = azurerm_storage_account.main.primary_blob_endpoint } } diff --git a/examples/vm-scale-set/windows/custom-data/main.tf b/examples/vm-scale-set/windows/custom-data/main.tf index d49eee980f20..d31576d7421e 100644 --- a/examples/vm-scale-set/windows/custom-data/main.tf +++ b/examples/vm-scale-set/windows/custom-data/main.tf @@ -10,14 +10,14 @@ resource "azurerm_resource_group" "main" { resource "azurerm_virtual_network" "main" { name = "${var.prefix}-network" address_space = ["10.0.0.0/16"] - location = "${azurerm_resource_group.main.location}" - resource_group_name = "${azurerm_resource_group.main.name}" + location = azurerm_resource_group.main.location + resource_group_name = azurerm_resource_group.main.name } resource "azurerm_subnet" "internal" { name = "internal" - resource_group_name = "${azurerm_resource_group.main.name}" - virtual_network_name = "${azurerm_virtual_network.main.name}" + resource_group_name = azurerm_resource_group.main.name + virtual_network_name = azurerm_virtual_network.main.name address_prefixes = ["10.0.2.0/24"] } diff --git a/examples/vm-scale-set/windows/custom-timezone/main.tf b/examples/vm-scale-set/windows/custom-timezone/main.tf index 4013ea598a71..2cd53337c2db 100644 --- a/examples/vm-scale-set/windows/custom-timezone/main.tf +++ b/examples/vm-scale-set/windows/custom-timezone/main.tf @@ -10,14 +10,14 @@ resource "azurerm_resource_group" "main" { resource "azurerm_virtual_network" "main" { name = "${var.prefix}-network" address_space = ["10.0.0.0/16"] - location = "${azurerm_resource_group.main.location}" - resource_group_name = "${azurerm_resource_group.main.name}" + location = azurerm_resource_group.main.location + resource_group_name = azurerm_resource_group.main.name } resource "azurerm_subnet" "internal" { name = "internal" - resource_group_name = "${azurerm_resource_group.main.name}" - virtual_network_name = "${azurerm_virtual_network.main.name}" + resource_group_name = azurerm_resource_group.main.name + virtual_network_name = azurerm_virtual_network.main.name address_prefixes = ["10.0.2.0/24"] } diff --git a/examples/vm-scale-set/windows/data-disks/main.tf b/examples/vm-scale-set/windows/data-disks/main.tf index cdaaa30f007e..fdcc04b61eb3 100644 --- a/examples/vm-scale-set/windows/data-disks/main.tf +++ b/examples/vm-scale-set/windows/data-disks/main.tf @@ -10,14 +10,14 @@ resource "azurerm_resource_group" "main" { resource "azurerm_virtual_network" "main" { name = "${var.prefix}-network" address_space = ["10.0.0.0/16"] - location = "${azurerm_resource_group.main.location}" - resource_group_name = "${azurerm_resource_group.main.name}" + location = azurerm_resource_group.main.location + resource_group_name = azurerm_resource_group.main.name } resource "azurerm_subnet" "internal" { name = "internal" - resource_group_name = "${azurerm_resource_group.main.name}" - virtual_network_name = "${azurerm_virtual_network.main.name}" + resource_group_name = azurerm_resource_group.main.name + virtual_network_name = azurerm_virtual_network.main.name address_prefixes = ["10.0.2.0/24"] } diff --git a/examples/vm-scale-set/windows/ephemeral-os-disk/main.tf b/examples/vm-scale-set/windows/ephemeral-os-disk/main.tf index 6d09db723253..9d60b6a22dd4 100644 --- a/examples/vm-scale-set/windows/ephemeral-os-disk/main.tf +++ b/examples/vm-scale-set/windows/ephemeral-os-disk/main.tf @@ -10,14 +10,14 @@ resource "azurerm_resource_group" "main" { resource "azurerm_virtual_network" "main" { name = "${var.prefix}-network" address_space = ["10.0.0.0/16"] - location = "${azurerm_resource_group.main.location}" - resource_group_name = "${azurerm_resource_group.main.name}" + location = azurerm_resource_group.main.location + resource_group_name = azurerm_resource_group.main.name } resource "azurerm_subnet" "internal" { name = "internal" - resource_group_name = "${azurerm_resource_group.main.name}" - virtual_network_name = "${azurerm_virtual_network.main.name}" + resource_group_name = azurerm_resource_group.main.name + virtual_network_name = azurerm_virtual_network.main.name address_prefixes = ["10.0.2.0/24"] } diff --git a/examples/vm-scale-set/windows/extensions/README.md b/examples/vm-scale-set/windows/extensions/README.md new file mode 100644 index 000000000000..3ac1e4029928 --- /dev/null +++ b/examples/vm-scale-set/windows/extensions/README.md @@ -0,0 +1,3 @@ +## Example: Windows Virtual Machine Scale Set with VM Extensions + +This example provisions a basic Windows Virtual Machine Scale Set with two VM Extensions. diff --git a/examples/vm-scale-set/windows/extensions/main.tf b/examples/vm-scale-set/windows/extensions/main.tf new file mode 100644 index 000000000000..21a7cbe8bae8 --- /dev/null +++ b/examples/vm-scale-set/windows/extensions/main.tf @@ -0,0 +1,77 @@ +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "main" { + name = "${var.prefix}-resources" + location = var.location +} + +resource "azurerm_virtual_network" "main" { + name = "${var.prefix}-network" + address_space = ["10.0.0.0/16"] + location = azurerm_resource_group.main.location + resource_group_name = azurerm_resource_group.main.name +} + +resource "azurerm_subnet" "internal" { + name = "internal" + resource_group_name = azurerm_resource_group.main.name + virtual_network_name = azurerm_virtual_network.main.name + address_prefixes = ["10.0.2.0/24"] +} + +resource "azurerm_windows_virtual_machine_scale_set" "main" { + name = "${var.prefix}vmss" + resource_group_name = azurerm_resource_group.main.name + location = azurerm_resource_group.main.location + sku = "Standard_F2" + instances = 3 + admin_username = "adminuser" + admin_password = "P@ssw0rd1234!" + computer_name_prefix = var.prefix + + source_image_reference { + publisher = "MicrosoftWindowsServer" + offer = "WindowsServer" + sku = "2019-Datacenter" + version = "latest" + } + + network_interface { + name = "example" + primary = true + + ip_configuration { + name = "internal" + primary = true + subnet_id = azurerm_subnet.internal.id + } + } + + os_disk { + storage_account_type = "Standard_LRS" + caching = "ReadWrite" + } + + extension { + name = "CustomScript" + publisher = "Microsoft.Compute" + type = "CustomScriptExtension" + type_handler_version = "1.10" + auto_upgrade_minor_version = true + + settings = jsonencode({ "commandToExecute" = "powershell.exe -c \"Get-Content env:computername\"" }) + + protected_settings = jsonencode({ "managedIdentity" = {} }) + } + + extension { + name = "AADLoginForWindows" + publisher = "Microsoft.Azure.ActiveDirectory" + type = "AADLoginForWindows" + type_handler_version = "1.0" + auto_upgrade_minor_version = true + } + +} diff --git a/examples/vm-scale-set/windows/extensions/variables.tf b/examples/vm-scale-set/windows/extensions/variables.tf new file mode 100644 index 000000000000..68babb00b91a --- /dev/null +++ b/examples/vm-scale-set/windows/extensions/variables.tf @@ -0,0 +1,7 @@ +variable "prefix" { + description = "The prefix which should be used for all resources in this example" +} + +variable "location" { + description = "The Azure Region in which all resources in this example should be created." +} diff --git a/examples/vm-scale-set/windows/hybrid-use-benefit/main.tf b/examples/vm-scale-set/windows/hybrid-use-benefit/main.tf index 7749205e1fdb..9f89ba64b445 100644 --- a/examples/vm-scale-set/windows/hybrid-use-benefit/main.tf +++ b/examples/vm-scale-set/windows/hybrid-use-benefit/main.tf @@ -10,14 +10,14 @@ resource "azurerm_resource_group" "main" { resource "azurerm_virtual_network" "main" { name = "${var.prefix}-network" address_space = ["10.0.0.0/16"] - location = "${azurerm_resource_group.main.location}" - resource_group_name = "${azurerm_resource_group.main.name}" + location = azurerm_resource_group.main.location + resource_group_name = azurerm_resource_group.main.name } resource "azurerm_subnet" "internal" { name = "internal" - resource_group_name = "${azurerm_resource_group.main.name}" - virtual_network_name = "${azurerm_virtual_network.main.name}" + resource_group_name = azurerm_resource_group.main.name + virtual_network_name = azurerm_virtual_network.main.name address_prefixes = ["10.0.2.0/24"] } diff --git a/examples/vm-scale-set/windows/multiple-nics/main.tf b/examples/vm-scale-set/windows/multiple-nics/main.tf index 58a02a565459..2b331b9687dc 100644 --- a/examples/vm-scale-set/windows/multiple-nics/main.tf +++ b/examples/vm-scale-set/windows/multiple-nics/main.tf @@ -10,14 +10,14 @@ resource "azurerm_resource_group" "main" { resource "azurerm_virtual_network" "main" { name = "${var.prefix}-network" address_space = ["10.0.0.0/16"] - location = "${azurerm_resource_group.main.location}" - resource_group_name = "${azurerm_resource_group.main.name}" + location = azurerm_resource_group.main.location + resource_group_name = azurerm_resource_group.main.name } resource "azurerm_subnet" "internal" { name = "internal" - resource_group_name = "${azurerm_resource_group.main.name}" - virtual_network_name = "${azurerm_virtual_network.main.name}" + resource_group_name = azurerm_resource_group.main.name + virtual_network_name = azurerm_virtual_network.main.name address_prefixes = ["10.0.2.0/24"] } diff --git a/examples/vm-scale-set/windows/public-ip-per-instance/main.tf b/examples/vm-scale-set/windows/public-ip-per-instance/main.tf index 1c3508c51417..f9b134baf229 100644 --- a/examples/vm-scale-set/windows/public-ip-per-instance/main.tf +++ b/examples/vm-scale-set/windows/public-ip-per-instance/main.tf @@ -10,21 +10,21 @@ resource "azurerm_resource_group" "main" { resource "azurerm_virtual_network" "main" { name = "${var.prefix}-network" address_space = ["10.0.0.0/16"] - location = "${azurerm_resource_group.main.location}" - resource_group_name = "${azurerm_resource_group.main.name}" + location = azurerm_resource_group.main.location + resource_group_name = azurerm_resource_group.main.name } resource "azurerm_subnet" "internal" { name = "internal" - resource_group_name = "${azurerm_resource_group.main.name}" - virtual_network_name = "${azurerm_virtual_network.main.name}" + resource_group_name = azurerm_resource_group.main.name + virtual_network_name = azurerm_virtual_network.main.name address_prefixes = ["10.0.2.0/24"] } resource "azurerm_public_ip_prefix" "main" { name = "${var.prefix}-pip" - location = azurerm_resource_group.test.location - resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.main.location + resource_group_name = azurerm_resource_group.main.name } resource "azurerm_windows_virtual_machine_scale_set" "main" { diff --git a/examples/vm-scale-set/windows/rolling-upgrade-policy/main.tf b/examples/vm-scale-set/windows/rolling-upgrade-policy/main.tf index 0da3c5a4e09e..e812ff6323ce 100644 --- a/examples/vm-scale-set/windows/rolling-upgrade-policy/main.tf +++ b/examples/vm-scale-set/windows/rolling-upgrade-policy/main.tf @@ -10,14 +10,14 @@ resource "azurerm_resource_group" "main" { resource "azurerm_virtual_network" "main" { name = "${var.prefix}-network" address_space = ["10.0.0.0/16"] - location = "${azurerm_resource_group.main.location}" - resource_group_name = "${azurerm_resource_group.main.name}" + location = azurerm_resource_group.main.location + resource_group_name = azurerm_resource_group.main.name } resource "azurerm_subnet" "internal" { name = "internal" - resource_group_name = "${azurerm_resource_group.main.name}" - virtual_network_name = "${azurerm_virtual_network.main.name}" + resource_group_name = azurerm_resource_group.main.name + virtual_network_name = azurerm_virtual_network.main.name address_prefixes = ["10.0.2.0/24"] } @@ -28,7 +28,7 @@ resource "azurerm_public_ip" "main" { allocation_method = "Static" } -resource "azurerm_lb" "test" { +resource "azurerm_lb" "main" { name = "${var.prefix}-lb" location = azurerm_resource_group.main.location resource_group_name = azurerm_resource_group.main.name diff --git a/examples/vm-scale-set/windows/secrets/main.tf b/examples/vm-scale-set/windows/secrets/main.tf index c5b57d3844c1..0aea8ca94939 100644 --- a/examples/vm-scale-set/windows/secrets/main.tf +++ b/examples/vm-scale-set/windows/secrets/main.tf @@ -10,14 +10,14 @@ resource "azurerm_resource_group" "main" { resource "azurerm_virtual_network" "main" { name = "${var.prefix}-network" address_space = ["10.0.0.0/16"] - location = "${azurerm_resource_group.main.location}" - resource_group_name = "${azurerm_resource_group.main.name}" + location = azurerm_resource_group.main.location + resource_group_name = azurerm_resource_group.main.name } resource "azurerm_subnet" "internal" { name = "internal" - resource_group_name = "${azurerm_resource_group.main.name}" - virtual_network_name = "${azurerm_virtual_network.main.name}" + resource_group_name = azurerm_resource_group.main.name + virtual_network_name = azurerm_virtual_network.main.name address_prefixes = ["10.0.2.0/24"] } data "azurerm_client_config" "current" {} @@ -117,7 +117,7 @@ resource "azurerm_key_vault" "main" { access_policy { tenant_id = data.azurerm_client_config.current.tenant_id - object_id = data.azurerm_client_config.current._object_id + object_id = data.azurerm_client_config.current.object_id certificate_permissions = [ "create", diff --git a/examples/vm-scale-set/windows/service-fabric/3-service-fabric.tf b/examples/vm-scale-set/windows/service-fabric/3-service-fabric.tf index fe1d98b5e0b2..c1486393a2a0 100644 --- a/examples/vm-scale-set/windows/service-fabric/3-service-fabric.tf +++ b/examples/vm-scale-set/windows/service-fabric/3-service-fabric.tf @@ -5,7 +5,7 @@ resource "azurerm_service_fabric_cluster" "main" { reliability_level = "Bronze" upgrade_mode = "Automatic" vm_image = "Windows" - management_endpoint = "https://${azurerm_public_ip.test.fqdn}:19080" + management_endpoint = "https://${azurerm_public_ip.main.fqdn}:19080" add_on_features = ["DnsService"] node_type { diff --git a/examples/vm-scale-set/windows/spot/main.tf b/examples/vm-scale-set/windows/spot/main.tf index c6a02763911a..1a2c0b4c45b7 100644 --- a/examples/vm-scale-set/windows/spot/main.tf +++ b/examples/vm-scale-set/windows/spot/main.tf @@ -10,14 +10,14 @@ resource "azurerm_resource_group" "main" { resource "azurerm_virtual_network" "main" { name = "${var.prefix}-network" address_space = ["10.0.0.0/16"] - location = "${azurerm_resource_group.main.location}" - resource_group_name = "${azurerm_resource_group.main.name}" + location = azurerm_resource_group.main.location + resource_group_name = azurerm_resource_group.main.name } resource "azurerm_subnet" "internal" { name = "internal" - resource_group_name = "${azurerm_resource_group.main.name}" - virtual_network_name = "${azurerm_virtual_network.main.name}" + resource_group_name = azurerm_resource_group.main.name + virtual_network_name = azurerm_virtual_network.main.name address_prefixes = ["10.0.2.0/24"] } diff --git a/examples/vm-scale-set/windows/system-assigned-identity/main.tf b/examples/vm-scale-set/windows/system-assigned-identity/main.tf index 52016a1e4d06..fbccf70d75cf 100644 --- a/examples/vm-scale-set/windows/system-assigned-identity/main.tf +++ b/examples/vm-scale-set/windows/system-assigned-identity/main.tf @@ -10,14 +10,14 @@ resource "azurerm_resource_group" "main" { resource "azurerm_virtual_network" "main" { name = "${var.prefix}-network" address_space = ["10.0.0.0/16"] - location = "${azurerm_resource_group.main.location}" - resource_group_name = "${azurerm_resource_group.main.name}" + location = azurerm_resource_group.main.location + resource_group_name = azurerm_resource_group.main.name } resource "azurerm_subnet" "internal" { name = "internal" - resource_group_name = "${azurerm_resource_group.main.name}" - virtual_network_name = "${azurerm_virtual_network.main.name}" + resource_group_name = azurerm_resource_group.main.name + virtual_network_name = azurerm_virtual_network.main.name address_prefixes = ["10.0.2.0/24"] } diff --git a/examples/vm-scale-set/windows/user-assigned-identity/main.tf b/examples/vm-scale-set/windows/user-assigned-identity/main.tf index c965b963e79e..b4d0fbdf5118 100644 --- a/examples/vm-scale-set/windows/user-assigned-identity/main.tf +++ b/examples/vm-scale-set/windows/user-assigned-identity/main.tf @@ -10,14 +10,14 @@ resource "azurerm_resource_group" "main" { resource "azurerm_virtual_network" "main" { name = "${var.prefix}-network" address_space = ["10.0.0.0/16"] - location = "${azurerm_resource_group.main.location}" - resource_group_name = "${azurerm_resource_group.main.name}" + location = azurerm_resource_group.main.location + resource_group_name = azurerm_resource_group.main.name } resource "azurerm_subnet" "internal" { name = "internal" - resource_group_name = "${azurerm_resource_group.main.name}" - virtual_network_name = "${azurerm_virtual_network.main.name}" + resource_group_name = azurerm_resource_group.main.name + virtual_network_name = azurerm_virtual_network.main.name address_prefixes = ["10.0.2.0/24"] } diff --git a/examples/vm-scale-set/windows/zones/main.tf b/examples/vm-scale-set/windows/zones/main.tf index 0b74c668cf0a..ab4daabc4b7c 100644 --- a/examples/vm-scale-set/windows/zones/main.tf +++ b/examples/vm-scale-set/windows/zones/main.tf @@ -10,14 +10,14 @@ resource "azurerm_resource_group" "main" { resource "azurerm_virtual_network" "main" { name = "${var.prefix}-network" address_space = ["10.0.0.0/16"] - location = "${azurerm_resource_group.main.location}" - resource_group_name = "${azurerm_resource_group.main.name}" + location = azurerm_resource_group.main.location + resource_group_name = azurerm_resource_group.main.name } resource "azurerm_subnet" "internal" { name = "internal" - resource_group_name = "${azurerm_resource_group.main.name}" - virtual_network_name = "${azurerm_virtual_network.main.name}" + resource_group_name = azurerm_resource_group.main.name + virtual_network_name = azurerm_virtual_network.main.name address_prefixes = ["10.0.2.0/24"] } diff --git a/website/docs/r/linux_virtual_machine_scale_set.html.markdown b/website/docs/r/linux_virtual_machine_scale_set.html.markdown index ba939fd6452b..2bb4c6e1a9ab 100644 --- a/website/docs/r/linux_virtual_machine_scale_set.html.markdown +++ b/website/docs/r/linux_virtual_machine_scale_set.html.markdown @@ -144,6 +144,10 @@ The following arguments are supported: * `do_not_run_extensions_on_overprovisioned_machines` - (Optional) Should Virtual Machine Extensions be run on Overprovisioned Virtual Machines in the Scale Set? Defaults to `false`. +* `extension` - (Optional) One or more `extension` blocks as defined below + +!> **NOTE:** This block is only available in the Opt-In beta and requires that the Environment Variable `ARM_PROVIDER_VMSS_EXTENSIONS_BETA` is set to `true` to be used. + * `eviction_policy` - (Optional) The Policy which should be used Virtual Machines are Evicted from the Scale Set. Changing this forces a new resource to be created. -> **NOTE:** This can only be configured when `priority` is set to `Spot`. @@ -276,6 +280,38 @@ A `diff_disk_settings` block supports the following: --- +An `extension` block supports the following: + +!> **NOTE:** This block is only available in the Opt-In beta and requires that the Environment Variable `ARM_PROVIDER_VMSS_EXTENSIONS_BETA` is set to `true` to be used. + +* `name` - (Required) The name for the Virtual Machine Scale Set Extension. + +* `publisher` - (Required) Specifies the Publisher of the Extension. + +* `type` - (Required) Specifies the Type of the Extension. + +* `type_handler_version` - (Required) Specifies the version of the extension to use, available versions can be found using the Azure CLI. + +* `auto_upgrade_minor_version` - (Optional) Should the latest version of the Extension be used at Deployment Time, if one is available? This won't auto-update the extension on existing installation. Defaults to `true`. + +* `force_update_tag` - (Optional) A value which, when different to the previous value can be used to force-run the Extension even if the Extension Configuration hasn't changed. + +* `protected_settings` - (Optional) A JSON String which specifies Sensitive Settings (such as Passwords) for the Extension. + +~> **NOTE:** Keys within the `protected_settings` block are notoriously case-sensitive, where the casing required (e.g. TitleCase vs snakeCase) depends on the Extension being used. Please refer to the documentation for the specific Virtual Machine Extension you're looking to use for more information. + +-> **Note:** Rather than defining JSON inline [you can use the `jsonencode` interpolation function](https://www.terraform.io/docs/configuration/functions/jsonencode.html) to define this in a cleaner way. + +* `provision_after_extensions` - (Optional) An ordered list of Extension names which this should be provisioned after. + +* `settings` - (Optional) A JSON String which specifies Settings for the Extension. + +~> **NOTE:** Keys within the `settings` block are notoriously case-sensitive, where the casing required (e.g. TitleCase vs snakeCase) depends on the Extension being used. Please refer to the documentation for the specific Virtual Machine Extension you're looking to use for more information. + +-> **Note:** Rather than defining JSON inline [you can use the `jsonencode` interpolation function](https://www.terraform.io/docs/configuration/functions/jsonencode.html) to define this in a cleaner way. + +--- + A `identity` block supports the following: * `type` - (Required) The type of Managed Identity which should be assigned to the Linux Virtual Machine Scale Set. Possible values are `SystemAssigned`, `UserAssigned` and `SystemAssigned, UserAssigned`. diff --git a/website/docs/r/service_fabric_cluster.html.markdown b/website/docs/r/service_fabric_cluster.html.markdown index 500b328a994b..43532900b611 100644 --- a/website/docs/r/service_fabric_cluster.html.markdown +++ b/website/docs/r/service_fabric_cluster.html.markdown @@ -24,7 +24,7 @@ resource "azurerm_service_fabric_cluster" "example" { location = azurerm_resource_group.example.location reliability_level = "Bronze" upgrade_mode = "Manual" - cluster_code_version = "6.5.639.9590" + cluster_code_version = "7.1.456.959" vm_image = "Windows" management_endpoint = "https://example:80" @@ -36,6 +36,7 @@ resource "azurerm_service_fabric_cluster" "example" { http_endpoint_port = 80 } } + ``` ## Argument Reference @@ -145,7 +146,7 @@ A `client_certificate_thumbprint` block supports the following: A `client_certificate_common_name` block supports the following: -* `certificate_common_name` - (Required) The common or subject name of the certificate. +* `common_name` - (Required) The common or subject name of the certificate. * `certificate_issuer_thumbprint` - (Optional) The Issuer Thumbprint of the Certificate. diff --git a/website/docs/r/windows_virtual_machine_scale_set.html.markdown b/website/docs/r/windows_virtual_machine_scale_set.html.markdown index b4abb5ad5965..10f17c52bbf5 100644 --- a/website/docs/r/windows_virtual_machine_scale_set.html.markdown +++ b/website/docs/r/windows_virtual_machine_scale_set.html.markdown @@ -130,6 +130,10 @@ The following arguments are supported: * `enable_automatic_updates` - (Optional) Are automatic updates enabled for this Virtual Machine? Defaults to `true`. +* `extension` - (Optional) One or more `extension` blocks as defined below + +!> **NOTE:** This block is only available in the Opt-In beta and requires that the Environment Variable `ARM_PROVIDER_VMSS_EXTENSIONS_BETA` is set to `true` to be used. + * `eviction_policy` - (Optional) The Policy which should be used Virtual Machines are Evicted from the Scale Set. Changing this forces a new resource to be created. -> **NOTE:** This can only be configured when `priority` is set to `Spot`. @@ -266,6 +270,38 @@ A `diff_disk_settings` block supports the following: --- +An `extension` block supports the following: + +!> **NOTE:** This block is only available in the Opt-In beta and requires that the Environment Variable `ARM_PROVIDER_VMSS_EXTENSIONS_BETA` is set to `true` to be used. + +* `name` - (Required) The name for the Virtual Machine Scale Set Extension. + +* `publisher` - (Required) Specifies the Publisher of the Extension. + +* `type` - (Required) Specifies the Type of the Extension. + +* `type_handler_version` - (Required) Specifies the version of the extension to use, available versions can be found using the Azure CLI. + +* `auto_upgrade_minor_version` - (Optional) Should the latest version of the Extension be used at Deployment Time, if one is available? This won't auto-update the extension on existing installation. Defaults to `true`. + +* `force_update_tag` - (Optional) A value which, when different to the previous value can be used to force-run the Extension even if the Extension Configuration hasn't changed. + +* `protected_settings` - (Optional) A JSON String which specifies Sensitive Settings (such as Passwords) for the Extension. + +~> **NOTE:** Keys within the `protected_settings` block are notoriously case-sensitive, where the casing required (e.g. TitleCase vs snakeCase) depends on the Extension being used. Please refer to the documentation for the specific Virtual Machine Extension you're looking to use for more information. + +-> **Note:** Rather than defining JSON inline [you can use the `jsonencode` interpolation function](https://www.terraform.io/docs/configuration/functions/jsonencode.html) to define this in a cleaner way. + +* `provision_after_extensions` - (Optional) An ordered list of Extension names which this should be provisioned after. + +* `settings` - (Optional) A JSON String which specifies Settings for the Extension. + +~> **NOTE:** Keys within the `settings` block are notoriously case-sensitive, where the casing required (e.g. TitleCase vs snakeCase) depends on the Extension being used. Please refer to the documentation for the specific Virtual Machine Extension you're looking to use for more information. + +-> **Note:** Rather than defining JSON inline [you can use the `jsonencode` interpolation function](https://www.terraform.io/docs/configuration/functions/jsonencode.html) to define this in a cleaner way. + +--- + A `identity` block supports the following: * `type` - (Required) The type of Managed Identity which should be assigned to the Windows Virtual Machine Scale Set. Possible values are `SystemAssigned`, `UserAssigned` and `SystemAssigned, UserAssigned`.