This is an automated email from the ASF dual-hosted git repository.

Pearl1594 pushed a commit to branch add-import-support
in repository 
https://gitbox.apache.org/repos/asf/cloudstack-terraform-provider.git

commit 306bccdb5b1555150c2ee9f60529a4841c2c2d57
Author: Pearl Dsilva <[email protected]>
AuthorDate: Wed Jul 22 16:33:20 2026 -0400

    Add terraform import support for several cloudstack resources
---
 cloudstack/resource_cloudstack_autoscale_policy.go |  3 +
 .../resource_cloudstack_autoscale_vm_group.go      |  3 +
 .../resource_cloudstack_autoscale_vm_profile.go    |  3 +
 ...esource_cloudstack_autoscale_vm_profile_test.go | 21 ++++++
 cloudstack/resource_cloudstack_condition.go        |  3 +
 cloudstack/resource_cloudstack_counter.go          |  3 +
 cloudstack/resource_cloudstack_host.go             |  3 +
 cloudstack/resource_cloudstack_host_test.go        | 26 +++++++
 cloudstack/resource_cloudstack_ipaddress.go        |  3 +
 cloudstack/resource_cloudstack_ipaddress_test.go   | 19 +++++
 .../resource_cloudstack_loadbalancer_rule.go       |  3 +
 .../resource_cloudstack_loadbalancer_rule_test.go  | 21 ++++++
 cloudstack/resource_cloudstack_network_offering.go | 20 +++++
 cloudstack/resource_cloudstack_port_forward.go     | 86 ++++++++++++++++++++++
 .../resource_cloudstack_port_forward_test.go       | 22 ++++++
 cloudstack/resource_cloudstack_service_offering.go | 20 +++++
 .../resource_cloudstack_service_offering_test.go   | 18 +++++
 cloudstack/resource_cloudstack_static_nat.go       |  3 +
 cloudstack/resource_cloudstack_static_nat_test.go  | 19 +++++
 cloudstack/resource_cloudstack_vpn_connection.go   |  3 +
 .../resource_cloudstack_vpn_connection_test.go     | 19 +++++
 website/docs/r/autoscale_policy.html.markdown      |  8 ++
 website/docs/r/autoscale_vm_profile.html.markdown  |  8 ++
 website/docs/r/condition.html.markdown             |  8 ++
 website/docs/r/counter.html.markdown               |  8 ++
 website/docs/r/ipaddress.html.markdown             | 15 ++++
 website/docs/r/loadbalancer_rule.html.markdown     | 18 +++++
 website/docs/r/port_forward.html.markdown          | 19 +++++
 website/docs/r/static_nat.html.markdown            | 15 ++++
 website/docs/r/vpn_connection.html.markdown        |  8 ++
 30 files changed, 428 insertions(+)

