Terraform可以解决Azure重命名资源之类的相互依赖性问题吗?

时间:2019-12-14 01:20:31

标签: azure terraform rename

今天,我使用Terraform部署了Azure环境。它是资源的简单集合-资源组,VNET,VM,NIC,公共IP和基本NSG。

完成部署后,我发现我错误地命名了我的公共IP和NSG。

我修改了Terraform配置,进行了terraform plan,然后进行了terraform apply来应用我的更改,但由于以下与资源正在使用且无法使用相关的错误而无法执行因此将被删除。

我的问题是-

  1. 期望Terraform正确处理解析的依赖关系并采取必要的操作来启用这种情况是否合理?
  2. 我在配置中做错了吗?
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  ~ update in-place
-/+ destroy and then create replacement

Terraform will perform the following actions:

  # azurerm_network_interface.nic will be updated in-place
  ~ resource "azurerm_network_interface" "nic" {
        applied_dns_servers           = []
        dns_servers                   = []
        enable_accelerated_networking = false
        enable_ip_forwarding          = false
        id                            = "/subscriptions/xxxxxxxxxxxxxxxxxxxxx/resourceGroups/app505-jmd-terraform-rg/providers/Microsoft.Network/networkInterfaces/app505-jmd-terraform-vm01-nic"
        location                      = "eastus2"
        mac_address                   = "00-0D-3A-7B-B9-EC"
        name                          = "app505-jmd-terraform-vm01-nic"
      ~ network_security_group_id     = "/subscriptions/xxxxxxxxxxxxxxxxxxxxx/resourceGroups/app505-jmd-terraform-rg/providers/Microsoft.Network/networkSecurityGroups/app505-jmd-terraform" -> (known after apply)
        private_ip_address            = "10.0.1.4"
        private_ip_addresses          = [
            "10.0.1.4",
        ]
        resource_group_name           = "app505-jmd-terraform-rg"
        tags                          = {}
        virtual_machine_id            = "/subscriptions/xxxxxxxxxxxxxxxxxxxxx/resourceGroups/app505-jmd-terraform-rg/providers/Microsoft.Compute/virtualMachines/app505-jmd-terraform-vm01"

      ~ ip_configuration {
            application_gateway_backend_address_pools_ids = []
            application_security_group_ids                = []
            load_balancer_backend_address_pools_ids       = []
            load_balancer_inbound_nat_rules_ids           = []
            name                                          = "myNicConfiguration"
            primary                                       = true
            private_ip_address                            = "10.0.1.4"
            private_ip_address_allocation                 = "dynamic"
            private_ip_address_version                    = "IPv4"
          ~ public_ip_address_id                          = "/subscriptions/xxxxxxxxxxxxxxxxxxxxx/resourceGroups/app505-jmd-terraform-rg/providers/Microsoft.Network/publicIPAddresses/app505-jmd-terraform" -> (known after apply)
            subnet_id                                     = "/subscriptions/xxxxxxxxxxxxxxxxxxxxx/resourceGroups/app505-jmd-terraform-rg/providers/Microsoft.Network/virtualNetworks/app505-jmd-terraform-vnet/subnets/Internal"
        }
    }

  # azurerm_network_security_group.nsg must be replaced
-/+ resource "azurerm_network_security_group" "nsg" {
      ~ id                  = "/subscriptions/xxxxxxxxxxxxxxxxxxxxx/resourceGroups/app505-jmd-terraform-rg/providers/Microsoft.Network/networkSecurityGroups/app505-jmd-terraform" -> (known after apply)
        location            = "eastus2"
      ~ name                = "app505-jmd-terraform" -> "app505-jmd-terraform-nsg" # forces replacement
        resource_group_name = "app505-jmd-terraform-rg"
        security_rule       = [
            {
                access                                     = "Allow"
                description                                = ""
                destination_address_prefix                 = "*"
                destination_address_prefixes               = []
                destination_application_security_group_ids = []
                destination_port_range                     = "22"
                destination_port_ranges                    = []
                direction                                  = "Inbound"
                name                                       = "SSH"
                priority                                   = 1001
                protocol                                   = "Tcp"
                source_address_prefix                      = "*"
                source_address_prefixes                    = []
                source_application_security_group_ids      = []
                source_port_range                          = "*"
                source_port_ranges                         = []
            },
        ]
      ~ tags                = {} -> (known after apply)
    }

  # azurerm_public_ip.pip must be replaced
