diff --git a/internal/services/storagemover/scripts/install_arc.sh.tftpl b/internal/services/storagemover/scripts/install_arc.sh.tftpl new file mode 100644 index 0000000000000..a44495683a45a --- /dev/null +++ b/internal/services/storagemover/scripts/install_arc.sh.tftpl @@ -0,0 +1,54 @@ +#!/bin/bash + +# Disable the Azure VM Guest Agent. +current_hostname=$(hostname) +sudo service walinuxagent stop +sudo waagent -deprovision -force +sudo rm -rf /var/lib/waagent +sudo hostnamectl set-hostname $current_hostname + +# Block access to the Azure IMDS endpoint. +sudo ufw --force enable +sudo ufw deny out from any to 169.254.169.254 +sudo ufw default allow incoming + +# Add the service principal application ID and secret here +servicePrincipalClientId="${client_id}" +servicePrincipalSecret="${client_secret}" +cloud="AzureCloud" +tenantId="${tenant_id}" +subscriptionId="${subscription_id}" +resourceGroup="${resource_group_name}" +location="${location}" +authType="principal" +correlationId="${uuid}" +output="$(wget https://aka.ms/azcmagent -O ~/install_linux_azcmagent.sh 2>&1)" +if [ $? != 0 ]; then + read -d '' bodyData < /dev/null || true +fi +echo "$output" +sudo chmod +x ~/install_linux_azcmagent.sh +cd ~ +./install_linux_azcmagent.sh +sudo azcmagent connect \ + --service-principal-id "$servicePrincipalClientId" \ + --service-principal-secret "$servicePrincipalSecret" \ + --cloud "$cloud" \ + --tenant-id "$tenantId" \ + --subscription-id "$subscriptionId" \ + --resource-group "$resourceGroup" \ + --location "$location" \ + --correlation-id "$correlationId" \ No newline at end of file diff --git a/internal/services/storagemover/storage_mover_agent_resource.go b/internal/services/storagemover/storage_mover_agent_resource.go index 7d380cef0fb11..43e04af4dbd46 100644 --- a/internal/services/storagemover/storage_mover_agent_resource.go +++ b/internal/services/storagemover/storage_mover_agent_resource.go @@ -15,11 +15,11 @@ import ( ) type StorageMoverAgentResourceModel struct { - Name string `tfschema:"name"` - StorageMoverId string `tfschema:"storage_mover_id"` - ArcResourceId string `tfschema:"arc_resource_id"` - ArcVmUuid string `tfschema:"arc_vm_uuid"` - Description string `tfschema:"description"` + Name string `tfschema:"name"` + StorageMoverId string `tfschema:"storage_mover_id"` + ArcVirtualMachineId string `tfschema:"arc_virtual_machine_id"` + ArcVmUuid string `tfschema:"arc_vm_uuid"` + Description string `tfschema:"description"` } type StorageMoverAgentResource struct{} @@ -47,7 +47,7 @@ func (r StorageMoverAgentResource) Arguments() map[string]*pluginsdk.Schema { ValidateFunc: validation.StringIsNotEmpty, }, - "arc_resource_id": { + "arc_virtual_machine_id": { Type: pluginsdk.TypeString, Required: true, ForceNew: true, @@ -108,7 +108,7 @@ func (r StorageMoverAgentResource) Create() sdk.ResourceFunc { properties := agents.Agent{ Properties: agents.AgentProperties{ - ArcResourceId: model.ArcResourceId, + ArcResourceId: model.ArcVirtualMachineId, ArcVMUuid: model.ArcVmUuid, }, } @@ -185,27 +185,21 @@ func (r StorageMoverAgentResource) Read() sdk.ResourceFunc { return fmt.Errorf("retrieving %s: %+v", *id, err) } - model := resp.Model - if model == nil { - return fmt.Errorf("retrieving %s: model was nil", *id) - } - state := StorageMoverAgentResourceModel{ Name: id.AgentName, StorageMoverId: storagemovers.NewStorageMoverID(id.SubscriptionId, id.ResourceGroupName, id.StorageMoverName).ID(), } - properties := &model.Properties + if model := resp.Model; model != nil { + state.ArcVmUuid = model.Properties.ArcVMUuid + state.ArcVirtualMachineId = model.Properties.ArcResourceId - state.ArcVmUuid = properties.ArcVMUuid - - state.ArcResourceId = properties.ArcResourceId - - des := "" - if properties.Description != nil { - des = *properties.Description + des := "" + if model.Properties.Description != nil { + des = *model.Properties.Description + } + state.Description = des } - state.Description = des return metadata.Encode(&state) }, diff --git a/internal/services/storagemover/storage_mover_agent_resource_test.go b/internal/services/storagemover/storage_mover_agent_resource_test.go index f2187c194e18a..dbb68e65a65f8 100644 --- a/internal/services/storagemover/storage_mover_agent_resource_test.go +++ b/internal/services/storagemover/storage_mover_agent_resource_test.go @@ -3,8 +3,11 @@ package storagemover_test import ( "context" "fmt" + "os" "testing" + "github.com/hashicorp/go-uuid" + "github.com/hashicorp/go-azure-sdk/resource-manager/storagemover/2023-03-01/agents" "github.com/hashicorp/go-azure-helpers/lang/response" @@ -34,6 +37,7 @@ func TestAccStorageMoverAgent_basic(t *testing.T) { func TestAccStorageMoverAgent_requiresImport(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_storage_mover_agent", "test") r := StorageMoverAgentTestResource{} + data.ResourceTest(t, r, []acceptance.TestStep{ { Config: r.basic(data), @@ -98,35 +102,169 @@ func (r StorageMoverAgentTestResource) Exists(ctx context.Context, clients *clie } func (r StorageMoverAgentTestResource) template(data acceptance.TestData) string { + randomUUID, _ := uuid.GenerateUUID() return fmt.Sprintf(` -provider "azurerm" { - features {} -} + + +data "azurerm_client_config" "current" {} resource "azurerm_resource_group" "test" { - name = "acctest-rg-%d" - location = "%s" + name = "acctestRG-%[1]d" + location = "%[2]s" +} + +resource "azurerm_virtual_network" "test" { + name = "acctestnw-%[1]d" + address_space = ["10.0.0.0/16"] + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name +} + +resource "azurerm_subnet" "test" { + name = "internal" + resource_group_name = azurerm_resource_group.test.name + virtual_network_name = azurerm_virtual_network.test.name + address_prefixes = ["10.0.2.0/24"] +} + +resource "azurerm_network_interface" "test" { + name = "acctestnic-%[1]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + + ip_configuration { + name = "internal" + subnet_id = azurerm_subnet.test.id + private_ip_address_allocation = "Dynamic" + public_ip_address_id = azurerm_public_ip.test.id + } +} + +resource "azurerm_network_security_group" "my_terraform_nsg" { + name = "myNetworkSecurityGroup" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + + security_rule { + name = "SSH" + priority = 1001 + direction = "Inbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "22" + source_address_prefix = "*" + destination_address_prefix = "*" + } +} + +resource "azurerm_network_interface_security_group_association" "example" { + network_interface_id = azurerm_network_interface.test.id + network_security_group_id = azurerm_network_security_group.my_terraform_nsg.id +} + +resource "azurerm_public_ip" "test" { + name = "acctestpip-%[1]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + allocation_method = "Static" +} + +resource "azurerm_linux_virtual_machine" "test" { + name = "acctestVM-%[1]d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + size = "Standard_F2" + admin_username = "adminuser" + admin_password = "TerraformTest01!" + provision_vm_agent = false + allow_extension_operations = false + disable_password_authentication = false + network_interface_ids = [ + azurerm_network_interface.test.id, + ] + + os_disk { + caching = "ReadWrite" + storage_account_type = "Standard_LRS" + } + + source_image_reference { + publisher = "Canonical" + offer = "UbuntuServer" + sku = "18.04-LTS" + version = "latest" + } + + connection { + type = "ssh" + host = azurerm_public_ip.test.ip_address + user = "adminuser" + password = "TerraformTest01!" + } + + provisioner "file" { + content = templatefile("scripts/install_arc.sh.tftpl", { + resource_group_name = azurerm_resource_group.test.name + uuid = "%[3]s" + location = azurerm_resource_group.test.location + tenant_id = data.azurerm_client_config.current.tenant_id + client_id = data.azurerm_client_config.current.client_id + client_secret = "%[4]s" + subscription_id = data.azurerm_client_config.current.subscription_id + }) + destination = "/home/adminuser/install_arc_agent.sh" + } + + provisioner "remote-exec" { + inline = [ + "sudo apt-get install -y python-ctypes", + "sudo sed -i 's/\r$//' /home/adminuser/install_arc_agent.sh", + "sudo chmod +x /home/adminuser/install_arc_agent.sh", + "bash /home/adminuser/install_arc_agent.sh", + ] + } +} + +data "azurerm_hybrid_compute_machine" "test" { + name = azurerm_linux_virtual_machine.test.name + resource_group_name = azurerm_resource_group.test.name + depends_on = [ + azurerm_linux_virtual_machine.test + ] } resource "azurerm_storage_mover" "test" { - name = "acctest-ssm-%d" + name = "acctest-ssm-%[1]d" resource_group_name = azurerm_resource_group.test.name location = azurerm_resource_group.test.location + depends_on = [ + data.azurerm_hybrid_compute_machine.test + ] } -`, data.RandomInteger, data.Locations.Primary, data.RandomInteger) + +`, data.RandomInteger, data.Locations.Primary, randomUUID, os.Getenv("ARM_CLIENT_SECRET")) } func (r StorageMoverAgentTestResource) basic(data acceptance.TestData) string { template := r.template(data) return fmt.Sprintf(` +provider "azurerm" { + features { + resource_group { + prevent_deletion_if_contains_resources = false + } + } +} + %s resource "azurerm_storage_mover_agent" "test" { - name = "acctest-sa-%d" - storage_mover_id = azurerm_storage_mover.test.id - arc_resource_id = "${azurerm_resource_group.test.id}/providers/Microsoft.HybridCompute/machines/examples-hybridComputeName" - arc_vm_uuid = "3bb2c024-eba9-4d18-9e7a-1d772fcc5fe9" + name = "acctest-sa-%d" + storage_mover_id = azurerm_storage_mover.test.id + arc_virtual_machine_id = data.azurerm_hybrid_compute_machine.test.id + arc_vm_uuid = data.azurerm_hybrid_compute_machine.test.vm_uuid } `, template, data.RandomInteger) } @@ -134,15 +272,15 @@ resource "azurerm_storage_mover_agent" "test" { func (r StorageMoverAgentTestResource) requiresImport(data acceptance.TestData) string { config := r.basic(data) return fmt.Sprintf(` - %s resource "azurerm_storage_mover_agent" "import" { - name = azurerm_storage_mover_agent.test.name - storage_mover_id = azurerm_storage_mover_agent.test.storage_mover_id - arc_resource_id = azurerm_storage_mover_agent.test.arc_resource_id - arc_vm_uuid = azurerm_storage_mover_agent.test.arc_vm_uuid + name = azurerm_storage_mover_agent.test.name + storage_mover_id = azurerm_storage_mover_agent.test.storage_mover_id + arc_virtual_machine_id = azurerm_storage_mover_agent.test.arc_virtual_machine_id + arc_vm_uuid = azurerm_storage_mover_agent.test.arc_vm_uuid } + `, config) } @@ -150,14 +288,22 @@ func (r StorageMoverAgentTestResource) complete(data acceptance.TestData) string template := r.template(data) return fmt.Sprintf(` +provider "azurerm" { + features { + resource_group { + prevent_deletion_if_contains_resources = false + } + } +} + %s resource "azurerm_storage_mover_agent" "test" { - name = "acctest-sa-%d" - storage_mover_id = azurerm_storage_mover.test.id - arc_resource_id = "${azurerm_resource_group.test.id}/providers/Microsoft.HybridCompute/machines/examples-hybridComputeName" - arc_vm_uuid = "3bb2c024-eba9-4d18-9e7a-1d772fcc5fe9" - description = "Example Agent Description" + name = "acctest-sa-%d" + storage_mover_id = azurerm_storage_mover.test.id + arc_virtual_machine_id = data.azurerm_hybrid_compute_machine.test.id + arc_vm_uuid = data.azurerm_hybrid_compute_machine.test.vm_uuid + description = "Example Agent Description" } `, template, data.RandomInteger) } @@ -166,14 +312,22 @@ func (r StorageMoverAgentTestResource) update(data acceptance.TestData) string { template := r.template(data) return fmt.Sprintf(` +provider "azurerm" { + features { + resource_group { + prevent_deletion_if_contains_resources = false + } + } +} + %s resource "azurerm_storage_mover_agent" "test" { - name = "acctest-sa-%d" - storage_mover_id = azurerm_storage_mover.test.id - arc_resource_id = "${azurerm_resource_group.test.id}/providers/Microsoft.HybridCompute/machines/examples-hybridComputeName" - arc_vm_uuid = "3bb2c024-eba9-4d18-9e7a-1d772fcc5fe9" - description = "Update Example Agent Description" + name = "acctest-sa-%d" + storage_mover_id = azurerm_storage_mover.test.id + arc_virtual_machine_id = data.azurerm_hybrid_compute_machine.test.id + arc_vm_uuid = data.azurerm_hybrid_compute_machine.test.vm_uuid + description = "Update Example Agent Description" } `, template, data.RandomInteger) diff --git a/website/docs/r/storage_mover_agent.html.markdown b/website/docs/r/storage_mover_agent.html.markdown index 3d89fedab2317..b4aabed506343 100644 --- a/website/docs/r/storage_mover_agent.html.markdown +++ b/website/docs/r/storage_mover_agent.html.markdown @@ -8,14 +8,14 @@ description: |- # azurerm_storage_mover_agent -Manages a Storage Mover Agents. +Manages a Storage Mover Agent. ## Example Usage ```hcl resource "azurerm_resource_group" "example" { name = "example-resources" - location = "West Europe" + location = "East US" } resource "azurerm_storage_mover" "example" { @@ -24,11 +24,11 @@ resource "azurerm_storage_mover" "example" { } resource "azurerm_storage_mover_agent" "example" { - name = "example-sa" - storage_mover_id = azurerm_storage_mover.example.id - arc_resource_id = "${azurerm_resource_group.example.id}/providers/Microsoft.HybridCompute/machines/examples-hybridComputeName" - arc_vm_uuid = "3bb2c024-eba9-4d18-9e7a-1d772fcc5fe9" - description = "Example Agent Description" + name = "example-sa" + storage_mover_id = azurerm_storage_mover.example.id + arc_virtual_machine_id = "${azurerm_resource_group.example.id}/providers/Microsoft.HybridCompute/machines/examples-hybridComputeName" + arc_vm_uuid = "3bb2c024-eba9-4d18-9e7a-1d772fcc5fe9" + description = "Example Agent Description" } ``` @@ -38,13 +38,13 @@ The following arguments are supported: * `name` - (Required) Specifies the name which should be used for this Storage Mover Agent. Changing this forces a new resource to be created. -* `arc_resource_id` - (Required) Specifies the fully qualified resource ID of the Hybrid Compute resource for the Storage Mover Agent. Changing this forces a new resource to be created. +* `arc_virtual_machine_id` - (Required) Specifies the fully qualified ID of the Hybrid Compute resource for the Storage Mover Agent. Changing this forces a new resource to be created. -* `arc_vm_uuid` - (Required) Specifies the VM UUID of the Hybrid Compute resource for the Storage Mover Agent. Changing this forces a new resource to be created. +* `arc_vm_uuid` - (Required) Specifies the Hybrid Compute resource's unique SMBIOS ID. Changing this forces a new resource to be created. -* `storage_mover_id` - (Required) Specifies the ID of the Storage Mover. Changing this forces a new resource to be created. +* `storage_mover_id` - (Required) Specifies the ID of the Storage Mover that this Agent should be connected to. Changing this forces a new resource to be created. -* `description` - (Optional) A description for the Storage Mover Agent. +* `description` - (Optional) Specifies a description for this Storage Mover Agent. ## Attributes Reference diff --git a/website/docs/r/storage_mover_endpoint.html.markdown b/website/docs/r/storage_mover_endpoint.html.markdown deleted file mode 100644 index 3a0ffdd19b041..0000000000000 --- a/website/docs/r/storage_mover_endpoint.html.markdown +++ /dev/null @@ -1,70 +0,0 @@ ---- -subcategory: "storagemover" -layout: "azurerm" -page_title: "Azure Resource Manager: azurerm_storagemover_endpoint" -description: |- - Manages a Storagemover Endpoints. ---- - -# azurerm_storagemover_endpoint - -Manages a Storagemover Endpoints. - -## Example Usage - -```hcl -resource "azurerm_resource_group" "example" { - name = "example-resources" - location = "West Europe" -} - -resource "azurerm_storagemover_storage_mover" "example" { - name = "example-ssm" - resource_group_name = azurerm_resource_group.example.name -} - -resource "azurerm_storagemover_endpoint" "example" { - name = "example-se" - storagemover_storage_mover_id = azurerm_storagemover_storage_mover.test.id - description = "" - endpoint_type = "" - -} -``` - -## Arguments Reference - -The following arguments are supported: - -* `name` - (Required) Specifies the name which should be used for this Storagemover Endpoints. Changing this forces a new Storagemover Endpoints to be created. - -* `storagemover_storage_mover_id` - (Required) Specifies the ID of the Storagemover Endpoints. Changing this forces a new Storagemover Endpoints to be created. - -* `endpoint_type` - (Required) Specifies the Endpoint resource type. Changing this forces a new Storagemover Endpoints to be created. - -* `description` - (Optional) A description for the Endpoint. - -## Attributes Reference - -In addition to the Arguments listed above - the following Attributes are exported: - -* `id` - The ID of the Storagemover Endpoints. - - - -## Timeouts - -The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/docs/configuration/resources.html#timeouts) for certain actions: - -* `create` - (Defaults to 30 minutes) Used when creating the Storagemover Endpoints. -* `read` - (Defaults to 5 minutes) Used when retrieving the Storagemover Endpoints. -* `update` - (Defaults to 30 minutes) Used when updating the Storagemover Endpoints. -* `delete` - (Defaults to 30 minutes) Used when deleting the Storagemover Endpoints. - -## Import - -Storagemover Endpoints can be imported using the `resource id`, e.g. - -```shell -terraform import azurerm_storagemover_endpoint.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resourceGroup1/providers/Microsoft.StorageMover/storageMovers/storageMover1/endpoints/endpoint1 -```