diff --git a/cloudstack/resource_cloudstack_autoscale_policy.go 
b/cloudstack/resource_cloudstack_autoscale_policy.go
index fe390b5..8de316e 100644
--- a/cloudstack/resource_cloudstack_autoscale_policy.go
+++ b/cloudstack/resource_cloudstack_autoscale_policy.go
@@ -34,6 +34,9 @@ func resourceCloudStackAutoScalePolicy() *schema.Resource {
                Read:   resourceCloudStackAutoScalePolicyRead,
                Update: resourceCloudStackAutoScalePolicyUpdate,
                Delete: resourceCloudStackAutoScalePolicyDelete,
+               Importer: &schema.ResourceImporter{
+                       State: schema.ImportStatePassthrough,
+               },
 
                Schema: map[string]*schema.Schema{
                        "name": {
diff --git a/cloudstack/resource_cloudstack_autoscale_vm_group.go 
b/cloudstack/resource_cloudstack_autoscale_vm_group.go
index 8d0eb7e..d282032 100644
--- a/cloudstack/resource_cloudstack_autoscale_vm_group.go
+++ b/cloudstack/resource_cloudstack_autoscale_vm_group.go
@@ -35,6 +35,9 @@ func resourceCloudStackAutoScaleVMGroup() *schema.Resource {
                Read:   resourceCloudStackAutoScaleVMGroupRead,
                Update: resourceCloudStackAutoScaleVMGroupUpdate,
                Delete: resourceCloudStackAutoScaleVMGroupDelete,
+               Importer: &schema.ResourceImporter{
+                       State: schema.ImportStatePassthrough,
+               },
 
                Schema: map[string]*schema.Schema{
                        "lbrule_id": {
diff --git a/cloudstack/resource_cloudstack_autoscale_vm_profile.go 
b/cloudstack/resource_cloudstack_autoscale_vm_profile.go
index 0032b92..0bc71ae 100644
--- a/cloudstack/resource_cloudstack_autoscale_vm_profile.go
+++ b/cloudstack/resource_cloudstack_autoscale_vm_profile.go
@@ -35,6 +35,9 @@ func resourceCloudStackAutoScaleVMProfile() *schema.Resource {
                Read:   resourceCloudStackAutoScaleVMProfileRead,
                Update: resourceCloudStackAutoScaleVMProfileUpdate,
                Delete: resourceCloudStackAutoScaleVMProfileDelete,
+               Importer: &schema.ResourceImporter{
+                       State: schema.ImportStatePassthrough,
+               },
 
                Schema: map[string]*schema.Schema{
                        "service_offering": {
diff --git a/cloudstack/resource_cloudstack_autoscale_vm_profile_test.go 
b/cloudstack/resource_cloudstack_autoscale_vm_profile_test.go
index f417f45..97bb5b6 100644
--- a/cloudstack/resource_cloudstack_autoscale_vm_profile_test.go
+++ b/cloudstack/resource_cloudstack_autoscale_vm_profile_test.go
@@ -85,6 +85,27 @@ func TestAccCloudStackAutoscaleVMProfile_update(t 
*testing.T) {
        })
 }
 
+func TestAccCloudStackAutoscaleVMProfile_import(t *testing.T) {
+       t.Skip("Skipping due to bug in cloudstack-go library")
+
+       resource.Test(t, resource.TestCase{
+               PreCheck:     func() { testAccPreCheck(t) },
+               Providers:    testAccProviders,
+               CheckDestroy: testAccCheckCloudStackAutoscaleVMProfileDestroy,
+               Steps: []resource.TestStep{
+                       {
+                               Config: 
testAccCloudStackAutoscaleVMProfile_basic,
+                       },
+
+                       {
+                               ResourceName:      
"cloudstack_autoscale_vm_profile.foo",
+                               ImportState:       true,
+                               ImportStateVerify: true,
+                       },
+               },
+       })
+}
+
 func testAccCheckResourceMetadata(vmProfile *cloudstack.AutoScaleVmProfile) 
resource.TestCheckFunc {
        return func(s *terraform.State) error {
                cs := testAccProvider.Meta().(*cloudstack.CloudStackClient)
diff --git a/cloudstack/resource_cloudstack_condition.go 
b/cloudstack/resource_cloudstack_condition.go
index cd74e5c..be734ed 100644
--- a/cloudstack/resource_cloudstack_condition.go
+++ b/cloudstack/resource_cloudstack_condition.go
@@ -33,6 +33,9 @@ func resourceCloudStackCondition() *schema.Resource {
                Read:   resourceCloudStackConditionRead,
                Update: resourceCloudStackConditionUpdate,
                Delete: resourceCloudStackConditionDelete,
+               Importer: &schema.ResourceImporter{
+                       State: schema.ImportStatePassthrough,
+               },
 
                Schema: map[string]*schema.Schema{
                        "counter_id": {
diff --git a/cloudstack/resource_cloudstack_counter.go 
b/cloudstack/resource_cloudstack_counter.go
index ddd7e9e..ca78047 100644
--- a/cloudstack/resource_cloudstack_counter.go
+++ b/cloudstack/resource_cloudstack_counter.go
@@ -32,6 +32,9 @@ func resourceCloudStackCounter() *schema.Resource {
                Create: resourceCloudStackCounterCreate,
                Read:   resourceCloudStackCounterRead,
                Delete: resourceCloudStackCounterDelete,
+               Importer: &schema.ResourceImporter{
+                       State: schema.ImportStatePassthrough,
+               },
 
                Schema: map[string]*schema.Schema{
                        "name": {
diff --git a/cloudstack/resource_cloudstack_host.go 
b/cloudstack/resource_cloudstack_host.go
index 3e88d72..ec6e666 100644
--- a/cloudstack/resource_cloudstack_host.go
+++ b/cloudstack/resource_cloudstack_host.go
@@ -37,6 +37,9 @@ func resourceCloudStackHost() *schema.Resource {
                Update: resourceCloudStackHostUpdate,
                Create: resourceCloudStackHostCreate,
                Delete: resourceCloudStackHostDelete,
+               Importer: &schema.ResourceImporter{
+                       State: schema.ImportStatePassthrough,
+               },
                Schema: map[string]*schema.Schema{
                        "hypervisor": {
                                Type:     schema.TypeString,
diff --git a/cloudstack/resource_cloudstack_host_test.go 
b/cloudstack/resource_cloudstack_host_test.go
index da91b8a..25b5365 100644
--- a/cloudstack/resource_cloudstack_host_test.go
+++ b/cloudstack/resource_cloudstack_host_test.go
@@ -49,6 +49,32 @@ func TestAccCloudStackHost_basic(t *testing.T) {
        })
 }
 
+func TestAccCloudStackHost_import(t *testing.T) {
+       resource.Test(t, resource.TestCase{
+               PreCheck:  func() { testAccPreCheck(t) },
+               Providers: testAccProviders,
+               Steps: []resource.TestStep{
+                       {
+                               Config: testAccCloudStackHost_basic,
+                       },
+
+                       {
+                               ResourceName:      "cloudstack_host.test",
+                               ImportState:       true,
+                               ImportStateVerify: true,
+                               // CloudStack's listHosts API never returns the 
connection URL or
+                               // credentials, and these timeouts/flags are 
provider-local knobs that
+                               // aren't part of the host object, so Read 
can't populate any of them.
+                               ImportStateVerifyIgnore: []string{
+                                       "url", "username", "password",
+                                       "create_timeout", "destroy_timeout",
+                                       "prevent_destroy", "force_destroy",
+                               },
+                       },
+               },
+       })
+}
+
 const testAccCloudStackHost_basic = `
 data "cloudstack_zone" "zone" {
        filter {
diff --git a/cloudstack/resource_cloudstack_ipaddress.go 
b/cloudstack/resource_cloudstack_ipaddress.go
index c7db4ac..536196e 100644
--- a/cloudstack/resource_cloudstack_ipaddress.go
+++ b/cloudstack/resource_cloudstack_ipaddress.go
@@ -33,6 +33,9 @@ func resourceCloudStackIPAddress() *schema.Resource {
                Create: resourceCloudStackIPAddressCreate,
                Read:   resourceCloudStackIPAddressRead,
                Delete: resourceCloudStackIPAddressDelete,
+               Importer: &schema.ResourceImporter{
+                       State: importStatePassthrough,
+               },
 
                Schema: map[string]*schema.Schema{
                        "is_portable": {
diff --git a/cloudstack/resource_cloudstack_ipaddress_test.go 
b/cloudstack/resource_cloudstack_ipaddress_test.go
index 82b8ffc..53115e2 100644
--- a/cloudstack/resource_cloudstack_ipaddress_test.go
+++ b/cloudstack/resource_cloudstack_ipaddress_test.go
@@ -49,6 +49,25 @@ func TestAccCloudStackIPAddress_basic(t *testing.T) {
        })
 }
 
+func TestAccCloudStackIPAddress_import(t *testing.T) {
+       resource.Test(t, resource.TestCase{
+               PreCheck:     func() { testAccPreCheck(t) },
+               Providers:    testAccProviders,
+               CheckDestroy: testAccCheckCloudStackIPAddressDestroy,
+               Steps: []resource.TestStep{
+                       {
+                               Config: testAccCloudStackIPAddress_basic,
+                       },
+
+                       {
+                               ResourceName:      "cloudstack_ipaddress.foo",
+                               ImportState:       true,
+                               ImportStateVerify: true,
+                       },
+               },
+       })
+}
+
 func TestAccCloudStackIPAddress_vpc(t *testing.T) {
        var ipaddr cloudstack.PublicIpAddress
 
diff --git a/cloudstack/resource_cloudstack_loadbalancer_rule.go 
b/cloudstack/resource_cloudstack_loadbalancer_rule.go
index 6ebf52b..1c53f17 100644
--- a/cloudstack/resource_cloudstack_loadbalancer_rule.go
+++ b/cloudstack/resource_cloudstack_loadbalancer_rule.go
@@ -37,6 +37,9 @@ func resourceCloudStackLoadBalancerRule() *schema.Resource {
                Read:   resourceCloudStackLoadBalancerRuleRead,
                Update: resourceCloudStackLoadBalancerRuleUpdate,
                Delete: resourceCloudStackLoadBalancerRuleDelete,
+               Importer: &schema.ResourceImporter{
+                       State: importStatePassthrough,
+               },
 
                Schema: map[string]*schema.Schema{
                        "name": {
diff --git a/cloudstack/resource_cloudstack_loadbalancer_rule_test.go 
b/cloudstack/resource_cloudstack_loadbalancer_rule_test.go
index 8a9c792..f251152 100644
--- a/cloudstack/resource_cloudstack_loadbalancer_rule_test.go
+++ b/cloudstack/resource_cloudstack_loadbalancer_rule_test.go
@@ -53,6 +53,27 @@ func TestAccCloudStackLoadBalancerRule_basic(t *testing.T) {
        })
 }
 
+func TestAccCloudStackLoadBalancerRule_import(t *testing.T) {
+       resource.Test(t, resource.TestCase{
+               PreCheck:     func() { testAccPreCheck(t) },
+               Providers:    testAccProviders,
+               CheckDestroy: testAccCheckCloudStackLoadBalancerRuleDestroy,
+               Steps: []resource.TestStep{
+                       {
+                               Config: testAccCloudStackLoadBalancerRule_basic,
+                       },
+
+                       {
+                               ResourceName:      
"cloudstack_loadbalancer_rule.foo",
+                               ImportState:       true,
+                               ImportStateVerify: true,
+                               // certificate_id can't be read back from the 
CloudStack API (write-only field)
+                               ImportStateVerifyIgnore: 
[]string{"certificate_id"},
+                       },
+               },
+       })
+}
+
 func TestAccCloudStackLoadBalancerRule_update(t *testing.T) {
        var id string
 
diff --git a/cloudstack/resource_cloudstack_network_offering.go 
b/cloudstack/resource_cloudstack_network_offering.go
index d6adf4b..f260e63 100644
--- a/cloudstack/resource_cloudstack_network_offering.go
+++ b/cloudstack/resource_cloudstack_network_offering.go
@@ -33,6 +33,9 @@ func resourceCloudStackNetworkOffering() *schema.Resource {
                Read:   resourceCloudStackNetworkOfferingRead,
                Update: resourceCloudStackNetworkOfferingUpdate,
                Delete: resourceCloudStackNetworkOfferingDelete,
+               Importer: &schema.ResourceImporter{
+                       State: resourceCloudStackNetworkOfferingImport,
+               },
                Schema: map[string]*schema.Schema{
                        "name": {
                                Type:     schema.TypeString,
@@ -342,6 +345,23 @@ func resourceCloudStackNetworkOfferingDelete(d 
*schema.ResourceData, meta interf
        return nil
 }
 
+func resourceCloudStackNetworkOfferingImport(d *schema.ResourceData, meta 
interface{}) ([]*schema.ResourceData, error) {
+       cs := meta.(*cloudstack.CloudStackClient)
+
+       // Read looks the offering up by name, so resolve the name from the ID 
first
+       n, count, err := cs.NetworkOffering.GetNetworkOfferingByID(d.Id())
+       if err != nil {
+               if count == 0 {
+                       return nil, fmt.Errorf("network offering with ID %s 
does not exist", d.Id())
+               }
+               return nil, err
+       }
+
+       d.Set("name", n.Name)
+
+       return []*schema.ResourceData{d}, nil
+}
+
 func resourceCloudStackNetworkOfferingRead(d *schema.ResourceData, meta 
interface{}) error {
        cs := meta.(*cloudstack.CloudStackClient)
        log.Printf("[DEBUG] Retrieving Network Offering %s", 
d.Get("name").(string))
diff --git a/cloudstack/resource_cloudstack_port_forward.go 
b/cloudstack/resource_cloudstack_port_forward.go
index 2b00673..661f8eb 100644
--- a/cloudstack/resource_cloudstack_port_forward.go
+++ b/cloudstack/resource_cloudstack_port_forward.go
@@ -38,6 +38,9 @@ func resourceCloudStackPortForward() *schema.Resource {
                Read:   resourceCloudStackPortForwardRead,
                Update: resourceCloudStackPortForwardUpdate,
                Delete: resourceCloudStackPortForwardDelete,
+               Importer: &schema.ResourceImporter{
+                       State: resourceCloudStackPortForwardImport,
+               },
 
                Schema: map[string]*schema.Schema{
                        "ip_address_id": {
@@ -230,6 +233,89 @@ func createPortForward(d *schema.ResourceData, meta 
interface{}, forward map[str
        return nil
 }
 
+func resourceCloudStackPortForwardImport(d *schema.ResourceData, meta 
interface{}) ([]*schema.ResourceData, error) {
+       cs := meta.(*cloudstack.CloudStackClient)
+
+       // Try to split the ID to extract the optional project name.
+       s := strings.SplitN(d.Id(), "/", 2)
+       if len(s) == 2 {
+               d.Set("project", s[0])
+       }
+
+       ipAddressID := s[len(s)-1]
+       d.SetId(ipAddressID)
+
+       // Make sure the IP address exists
+       if _, count, err := cs.Address.GetPublicIpAddressByID(
+               ipAddressID,
+               cloudstack.WithProject(d.Get("project").(string)),
+       ); err != nil {
+               if count == 0 {
+                       return nil, fmt.Errorf("IP address with ID %s does not 
exist", ipAddressID)
+               }
+               return nil, err
+       }
+
+       // Get all the forwards configured for this IP address
+       p := cs.Firewall.NewListPortForwardingRulesParams()
+       p.SetIpaddressid(ipAddressID)
+       p.SetListall(true)
+
+       if err := setProjectid(p, cs, d); err != nil {
+               return nil, err
+       }
+
+       l, err := cs.Firewall.ListPortForwardingRules(p)
+       if err != nil {
+               return nil, err
+       }
+
+       forwards := 
resourceCloudStackPortForward().Schema["forward"].ZeroValue().(*schema.Set)
+       for _, f := range l.PortForwardingRules {
+               privPort, err := strconv.Atoi(f.Privateport)
+               if err != nil {
+                       return nil, err
+               }
+
+               pubPort, err := strconv.Atoi(f.Publicport)
+               if err != nil {
+                       return nil, err
+               }
+
+               forward := map[string]interface{}{
+                       "protocol":           f.Protocol,
+                       "private_port":       privPort,
+                       "public_port":        pubPort,
+                       "virtual_machine_id": f.Virtualmachineid,
+                       "vm_guest_ip":        f.Vmguestip,
+                       "uuid":               f.Id,
+               }
+
+               if f.Privateendport != "" && f.Privateendport != f.Privateport {
+                       privEndPort, err := strconv.Atoi(f.Privateendport)
+                       if err != nil {
+                               return nil, err
+                       }
+                       forward["private_end_port"] = privEndPort
+               }
+
+               if f.Publicendport != "" && f.Publicendport != f.Publicport {
+                       pubEndPort, err := strconv.Atoi(f.Publicendport)
+                       if err != nil {
+                               return nil, err
+                       }
+                       forward["public_end_port"] = pubEndPort
+               }
+
+               forwards.Add(forward)
+       }
+
+       d.Set("forward", forwards)
+       d.Set("managed", true)
+
+       return []*schema.ResourceData{d}, nil
+}
+
 func resourceCloudStackPortForwardRead(d *schema.ResourceData, meta 
interface{}) error {
        cs := meta.(*cloudstack.CloudStackClient)
 
diff --git a/cloudstack/resource_cloudstack_port_forward_test.go 
b/cloudstack/resource_cloudstack_port_forward_test.go
index bb15f28..44a0a80 100644
--- a/cloudstack/resource_cloudstack_port_forward_test.go
+++ b/cloudstack/resource_cloudstack_port_forward_test.go
@@ -57,6 +57,28 @@ func TestAccCloudStackPortForward_basic(t *testing.T) {
        })
 }
 
+func TestAccCloudStackPortForward_import(t *testing.T) {
+       resource.Test(t, resource.TestCase{
+               PreCheck:     func() { testAccPreCheck(t) },
+               Providers:    testAccProviders,
+               CheckDestroy: testAccCheckCloudStackPortForwardDestroy,
+               Steps: []resource.TestStep{
+                       {
+                               Config: testAccCloudStackPortForward_basic,
+                       },
+
+                       {
+                               ResourceName:      
"cloudstack_port_forward.foo",
+                               ImportState:       true,
+                               ImportStateVerify: true,
+                               // The importer sets managed=true so unrelated 
forwards on the same IP
+                               // aren't silently dropped; the applied config 
leaves it at its default.
+                               ImportStateVerifyIgnore: []string{"managed"},
+                       },
+               },
+       })
+}
+
 func TestAccCloudStackPortForward_update(t *testing.T) {
        resource.Test(t, resource.TestCase{
                PreCheck:     func() { testAccPreCheck(t) },
diff --git a/cloudstack/resource_cloudstack_service_offering.go 
b/cloudstack/resource_cloudstack_service_offering.go
index b2b2b92..227a879 100644
--- a/cloudstack/resource_cloudstack_service_offering.go
+++ b/cloudstack/resource_cloudstack_service_offering.go
@@ -34,6 +34,9 @@ func resourceCloudStackServiceOffering() *schema.Resource {
                Read:   resourceCloudStackServiceOfferingRead,
                Update: resourceCloudStackServiceOfferingUpdate,
                Delete: resourceCloudStackServiceOfferingDelete,
+               Importer: &schema.ResourceImporter{
+                       State: resourceCloudStackServiceOfferingImport,
+               },
                Schema: map[string]*schema.Schema{
                        "name": {
                                Type:     schema.TypeString,
@@ -246,6 +249,23 @@ func resourceCloudStackServiceOfferingCreate(d 
*schema.ResourceData, meta interf
        return resourceCloudStackServiceOfferingRead(d, meta)
 }
 
+func resourceCloudStackServiceOfferingImport(d *schema.ResourceData, meta 
interface{}) ([]*schema.ResourceData, error) {
+       cs := meta.(*cloudstack.CloudStackClient)
+
+       // Read looks the offering up by name, so resolve the name from the ID 
first
+       s, count, err := cs.ServiceOffering.GetServiceOfferingByID(d.Id())
+       if err != nil {
+               if count == 0 {
+                       return nil, fmt.Errorf("service offering with ID %s 
does not exist", d.Id())
+               }
+               return nil, err
+       }
+
+       d.Set("name", s.Name)
+
+       return []*schema.ResourceData{d}, nil
+}
+
 func resourceCloudStackServiceOfferingRead(d *schema.ResourceData, meta 
interface{}) error {
        cs := meta.(*cloudstack.CloudStackClient)
        log.Printf("[DEBUG] Retrieving Service Offering %s", 
d.Get("name").(string))
diff --git a/cloudstack/resource_cloudstack_service_offering_test.go 
b/cloudstack/resource_cloudstack_service_offering_test.go
index c403428..9bb34f3 100644
--- a/cloudstack/resource_cloudstack_service_offering_test.go
+++ b/cloudstack/resource_cloudstack_service_offering_test.go
@@ -47,6 +47,24 @@ func TestAccCloudStackServiceOffering_basic(t *testing.T) {
        })
 }
 
+func TestAccCloudStackServiceOffering_import(t *testing.T) {
+       resource.Test(t, resource.TestCase{
+               PreCheck:  func() { testAccPreCheck(t) },
+               Providers: testAccProviders,
+               Steps: []resource.TestStep{
+                       {
+                               Config: testAccCloudStackServiceOffering_basic,
+                       },
+
+                       {
+                               ResourceName:      
"cloudstack_service_offering.test1",
+                               ImportState:       true,
+                               ImportStateVerify: true,
+                       },
+               },
+       })
+}
+
 const testAccCloudStackServiceOffering_basic = `
 resource "cloudstack_service_offering" "test1" {
   name                         = "service_offering_1"
diff --git a/cloudstack/resource_cloudstack_static_nat.go 
b/cloudstack/resource_cloudstack_static_nat.go
index 2b2c402..36fef6c 100644
--- a/cloudstack/resource_cloudstack_static_nat.go
+++ b/cloudstack/resource_cloudstack_static_nat.go
@@ -34,6 +34,9 @@ func resourceCloudStackStaticNAT() *schema.Resource {
                Exists: resourceCloudStackStaticNATExists,
                Read:   resourceCloudStackStaticNATRead,
                Delete: resourceCloudStackStaticNATDelete,
+               Importer: &schema.ResourceImporter{
+                       State: importStatePassthrough,
+               },
 
                Schema: map[string]*schema.Schema{
                        "ip_address_id": {
diff --git a/cloudstack/resource_cloudstack_static_nat_test.go 
b/cloudstack/resource_cloudstack_static_nat_test.go
index eebebcb..8004718 100644
--- a/cloudstack/resource_cloudstack_static_nat_test.go
+++ b/cloudstack/resource_cloudstack_static_nat_test.go
@@ -48,6 +48,25 @@ func TestAccCloudStackStaticNAT_basic(t *testing.T) {
        })
 }
 
+func TestAccCloudStackStaticNAT_import(t *testing.T) {
+       resource.Test(t, resource.TestCase{
+               PreCheck:     func() { testAccPreCheck(t) },
+               Providers:    testAccProviders,
+               CheckDestroy: testAccCheckCloudStackStaticNATDestroy,
+               Steps: []resource.TestStep{
+                       {
+                               Config: testAccCloudStackStaticNAT_basic,
+                       },
+
+                       {
+                               ResourceName:      "cloudstack_static_nat.foo",
+                               ImportState:       true,
+                               ImportStateVerify: true,
+                       },
+               },
+       })
+}
+
 func testAccCheckCloudStackStaticNATExists(
        n string, ipaddr *cloudstack.PublicIpAddress) resource.TestCheckFunc {
        return func(s *terraform.State) error {
diff --git a/cloudstack/resource_cloudstack_vpn_connection.go 
b/cloudstack/resource_cloudstack_vpn_connection.go
index a493e16..d1bf4d8 100644
--- a/cloudstack/resource_cloudstack_vpn_connection.go
+++ b/cloudstack/resource_cloudstack_vpn_connection.go
@@ -33,6 +33,9 @@ func resourceCloudStackVPNConnection() *schema.Resource {
                Create: resourceCloudStackVPNConnectionCreate,
                Read:   resourceCloudStackVPNConnectionRead,
                Delete: resourceCloudStackVPNConnectionDelete,
+               Importer: &schema.ResourceImporter{
+                       State: schema.ImportStatePassthrough,
+               },
 
                Schema: map[string]*schema.Schema{
                        "customer_gateway_id": {
diff --git a/cloudstack/resource_cloudstack_vpn_connection_test.go 
b/cloudstack/resource_cloudstack_vpn_connection_test.go
index 55d42a7..1eef989 100644
--- a/cloudstack/resource_cloudstack_vpn_connection_test.go
+++ b/cloudstack/resource_cloudstack_vpn_connection_test.go
@@ -49,6 +49,25 @@ func TestAccCloudStackVPNConnection_basic(t *testing.T) {
        })
 }
 
+func TestAccCloudStackVPNConnection_import(t *testing.T) {
+       resource.Test(t, resource.TestCase{
+               PreCheck:     func() { testAccPreCheck(t) },
+               Providers:    testAccProviders,
+               CheckDestroy: testAccCheckCloudStackVPNConnectionDestroy,
+               Steps: []resource.TestStep{
+                       {
+                               Config: testAccCloudStackVPNConnection_basic,
+                       },
+
+                       {
+                               ResourceName:      
"cloudstack_vpn_connection.foo-bar",
+                               ImportState:       true,
+                               ImportStateVerify: true,
+                       },
+               },
+       })
+}
+
 func testAccCheckCloudStackVPNConnectionExists(
        n string, vpnConnection *cloudstack.VpnConnection) 
resource.TestCheckFunc {
        return func(s *terraform.State) error {
diff --git a/website/docs/r/autoscale_policy.html.markdown 
b/website/docs/r/autoscale_policy.html.markdown
index 98da742..3abe3c2 100644
--- a/website/docs/r/autoscale_policy.html.markdown
+++ b/website/docs/r/autoscale_policy.html.markdown
@@ -61,3 +61,11 @@ The following arguments are supported:
 The following attributes are exported:
 
 * `id` - The autoscale policy ID.
+
+## Import
+
+Autoscale policies can be imported using the `id`, e.g.
+
+```shell
+$ terraform import cloudstack_autoscale_policy.default 
eb22f91-7454-4107-89f4-36afcdf33021
+```
diff --git a/website/docs/r/autoscale_vm_profile.html.markdown 
b/website/docs/r/autoscale_vm_profile.html.markdown
index 4213ccc..f9149fc 100644
--- a/website/docs/r/autoscale_vm_profile.html.markdown
+++ b/website/docs/r/autoscale_vm_profile.html.markdown
@@ -74,3 +74,11 @@ The following arguments are supported:
 The following attributes are exported:
 
 * `id` - The autoscale VM profile ID.
+
+## Import
+
+Autoscale VM profiles can be imported using the `id`, e.g.
+
+```shell
+$ terraform import cloudstack_autoscale_vm_profile.default 
eb22f91-7454-4107-89f4-36afcdf33021
+```
diff --git a/website/docs/r/condition.html.markdown 
b/website/docs/r/condition.html.markdown
index 68f80d6..23956a3 100644
--- a/website/docs/r/condition.html.markdown
+++ b/website/docs/r/condition.html.markdown
@@ -59,3 +59,11 @@ The following arguments are supported:
 The following attributes are exported:
 
 * `id` - The condition ID.
+
+## Import
+
+Conditions can be imported using the `id`, e.g.
+
+```shell
+$ terraform import cloudstack_condition.default 
eb22f91-7454-4107-89f4-36afcdf33021
+```
diff --git a/website/docs/r/counter.html.markdown 
b/website/docs/r/counter.html.markdown
index 9699df9..0dada3f 100644
--- a/website/docs/r/counter.html.markdown
+++ b/website/docs/r/counter.html.markdown
@@ -41,3 +41,11 @@ The following arguments are supported:
 The following attributes are exported:
 
 * `id` - The counter ID.
+
+## Import
+
+Counters can be imported using the `id`, e.g.
+
+```shell
+$ terraform import cloudstack_counter.default 
eb22f91-7454-4107-89f4-36afcdf33021
+```
diff --git a/website/docs/r/ipaddress.html.markdown 
b/website/docs/r/ipaddress.html.markdown
index 27bcbd2..042753b 100644
--- a/website/docs/r/ipaddress.html.markdown
+++ b/website/docs/r/ipaddress.html.markdown
@@ -46,3 +46,18 @@ The following attributes are exported:
 
 * `id` - The ID of the acquired and associated IP address.
 * `ip_address` - The IP address that was acquired and associated.
+
+## Import
+
+IP addresses can be imported; use `<IPADDRESSID>` as the import ID. For
+example:
+
+```shell
+$ terraform import cloudstack_ipaddress.default 
6226ea4d-9cbe-4cc9-b30c-b9532146da5b
+```
+
+When importing into a project you need to prefix the import ID with the 
project name:
+
+```shell
+$ terraform import cloudstack_ipaddress.default 
my-project/6226ea4d-9cbe-4cc9-b30c-b9532146da5b
+```
diff --git a/website/docs/r/loadbalancer_rule.html.markdown 
b/website/docs/r/loadbalancer_rule.html.markdown
index 890d044..00cd968 100644
--- a/website/docs/r/loadbalancer_rule.html.markdown
+++ b/website/docs/r/loadbalancer_rule.html.markdown
@@ -70,3 +70,21 @@ The following attributes are exported:
 
 * `id` - The load balancer rule ID.
 * `description` - The description of the load balancer rule.
+
+## Import
+
+Load balancer rules can be imported; use `<LOADBALANCERRULEID>` as the import 
ID. For
+example:
+
+```shell
+$ terraform import cloudstack_loadbalancer_rule.default 
6226ea4d-9cbe-4cc9-b30c-b9532146da5b
+```
+
+When importing into a project you need to prefix the import ID with the 
project name:
+
+```shell
+$ terraform import cloudstack_loadbalancer_rule.default 
my-project/6226ea4d-9cbe-4cc9-b30c-b9532146da5b
+```
+
+*NOTE: `certificate_id` cannot be read back from the CloudStack API, so it will
+always be empty after an import.*
diff --git a/website/docs/r/port_forward.html.markdown 
b/website/docs/r/port_forward.html.markdown
index 23d1eb3..b5ffe52 100644
--- a/website/docs/r/port_forward.html.markdown
+++ b/website/docs/r/port_forward.html.markdown
@@ -70,3 +70,22 @@ The following attributes are exported:
 * `id` - The ID of the IP address for which the port forwards are created.
 * `vm_guest_ip` - The IP address of the virtual machine that is used
     for the port forwarding rule.
+
+## Import
+
+Port forwards can be imported; use the `<IPADDRESSID>` for which the rules
+are configured as the import ID. For example:
+
+```shell
+$ terraform import cloudstack_port_forward.default 
6226ea4d-9cbe-4cc9-b30c-b9532146da5b
+```
+
+When importing into a project you need to prefix the import ID with the 
project name:
+
+```shell
+$ terraform import cloudstack_port_forward.default 
my-project/6226ea4d-9cbe-4cc9-b30c-b9532146da5b
+```
+
+*NOTE: All existing port forwarding rules for the IP address are imported into
+a single `forward` set, and `managed` is set to `true` so unrelated rules
+created outside of this resource aren't dropped on the next apply.*
diff --git a/website/docs/r/static_nat.html.markdown 
b/website/docs/r/static_nat.html.markdown
index 7484782..f62bf94 100644
--- a/website/docs/r/static_nat.html.markdown
+++ b/website/docs/r/static_nat.html.markdown
@@ -43,3 +43,18 @@ The following attributes are exported:
 * `id` - The static nat ID.
 * `vm_guest_ip` - The IP address of the virtual machine that is used
     to forward the static NAT traffic to.
+
+## Import
+
+Static NAT can be imported; use the `<IPADDRESSID>` for which static NAT is
+enabled as the import ID. For example:
+
+```shell
+$ terraform import cloudstack_static_nat.default 
6226ea4d-9cbe-4cc9-b30c-b9532146da5b
+```
+
+When importing into a project you need to prefix the import ID with the 
project name:
+
+```shell
+$ terraform import cloudstack_static_nat.default 
my-project/6226ea4d-9cbe-4cc9-b30c-b9532146da5b
+```
diff --git a/website/docs/r/vpn_connection.html.markdown 
b/website/docs/r/vpn_connection.html.markdown
index 7a2f701..56896ac 100644
--- a/website/docs/r/vpn_connection.html.markdown
+++ b/website/docs/r/vpn_connection.html.markdown
@@ -36,3 +36,11 @@ The following arguments are supported:
 The following attributes are exported:
 
 * `id` - The ID of the VPN Connection.
+
+## Import
+
+VPN Connections can be imported using the `id`, e.g.
+
+```shell
+$ terraform import cloudstack_vpn_connection.default 
eb22f91-7454-4107-89f4-36afcdf33021
+```

Reply via email to