-/+ resource "azurerm_public_ip" "pip" {
        allocation_method            = "Dynamic"
      + fqdn                         = (known after apply)
      ~ id                           = "/subscriptions/xxxxxxxxxxxxxxxxxxxxx/resourceGroups/app505-jmd-terraform-rg/providers/Microsoft.Network/publicIPAddresses/app505-jmd-terraform" -> (known after apply)
        idle_timeout_in_minutes      = 4
      ~ ip_address                   = "13.68.114.233" -> (known after apply)
        ip_version                   = "IPv4"
        location                     = "eastus2"
      ~ name                         = "app505-jmd-terraform" -> "app505-jmd-terraform-pip" # forces replacement
      ~ public_ip_address_allocation = "Dynamic" -> (known after apply)
        resource_group_name          = "app505-jmd-terraform-rg"
        sku                          = "Basic"
      ~ tags                         = {} -> (known after apply)
      - zones                        = [] -> null
    }

Plan: 2 to add, 1 to change, 2 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

azurerm_public_ip.pip: Destroying... [id=/subscriptions/xxxxxxxxxxxxxxxxxxxxx/resourceGroups/app505-jmd-terraform-rg/providers/Microsoft.Network/publicIPAddresses/app505-jmd-terraform]
azurerm_network_security_group.nsg: Destroying... [id=/subscriptions/xxxxxxxxxxxxxxxxxxxxx/resourceGroups/app505-jmd-terraform-rg/providers/Microsoft.Network/networkSecurityGroups/app505-jmd-terraform]

Error: Error deleting Network Security Group "app505-jmd-terraform" (Resource Group "app505-jmd-terraform-rg"): network.SecurityGroupsClient#Delete: Failure sending request: StatusCode=400 -- Original Error: Code="InUseNetworkSecurityGroupCannotBeDeleted" Message="Network security group /subscriptions/xxxxxxxxxxxxxxxxxxxxx/resourceGroups/app505-jmd-terraform-rg/providers/Microsoft.Network/networkSecurityGroups/app505-jmd-terraform cannot be deleted because it is in use by the following resources: /subscriptions/xxxxxxxxxxxxxxxxxxxxx/resourceGroups/app505-jmd-terraform-rg/providers/Microsoft.Network/networkInterfaces/app505-jmd-terraform-vm01-nic. In order to delete the Network security group, remove the association with the resource(s). To learn how to do this, see aka.ms/deletensg." Details=[]



Error: Error deleting Public IP "app505-jmd-terraform" (Resource Group "app505-jmd-terraform-rg"): network.PublicIPAddressesClient#Delete: Failure sending request: StatusCode=400 -- Original Error: Code="PublicIPAddressCannotBeDeleted" Message="Public IP address /subscriptions/xxxxxxxxxxxxxxxxxxxxx/resourceGroups/app505-jmd-terraform-rg/providers/Microsoft.Network/publicIPAddresses/app505-jmd-terraform can not be deleted since it is still allocated to resource /subscriptions/xxxxxxxxxxxxxxxxxxxxx/resourceGroups/app505-jmd-terraform-rg/providers/Microsoft.Network/networkInterfaces/app505-jmd-terraform-vm01-nic/ipConfigurations/myNicConfiguration. In order to delete the public IP, disassociate/detach the Public IP address from the resource.  To learn how to do this, see aka.ms/deletepublicip." Details=[]



C:\Users\jdeli\OneDrive\Documents\Code\Terraform\terraform>

最后,我的配置:

# Configure the Microsoft Azure Provider
provider "azurerm" {
    subscription_id = "aaaaaaaaaaaaaaaa"
    client_id       = "bbbbbbbbbbbbbbbb"
    client_secret   = "cccccccccccccccc"
    tenant_id       = "dddddddddddddddd"
    skip_provider_registration = true
}

# Create a resource group if it doesn’t exist
resource "azurerm_resource_group" "main" {
    name     = "${var.prefix}-rg"
    location = var.location
}

# Create virtual network
resource "azurerm_virtual_network" "network" {
    name                = "${var.prefix}-vnet"
    address_space       = ["10.0.0.0/16"]
    location            = var.location
    resource_group_name = azurerm_resource_group.main.name

}

# Create subnet
resource "azurerm_subnet" "subnet" {
    name                 = "Internal"
    resource_group_name  = azurerm_resource_group.main.name
    virtual_network_name = azurerm_virtual_network.network.name
    address_prefix       = "10.0.1.0/24"
}

# Create public IPs
resource "azurerm_public_ip" "pip" {
    name                         = "${var.prefix}-pip"
    location                     = var.location
    resource_group_name          = azurerm_resource_group.main.name
    allocation_method            = "Dynamic"
}

# Create Network Security Group and rule
resource "azurerm_network_security_group" "nsg" {
    name                = "${var.prefix}-nsg"
    location            = var.location
    resource_group_name = azurerm_resource_group.main.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 = "*"
    }
}

# Create network interface
resource "azurerm_network_interface" "nic" {
    name                      = "${var.prefix}-vm01-nic"
    location                  = var.location
    resource_group_name       = azurerm_resource_group.main.name
    network_security_group_id = azurerm_network_security_group.nsg.id

    ip_configuration {
        name                          = "myNicConfiguration"
        subnet_id                     = azurerm_subnet.subnet.id
        private_ip_address_allocation = "Dynamic"
        public_ip_address_id          = azurerm_public_ip.pip.id
    }

}

# Generate random text for a unique storage account name
resource "random_id" "randomId" {
    keepers = {
        # Generate a new ID only when a new resource group is defined
        resource_group = azurerm_resource_group.main.name
    }
    byte_length = 8
}

# Create storage account for boot diagnostics
resource "azurerm_storage_account" "diagstorage" {
    name                        = "diag${random_id.randomId.hex}"
    resource_group_name         = azurerm_resource_group.main.name
    location                    = var.location
    account_tier                = "Standard"
    account_replication_type    = "LRS"
}

# Create virtual machine
resource "azurerm_virtual_machine" "vm" {

    name                  = "${var.prefix}-"
    location              = var.location
    resource_group_name   = azurerm_resource_group.main.name
    network_interface_ids = [azurerm_network_interface.nic.id]
    vm_size               = "Standard_DS1_v2"

    storage_os_disk {
        name              = "${var.prefix}-vm01-disk0"
        caching           = "ReadWrite"
        create_option     = "FromImage"
        managed_disk_type = "Premium_LRS"
    }

    storage_image_reference {
        publisher = "Canonical"
        offer     = "UbuntuServer"
        sku       = "16.04.0-LTS"
        version   = "latest"
    }

    os_profile {
        computer_name  = "${var.prefix}-vm01"
        admin_username = "azureuser"
    }

    os_profile_linux_config {
        disable_password_authentication = true
        ssh_keys {
            path     = "/home/azureuser/.ssh/authorized_keys"
            key_data = "ssh-rsa xxxxxxxx"
        }
    }

    boot_diagnostics {
        enabled = "true"
        storage_uri = azurerm_storage_account.diagstorage.primary_blob_endpoint
    }
}

复制步骤:

  1. 部署上述配置
  2. 重命名NSG和公共IP地址(“名称”属性)
  3. 再次部署,并且出错。

1 个答案:

答案 0 :(得分:0)

我怀疑这对“顶级”资源(因此没有依赖于这些资源的资源)有效。 TF会从头开始删除并创建那些资源(您不能真正重命名Azure中的内容)。

对于具有依赖项的资源,这将不起作用,因为这意味着必须首先删除所有依赖项资源(或删除依赖项),然后才可以重命名资源(以便使用新名称删除\创建),然后所有依赖资源都必须重新创建\重新配置