Adding new data sources to cloudstack-terraform-proivder (#38)

* create ssh keypair data-source

* create a method stub for instance data-source

* extending instance data-source to use its id as an input

* use SetId() to define the ID of the instance resource

* implement filters to allow filtering off of any exported attributes

* add ip-address to schema and allow filtering off of it

* create a method stub to acceptance test the instance data-source

* basic acceptance test for instance data-source passing

* adding comments to improve the readability of code

* add basic acceptance test for ssh keypair data-source

* create network offering resource

* complete network offering resource type

* create network offering data source

* add basic acceptance test for network offering data source

* create disk offering resource

* implement create method for disk offering resource

* create cloudstack volume resource type

* create cloudstack zone resource type

* create zone data source

* add acceptance test for zone datasource

* create service offering resource

* create service offering data source

* add service offering data source

* fix typos in comments for network offering resource

* add volume data source

* add acceptance test for volume data source

* create account resource

* implement delete method in account resource

* fix a typo in network offering

* create user resource

* create domain resource

* add vpc data-source

* add ip address data-source

* add user data-source

* add vpn connection data-source

* add acceptance test for vpc data-source

* add acceptance test for ipaddress data-source

* add acceptance test for user data-source

* fix a typo in applyNetworkOfferingFilters method of network offering data-source
diff --git a/cloudstack/data_source_cloudstack_instance.go b/cloudstack/data_source_cloudstack_instance.go
new file mode 100644
index 0000000..a78f39b
--- /dev/null
+++ b/cloudstack/data_source_cloudstack_instance.go
@@ -0,0 +1,208 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package cloudstack
+
+import (
+	"encoding/json"
+	"fmt"
+	"log"
+	"regexp"
+	"strings"
+	"time"
+
+	"github.com/apache/cloudstack-go/v2/cloudstack"
+	"github.com/hashicorp/terraform/helper/schema"
+)
+
+func dataSourceCloudstackInstance() *schema.Resource {
+	return &schema.Resource{
+		Read: dataSourceCloudstackInstanceRead,
+		Schema: map[string]*schema.Schema{
+			"filter": dataSourceFiltersSchema(),
+
+			//Computed values
+			"instance_id": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+
+			"account": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+
+			"display_name": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+
+			"state": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+
+			"host_id": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+
+			"zone_id": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+
+			"created": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+
+			"tags": tagsSchema(),
+
+			"nic": {
+				Type:     schema.TypeList,
+				Computed: true,
+				Optional: true,
+				Elem: &schema.Resource{
+					Schema: map[string]*schema.Schema{
+						"ip_address": {
+							Type:     schema.TypeString,
+							Computed: true,
+							Optional: true,
+						},
+					},
+				},
+			},
+		},
+	}
+}
+
+func dataSourceCloudstackInstanceRead(d *schema.ResourceData, meta interface{}) error {
+	log.Printf("Instance Data Source Read Started")
+
+	cs := meta.(*cloudstack.CloudStackClient)
+	p := cs.VirtualMachine.NewListVirtualMachinesParams()
+	csInstances, err := cs.VirtualMachine.ListVirtualMachines(p)
+
+	if err != nil {
+		return fmt.Errorf("Failed to list instances: %s", err)
+	}
+
+	filters := d.Get("filter")
+	nic := d.Get("nic").([]interface{})
+	var instances []*cloudstack.VirtualMachine
+
+	//the if-else block to check whether to filter the data source by an IP address
+	// or by any other exported attributes
+	if len(nic) != 0 {
+		ip_address := nic[0].(map[string]interface{})["ip_address"]
+		for _, i := range csInstances.VirtualMachines {
+			if ip_address == i.Nic[0].Ipaddress {
+				instances = append(instances, i)
+			}
+		}
+	} else {
+		for _, i := range csInstances.VirtualMachines {
+			match, err := applyInstanceFilters(i, filters.(*schema.Set))
+			if err != nil {
+				return err
+			}
+
+			if match {
+				instances = append(instances, i)
+			}
+		}
+	}
+
+	if len(instances) == 0 {
+		return fmt.Errorf("No instance is matching with the specified regex")
+	}
+	//return the latest instance from the list of filtered instances according
+	//to its creation date
+	instance, err := latestInstance(instances)
+	if err != nil {
+		return err
+	}
+	log.Printf("[DEBUG] Selected instances: %s\n", instance.Displayname)
+
+	return instanceDescriptionAttributes(d, instance)
+}
+
+func instanceDescriptionAttributes(d *schema.ResourceData, instance *cloudstack.VirtualMachine) error {
+	d.SetId(instance.Id)
+	d.Set("instance_id", instance.Id)
+	d.Set("account", instance.Account)
+	d.Set("created", instance.Created)
+	d.Set("display_name", instance.Displayname)
+	d.Set("state", instance.State)
+	d.Set("host_id", instance.Hostid)
+	d.Set("zone_id", instance.Zoneid)
+	d.Set("nic", []interface{}{map[string]string{"ip_address": instance.Nic[0].Ipaddress}})
+
+	tags := make(map[string]interface{})
+	for _, tag := range instance.Tags {
+		tags[tag.Key] = tag.Value
+	}
+	d.Set("tags", tags)
+
+	return nil
+}
+
+func latestInstance(instances []*cloudstack.VirtualMachine) (*cloudstack.VirtualMachine, error) {
+	var latest time.Time
+	var instance *cloudstack.VirtualMachine
+
+	for _, i := range instances {
+		created, err := time.Parse("2006-01-02T15:04:05-0700", i.Created)
+		if err != nil {
+			return nil, fmt.Errorf("Failed to parse creation date of an instance: %s", err)
+		}
+
+		if created.After(latest) {
+			latest = created
+			instance = i
+		}
+	}
+
+	return instance, nil
+}
+
+func applyInstanceFilters(instance *cloudstack.VirtualMachine, filters *schema.Set) (bool, error) {
+	var instanceJSON map[string]interface{}
+	i, _ := json.Marshal(instance)
+	err := json.Unmarshal(i, &instanceJSON)
+	if err != nil {
+		return false, err
+	}
+
+	for _, f := range filters.List() {
+		m := f.(map[string]interface{})
+		r, err := regexp.Compile(m["value"].(string))
+		if err != nil {
+			return false, fmt.Errorf("Invalid regex: %s", err)
+		}
+		updatedName := strings.ReplaceAll(m["name"].(string), "_", "")
+		instanceField := instanceJSON[updatedName].(string)
+		if !r.MatchString(instanceField) {
+			return false, nil
+		}
+
+	}
+	return true, nil
+}
diff --git a/cloudstack/data_source_cloudstack_instance_test.go b/cloudstack/data_source_cloudstack_instance_test.go
new file mode 100644
index 0000000..e27b1e1
--- /dev/null
+++ b/cloudstack/data_source_cloudstack_instance_test.go
@@ -0,0 +1,66 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package cloudstack
+
+import (
+	"testing"
+
+	"github.com/hashicorp/terraform/helper/resource"
+)
+
+//basic acceptance to check if the display_name attribute has same value in
+//the created instance and its data source respectively.
+func TestAccInstanceDataSource_basic(t *testing.T) {
+	resourceName := "cloudstack_instance.my_instance"
+	datasourceName := "data.cloudstack_instance.my_instance_test"
+
+	resource.Test(t, resource.TestCase{
+		PreCheck:  func() { testAccPreCheck(t) },
+		Providers: testAccProviders,
+		Steps: []resource.TestStep{
+			{
+				Config: testAccInstanceDataSourceConfig_basic,
+				Check: resource.ComposeTestCheckFunc(
+					resource.TestCheckResourceAttrPair(datasourceName, "display_name", resourceName, "display_name"),
+				),
+				ExpectNonEmptyPlan: true,
+			},
+		},
+	})
+}
+
+const testAccInstanceDataSourceConfig_basic = `
+	resource "cloudstack_instance" "my_instance" {
+		name             = "server-a"
+		service_offering = "Small Instance"
+		network_id       = "b9c953a0-8686-4240-b8a4-43849f7079ff"
+		template         = "CentOS 5.5(64-bit) no GUI (KVM)"
+		zone             = "DC"
+	  }
+	  data "cloudstack_instance" "my_instance_test" {
+		filter {
+		name = "display_name" 
+		value = "server-a"
+	  }
+		depends_on = [
+		cloudstack_instance.my_instance
+	  ]
+	}
+`
diff --git a/cloudstack/data_source_cloudstack_ipaddress.go b/cloudstack/data_source_cloudstack_ipaddress.go
new file mode 100644
index 0000000..ad7b108
--- /dev/null
+++ b/cloudstack/data_source_cloudstack_ipaddress.go
@@ -0,0 +1,175 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package cloudstack
+
+import (
+	"encoding/json"
+	"fmt"
+	"log"
+	"regexp"
+	"strings"
+	"time"
+
+	"github.com/apache/cloudstack-go/v2/cloudstack"
+	"github.com/hashicorp/terraform/helper/schema"
+)
+
+func dataSourceCloudstackIPAddress() *schema.Resource {
+	return &schema.Resource{
+		Read: datasourceCloudStackIPAddressRead,
+		Schema: map[string]*schema.Schema{
+			"filter": dataSourceFiltersSchema(),
+
+			//Computed values
+			"is_portable": {
+				Type:     schema.TypeBool,
+				Computed: true,
+			},
+
+			"network_id": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+
+			"vpc_id": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+
+			"zone_name": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+
+			"project": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+
+			"ip_address": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+
+			"is_source_nat": {
+				Type:     schema.TypeBool,
+				Computed: true,
+			},
+
+			"tags": tagsSchema(),
+		},
+	}
+}
+
+func datasourceCloudStackIPAddressRead(d *schema.ResourceData, meta interface{}) error {
+	cs := meta.(*cloudstack.CloudStackClient)
+	p := cs.Address.NewListPublicIpAddressesParams()
+	csPublicIPAddresses, err := cs.Address.ListPublicIpAddresses(p)
+
+	if err != nil {
+		return fmt.Errorf("Failed to list ip addresses: %s", err)
+	}
+
+	filters := d.Get("filter")
+	var publicIpAddresses []*cloudstack.PublicIpAddress
+
+	for _, ip := range csPublicIPAddresses.PublicIpAddresses {
+		match, err := applyIPAddressFilters(ip, filters.(*schema.Set))
+
+		if err != nil {
+			return err
+		}
+		if match {
+			publicIpAddresses = append(publicIpAddresses, ip)
+		}
+	}
+
+	if len(publicIpAddresses) == 0 {
+		return fmt.Errorf("No ip address is matching with the specified regex")
+	}
+	//return the latest ip address from the list of filtered ip addresses according
+	//to its creation date
+	publicIpAddress, err := latestIPAddress(publicIpAddresses)
+	if err != nil {
+		return err
+	}
+	log.Printf("[DEBUG] Selected ip addresses: %s\n", publicIpAddress.Ipaddress)
+
+	return ipAddressDescriptionAttributes(d, publicIpAddress)
+}
+
+func ipAddressDescriptionAttributes(d *schema.ResourceData, publicIpAddress *cloudstack.PublicIpAddress) error {
+	d.SetId(publicIpAddress.Id)
+	d.Set("is_portable", publicIpAddress.Isportable)
+	d.Set("network_id", publicIpAddress.Networkid)
+	d.Set("vpc_id", publicIpAddress.Vpcid)
+	d.Set("zone_name", publicIpAddress.Zonename)
+	d.Set("project", publicIpAddress.Project)
+	d.Set("ip_address", publicIpAddress.Ipaddress)
+	d.Set("is_source_nat", publicIpAddress.Issourcenat)
+	d.Set("tags", publicIpAddress.Tags)
+
+	return nil
+}
+
+func latestIPAddress(publicIpAddresses []*cloudstack.PublicIpAddress) (*cloudstack.PublicIpAddress, error) {
+	var latest time.Time
+	var publicIpAddress *cloudstack.PublicIpAddress
+
+	for _, ip := range publicIpAddresses {
+		created, err := time.Parse("2006-01-02T15:04:05-0700", ip.Allocated)
+
+		if err != nil {
+			return nil, fmt.Errorf("Failed to parse allocation date of the ip address: %s", err)
+		}
+
+		if created.After(latest) {
+			latest = created
+			publicIpAddress = ip
+		}
+	}
+
+	return publicIpAddress, nil
+}
+
+func applyIPAddressFilters(publicIpAddress *cloudstack.PublicIpAddress, filters *schema.Set) (bool, error) {
+	var publicIPAdressJSON map[string]interface{}
+	k, _ := json.Marshal(publicIpAddress)
+	err := json.Unmarshal(k, &publicIPAdressJSON)
+
+	if err != nil {
+		return false, err
+	}
+
+	for _, f := range filters.List() {
+		m := f.(map[string]interface{})
+		r, err := regexp.Compile(m["value"].(string))
+		if err != nil {
+			return false, fmt.Errorf("Invalid regex: %s", err)
+		}
+		updatedName := strings.ReplaceAll(m["name"].(string), "_", "")
+		publicIPAdressField := fmt.Sprintf("%v", publicIPAdressJSON[updatedName])
+		if !r.MatchString(publicIPAdressField) {
+			return false, nil
+		}
+	}
+
+	return true, nil
+}
diff --git a/cloudstack/data_source_cloudstack_ipaddress_test.go b/cloudstack/data_source_cloudstack_ipaddress_test.go
new file mode 100644
index 0000000..ad98201
--- /dev/null
+++ b/cloudstack/data_source_cloudstack_ipaddress_test.go
@@ -0,0 +1,65 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package cloudstack
+
+import (
+	"testing"
+
+	"github.com/hashicorp/terraform/helper/resource"
+)
+
+func TestAccIPAddressDataSource_basic(t *testing.T) {
+	resourceName := "cloudstack_ipaddress.ipaddress-resource"
+	datasourceName := "data.cloudstack_ipaddress.ipaddress-data-source"
+
+	resource.Test(t, resource.TestCase{
+		PreCheck:  func() { testAccPreCheck(t) },
+		Providers: testAccProviders,
+		Steps: []resource.TestStep{
+			{
+				Config: testIPAddressDataSourceConfig_basic,
+				Check: resource.ComposeTestCheckFunc(
+					resource.TestCheckResourceAttrPair(datasourceName, "zone_name", resourceName, "zone"),
+				),
+				ExpectNonEmptyPlan: true,
+			},
+		},
+	})
+}
+
+const testIPAddressDataSourceConfig_basic = `
+resource "cloudstack_ipaddress" "ipaddress-resource" {
+	zone         = "DC"
+  }
+  
+  data "cloudstack_ipaddress" "ipaddress-data-source"{
+	  filter{
+	  name = "zone_name"
+	  value= "DC"
+	  }
+	  depends_on = [
+		cloudstack_ipaddress.ipaddress-resource
+	  ]
+	}
+  
+  output "ipaddress-output" {
+	value = "${data.cloudstack_ipaddress.ipaddress-data-source}"
+  }
+  `
diff --git a/cloudstack/data_source_cloudstack_network_offering.go b/cloudstack/data_source_cloudstack_network_offering.go
new file mode 100644
index 0000000..8e57fae
--- /dev/null
+++ b/cloudstack/data_source_cloudstack_network_offering.go
@@ -0,0 +1,148 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package cloudstack
+
+import (
+	"encoding/json"
+	"fmt"
+	"log"
+	"regexp"
+	"strings"
+	"time"
+
+	"github.com/apache/cloudstack-go/v2/cloudstack"
+	"github.com/hashicorp/terraform/helper/schema"
+)
+
+func dataSourceCloudstackNetworkOffering() *schema.Resource {
+	return &schema.Resource{
+		Read: datasourceCloudStackNetworkOfferingRead,
+		Schema: map[string]*schema.Schema{
+			"filter": dataSourceFiltersSchema(),
+
+			//Computed values
+			"name": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+			"display_text": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+			"guest_ip_type": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+			"traffic_type": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+		},
+	}
+}
+
+func datasourceCloudStackNetworkOfferingRead(d *schema.ResourceData, meta interface{}) error {
+	cs := meta.(*cloudstack.CloudStackClient)
+	p := cs.NetworkOffering.NewListNetworkOfferingsParams()
+	csNetworkOfferings, err := cs.NetworkOffering.ListNetworkOfferings(p)
+
+	if err != nil {
+		return fmt.Errorf("Failed to list network offerings: %s", err)
+	}
+
+	filters := d.Get("filter")
+	var networkOfferings []*cloudstack.NetworkOffering
+
+	for _, n := range csNetworkOfferings.NetworkOfferings {
+		match, err := applyNetworkOfferingFilters(n, filters.(*schema.Set))
+		if err != nil {
+			return err
+		}
+		if match {
+			networkOfferings = append(networkOfferings, n)
+		}
+	}
+
+	if len(networkOfferings) == 0 {
+		return fmt.Errorf("No network offering is matching with the specified regex")
+	}
+	//return the latest network offering from the list of filtered network offerings according
+	//to its creation date
+	networkOffering, err := latestNetworkOffering(networkOfferings)
+	if err != nil {
+		return err
+	}
+	log.Printf("[DEBUG] Selected network offerings: %s\n", networkOffering.Displaytext)
+
+	return networkOfferingDescriptionAttributes(d, networkOffering)
+}
+
+func networkOfferingDescriptionAttributes(d *schema.ResourceData, networkOffering *cloudstack.NetworkOffering) error {
+	d.SetId(networkOffering.Id)
+	d.Set("name", networkOffering.Name)
+	d.Set("display_text", networkOffering.Displaytext)
+	d.Set("guest_ip_type", networkOffering.Guestiptype)
+	d.Set("traffic_type", networkOffering.Traffictype)
+
+	return nil
+}
+
+func latestNetworkOffering(networkOfferings []*cloudstack.NetworkOffering) (*cloudstack.NetworkOffering, error) {
+	var latest time.Time
+	var networkOffering *cloudstack.NetworkOffering
+
+	for _, n := range networkOfferings {
+		created, err := time.Parse("2006-01-02T15:04:05-0700", n.Created)
+		if err != nil {
+			return nil, fmt.Errorf("Failed to parse creation date of a network offering: %s", err)
+		}
+
+		if created.After(latest) {
+			latest = created
+			networkOffering = n
+		}
+	}
+
+	return networkOffering, nil
+}
+
+func applyNetworkOfferingFilters(networkOffering *cloudstack.NetworkOffering, filters *schema.Set) (bool, error) {
+	var networkOfferingJSON map[string]interface{}
+	k, _ := json.Marshal(networkOffering)
+	err := json.Unmarshal(k, &networkOfferingJSON)
+	if err != nil {
+		return false, err
+	}
+
+	for _, f := range filters.List() {
+		m := f.(map[string]interface{})
+		r, err := regexp.Compile(m["value"].(string))
+		if err != nil {
+			return false, fmt.Errorf("Invalid regex: %s", err)
+		}
+		updatedName := strings.ReplaceAll(m["name"].(string), "_", "")
+		networkOfferingField := networkOfferingJSON[updatedName].(string)
+		if !r.MatchString(networkOfferingField) {
+			return false, nil
+		}
+
+	}
+	return true, nil
+}
diff --git a/cloudstack/data_source_cloudstack_network_offering_test.go b/cloudstack/data_source_cloudstack_network_offering_test.go
new file mode 100644
index 0000000..0101b31
--- /dev/null
+++ b/cloudstack/data_source_cloudstack_network_offering_test.go
@@ -0,0 +1,65 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package cloudstack
+
+import (
+	"testing"
+
+	"github.com/hashicorp/terraform/helper/resource"
+)
+
+func TestAccNetworkOfferingDataSource_basic(t *testing.T) {
+	resourceName := "cloudstack_network_offering.net-off-resource"
+	datasourceName := "data.cloudstack_network_offering.net-off-data-source"
+
+	resource.Test(t, resource.TestCase{
+		PreCheck:  func() { testAccPreCheck(t) },
+		Providers: testAccProviders,
+		Steps: []resource.TestStep{
+			{
+				Config: testNetworkOfferingDataSourceConfig_basic,
+				Check: resource.ComposeTestCheckFunc(
+					resource.TestCheckResourceAttrPair(datasourceName, "name", resourceName, "name"),
+				),
+				ExpectNonEmptyPlan: true,
+			},
+		},
+	})
+}
+
+const testNetworkOfferingDataSourceConfig_basic = `
+resource "cloudstack_network_offering" "net-off-resource"{
+  name       = "TestNetworkDisplay01"
+  display_text = "TestNetworkDisplay01"
+  guest_ip_type = "Isolated"
+  traffic_type = "Guest"
+  }
+
+  data "cloudstack_network_offering" "net-off-data-source"{
+
+    filter{
+    name = "name"
+    value="TestNetworkDisplay01"
+    }
+	  depends_on = [
+	  cloudstack_network_offering.net-off-resource
+	]
+  }
+  `
diff --git a/cloudstack/data_source_cloudstack_service_offering.go b/cloudstack/data_source_cloudstack_service_offering.go
new file mode 100644
index 0000000..4b33903
--- /dev/null
+++ b/cloudstack/data_source_cloudstack_service_offering.go
@@ -0,0 +1,138 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package cloudstack
+
+import (
+	"encoding/json"
+	"fmt"
+	"log"
+	"regexp"
+	"strings"
+	"time"
+
+	"github.com/apache/cloudstack-go/v2/cloudstack"
+	"github.com/hashicorp/terraform/helper/schema"
+)
+
+func dataSourceCloudstackServiceOffering() *schema.Resource {
+	return &schema.Resource{
+		Read: datasourceCloudStackServiceOfferingRead,
+		Schema: map[string]*schema.Schema{
+			"filter": dataSourceFiltersSchema(),
+
+			//Computed values
+			"name": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+			"display_text": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+		},
+	}
+}
+
+func datasourceCloudStackServiceOfferingRead(d *schema.ResourceData, meta interface{}) error {
+	cs := meta.(*cloudstack.CloudStackClient)
+	p := cs.ServiceOffering.NewListServiceOfferingsParams()
+	csServiceOfferings, err := cs.ServiceOffering.ListServiceOfferings(p)
+
+	if err != nil {
+		return fmt.Errorf("Failed to list service offerings: %s", err)
+	}
+
+	filters := d.Get("filter")
+	var serviceOfferings []*cloudstack.ServiceOffering
+
+	for _, s := range csServiceOfferings.ServiceOfferings {
+		match, err := applyServiceOfferingFilters(s, filters.(*schema.Set))
+		if err != nil {
+			return err
+		}
+		if match {
+			serviceOfferings = append(serviceOfferings, s)
+		}
+	}
+
+	if len(serviceOfferings) == 0 {
+		return fmt.Errorf("No service offering is matching with the specified regex")
+	}
+	//return the latest service offering from the list of filtered service according
+	//to its creation date
+	serviceOffering, err := latestServiceOffering(serviceOfferings)
+	if err != nil {
+		return err
+	}
+	log.Printf("[DEBUG] Selected service offerings: %s\n", serviceOffering.Displaytext)
+
+	return serviceOfferingDescriptionAttributes(d, serviceOffering)
+}
+
+func serviceOfferingDescriptionAttributes(d *schema.ResourceData, serviceOffering *cloudstack.ServiceOffering) error {
+	d.SetId(serviceOffering.Id)
+	d.Set("name", serviceOffering.Name)
+	d.Set("display_text", serviceOffering.Displaytext)
+
+	return nil
+}
+
+func latestServiceOffering(serviceOfferings []*cloudstack.ServiceOffering) (*cloudstack.ServiceOffering, error) {
+	var latest time.Time
+	var serviceOffering *cloudstack.ServiceOffering
+
+	for _, s := range serviceOfferings {
+		created, err := time.Parse("2006-01-02T15:04:05-0700", s.Created)
+		if err != nil {
+			return nil, fmt.Errorf("Failed to parse creation date of an service offering: %s", err)
+		}
+
+		if created.After(latest) {
+			latest = created
+			serviceOffering = s
+		}
+	}
+
+	return serviceOffering, nil
+}
+
+func applyServiceOfferingFilters(serviceOffering *cloudstack.ServiceOffering, filters *schema.Set) (bool, error) {
+	var serviceOfferingJSON map[string]interface{}
+	k, _ := json.Marshal(serviceOffering)
+	err := json.Unmarshal(k, &serviceOfferingJSON)
+	if err != nil {
+		return false, err
+	}
+
+	for _, f := range filters.List() {
+		m := f.(map[string]interface{})
+		r, err := regexp.Compile(m["value"].(string))
+		if err != nil {
+			return false, fmt.Errorf("Invalid regex: %s", err)
+		}
+		updatedName := strings.ReplaceAll(m["name"].(string), "_", "")
+		serviceOfferingField := serviceOfferingJSON[updatedName].(string)
+		if !r.MatchString(serviceOfferingField) {
+			return false, nil
+		}
+
+	}
+	return true, nil
+}
diff --git a/cloudstack/data_source_cloudstack_service_offering_test.go b/cloudstack/data_source_cloudstack_service_offering_test.go
new file mode 100644
index 0000000..fbc3faa
--- /dev/null
+++ b/cloudstack/data_source_cloudstack_service_offering_test.go
@@ -0,0 +1,62 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package cloudstack
+
+import (
+	"testing"
+
+	"github.com/hashicorp/terraform/helper/resource"
+)
+
+func TestAccServiceOfferingDataSource_basic(t *testing.T) {
+	resourceName := "cloudstack_service_offering.service-offering-resource"
+	datasourceName := "cloudstack_service_offering.service-offering-data-source"
+
+	resource.Test(t, resource.TestCase{
+		PreCheck:  func() { testAccPreCheck(t) },
+		Providers: testAccProviders,
+		Steps: []resource.TestStep{
+			{
+				Config: testServiceOfferingDataSourceConfig_basic,
+				Check: resource.ComposeTestCheckFunc(
+					resource.TestCheckResourceAttrPair(datasourceName, "name", resourceName, "name"),
+				),
+				ExpectNonEmptyPlan: true,
+			},
+		},
+	})
+}
+
+const testServiceOfferingDataSourceConfig_basic = `
+resource "cloudstack_service_offering" "service-offering-resource"{
+	name       = "TestServiceUpdate"
+  display_text = "DisplayService"
+  }
+
+ data "cloudstack_service_offering" "service-offering-data-source"{
+    filter{
+    name = "name"
+    value="TestServiceUpdate"
+    }
+	  depends_on = [
+	  cloudstack_service_offering.service-resource
+	] 
+  }
+  `
diff --git a/cloudstack/data_source_cloudstack_ssh_keypair.go b/cloudstack/data_source_cloudstack_ssh_keypair.go
new file mode 100644
index 0000000..c7696cb
--- /dev/null
+++ b/cloudstack/data_source_cloudstack_ssh_keypair.go
@@ -0,0 +1,113 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package cloudstack
+
+import (
+	"encoding/json"
+	"fmt"
+	"log"
+	"regexp"
+	"strings"
+
+	"github.com/apache/cloudstack-go/v2/cloudstack"
+	"github.com/hashicorp/terraform/helper/schema"
+)
+
+func dataSourceCloudstackSSHKeyPair() *schema.Resource {
+	return &schema.Resource{
+		Read: dataSourceCloudstackSSHKeyPairRead,
+
+		Schema: map[string]*schema.Schema{
+			"filter": dataSourceFiltersSchema(),
+
+			//Computed values
+			"fingerprint": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+
+			"name": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+		},
+	}
+}
+
+func dataSourceCloudstackSSHKeyPairRead(d *schema.ResourceData, meta interface{}) error {
+	cs := meta.(*cloudstack.CloudStackClient)
+	p := cs.SSH.NewListSSHKeyPairsParams()
+	csSshKeyPairs, err := cs.SSH.ListSSHKeyPairs(p)
+
+	if err != nil {
+		return fmt.Errorf("Failed to list ssh key pairs: %s", err)
+	}
+	filters := d.Get("filter")
+	var sshKeyPair *cloudstack.SSHKeyPair
+
+	for _, k := range csSshKeyPairs.SSHKeyPairs {
+		match, err := applySshKeyPairsFilters(k, filters.(*schema.Set))
+		if err != nil {
+			return err
+		}
+		if match {
+			sshKeyPair = k
+		}
+	}
+
+	if sshKeyPair == nil {
+		return fmt.Errorf("No ssh key pair is matching with the specified regex")
+	}
+	log.Printf("[DEBUG] Selected ssh key pair: %s\n", sshKeyPair.Name)
+
+	return sshKeyPairDescriptionAttributes(d, sshKeyPair)
+}
+
+func sshKeyPairDescriptionAttributes(d *schema.ResourceData, sshKeyPair *cloudstack.SSHKeyPair) error {
+	d.SetId(sshKeyPair.Name)
+	d.Set("fingerprint", sshKeyPair.Fingerprint)
+	d.Set("name", sshKeyPair.Name)
+
+	return nil
+}
+
+func applySshKeyPairsFilters(sshKeyPair *cloudstack.SSHKeyPair, filters *schema.Set) (bool, error) {
+	var sshKeyPairJSON map[string]interface{}
+	k, _ := json.Marshal(sshKeyPair)
+	err := json.Unmarshal(k, &sshKeyPairJSON)
+	if err != nil {
+		return false, err
+	}
+
+	for _, f := range filters.List() {
+		m := f.(map[string]interface{})
+		r, err := regexp.Compile(m["value"].(string))
+		if err != nil {
+			return false, fmt.Errorf("Invalid regex: %s", err)
+		}
+		updatedName := strings.ReplaceAll(m["name"].(string), "_", "")
+		sshKeyPairField := sshKeyPairJSON[updatedName].(string)
+		if !r.MatchString(sshKeyPairField) {
+			return false, nil
+		}
+
+	}
+	return true, nil
+}
diff --git a/cloudstack/data_source_cloudstack_ssh_keypair_test.go b/cloudstack/data_source_cloudstack_ssh_keypair_test.go
new file mode 100644
index 0000000..32bd3fd
--- /dev/null
+++ b/cloudstack/data_source_cloudstack_ssh_keypair_test.go
@@ -0,0 +1,62 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package cloudstack
+
+import (
+	"testing"
+
+	"github.com/hashicorp/terraform/helper/resource"
+)
+
+func TestAccSshKeyPairDataSource_basic(t *testing.T) {
+	resourceName := "cloudstack_ssh_keypair.ssh-keypair-resource"
+	datasourceName := "data.cloudstack_ssh_keypair.ssh-keypair-data"
+
+	resource.Test(t, resource.TestCase{
+		PreCheck:  func() { testAccPreCheck(t) },
+		Providers: testAccProviders,
+		Steps: []resource.TestStep{
+			{
+				Config: testAccSshKeyPairDataSourceConfig_basic,
+				Check: resource.ComposeTestCheckFunc(
+					resource.TestCheckResourceAttrPair(datasourceName, "id", resourceName, "id"),
+				),
+				ExpectNonEmptyPlan: true,
+			},
+		},
+	})
+}
+
+const testAccSshKeyPairDataSourceConfig_basic = `
+	resource "cloudstack_ssh_keypair" "ssh-keypair-resource"{
+	name       = "myKey"
+  }
+  
+  data "cloudstack_ssh_keypair" "ssh-keypair-data" {
+	  filter {
+	  name = "name" 
+	  value = "myKey"
+	}
+	  depends_on = [
+	  cloudstack_ssh_keypair.ssh-keypair-resource
+	]
+  
+  }
+  `
diff --git a/cloudstack/data_source_cloudstack_user.go b/cloudstack/data_source_cloudstack_user.go
new file mode 100644
index 0000000..a40862a
--- /dev/null
+++ b/cloudstack/data_source_cloudstack_user.go
@@ -0,0 +1,154 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package cloudstack
+
+import (
+	"encoding/json"
+	"fmt"
+	"log"
+	"regexp"
+	"strings"
+	"time"
+
+	"github.com/apache/cloudstack-go/v2/cloudstack"
+	"github.com/hashicorp/terraform/helper/schema"
+)
+
+func dataSourceCloudstackUser() *schema.Resource {
+	return &schema.Resource{
+		Read: datasourceCloudStackUserRead,
+		Schema: map[string]*schema.Schema{
+			"filter": dataSourceFiltersSchema(),
+
+			//Computed values
+			"account": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+			"email": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+			"first_name": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+			"last_name": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+			"username": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+		},
+	}
+}
+
+func datasourceCloudStackUserRead(d *schema.ResourceData, meta interface{}) error {
+	cs := meta.(*cloudstack.CloudStackClient)
+	p := cs.User.NewListUsersParams()
+	csUsers, err := cs.User.ListUsers(p)
+
+	if err != nil {
+		return fmt.Errorf("Failed to list users: %s", err)
+	}
+
+	filters := d.Get("filter")
+	var users []*cloudstack.User
+
+	for _, u := range csUsers.Users {
+		match, err := applyUserFilters(u, filters.(*schema.Set))
+		if err != nil {
+			return err
+		}
+		if match {
+			users = append(users, u)
+		}
+	}
+
+	if len(users) == 0 {
+		return fmt.Errorf("No user is matching with the specified regex")
+	}
+	//return the latest user from the list of filtered userss according
+	//to its creation date
+	user, err := latestUser(users)
+	if err != nil {
+		return err
+	}
+	log.Printf("[DEBUG] Selected users: %s\n", user.Username)
+
+	return userDescriptionAttributes(d, user)
+}
+
+func userDescriptionAttributes(d *schema.ResourceData, user *cloudstack.User) error {
+	d.SetId(user.Id)
+	d.Set("account", user.Account)
+	d.Set("email", user.Email)
+	d.Set("first_name", user.Firstname)
+	d.Set("last_name", user.Lastname)
+	d.Set("username", user.Username)
+
+	return nil
+}
+
+func latestUser(users []*cloudstack.User) (*cloudstack.User, error) {
+	var latest time.Time
+	var user *cloudstack.User
+
+	for _, u := range users {
+		created, err := time.Parse("2006-01-02T15:04:05-0700", u.Created)
+		if err != nil {
+			return nil, fmt.Errorf("Failed to parse creation date of a user: %s", err)
+		}
+
+		if created.After(latest) {
+			latest = created
+			user = u
+		}
+	}
+
+	return user, nil
+}
+
+func applyUserFilters(user *cloudstack.User, filters *schema.Set) (bool, error) {
+	var userJSON map[string]interface{}
+	k, _ := json.Marshal(user)
+	err := json.Unmarshal(k, &userJSON)
+	if err != nil {
+		return false, err
+	}
+
+	for _, f := range filters.List() {
+		m := f.(map[string]interface{})
+		log.Print(m)
+		r, err := regexp.Compile(m["value"].(string))
+		if err != nil {
+			return false, fmt.Errorf("Invalid regex: %s", err)
+		}
+		updatedName := strings.ReplaceAll(m["name"].(string), "_", "")
+		log.Print(updatedName)
+		userField := userJSON[updatedName].(string)
+		if !r.MatchString(userField) {
+			return false, nil
+		}
+	}
+	return true, nil
+}
diff --git a/cloudstack/data_source_cloudstack_user_test.go b/cloudstack/data_source_cloudstack_user_test.go
new file mode 100644
index 0000000..aa9c14d
--- /dev/null
+++ b/cloudstack/data_source_cloudstack_user_test.go
@@ -0,0 +1,70 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package cloudstack
+
+import (
+	"testing"
+
+	"github.com/hashicorp/terraform/helper/resource"
+)
+
+func TestAccUserDataSource_basic(t *testing.T) {
+	resourceName := "cloudstack_user.user-resource"
+	datasourceName := "data.cloudstack_user.user-data-source"
+
+	resource.Test(t, resource.TestCase{
+		PreCheck:  func() { testAccPreCheck(t) },
+		Providers: testAccProviders,
+		Steps: []resource.TestStep{
+			{
+				Config: testUserDataSourceConfig_basic,
+				Check: resource.ComposeTestCheckFunc(
+					resource.TestCheckResourceAttrPair(datasourceName, "first_name", resourceName, "first_name"),
+				),
+				ExpectNonEmptyPlan: true,
+			},
+		},
+	})
+}
+
+const testUserDataSourceConfig_basic = `
+resource "cloudstack_user" "user-resource" {
+  account = "admin"
+  email         = "jon.doe@gmail.com"
+  first_name    = "jon"
+  last_name     = "doe"
+  password      = "password"
+  username      = "jon123"
+}
+
+data "cloudstack_user" "user-data-source"{
+    filter{
+    name = "first_name"
+    value= "jon"
+    }
+    depends_on = [
+	  cloudstack_user.user-resource
+	]
+  }
+
+output "user-output" {
+  value = "${data.cloudstack_user.user-data-source}"
+}
+  `
diff --git a/cloudstack/data_source_cloudstack_volume.go b/cloudstack/data_source_cloudstack_volume.go
new file mode 100644
index 0000000..e8c6bdb
--- /dev/null
+++ b/cloudstack/data_source_cloudstack_volume.go
@@ -0,0 +1,143 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package cloudstack
+
+import (
+	"encoding/json"
+	"fmt"
+	"log"
+	"regexp"
+	"strings"
+	"time"
+
+	"github.com/apache/cloudstack-go/v2/cloudstack"
+	"github.com/hashicorp/terraform/helper/schema"
+)
+
+func dataSourceCloudstackVolume() *schema.Resource {
+	return &schema.Resource{
+		Read: datasourceCloudStackVolumeRead,
+		Schema: map[string]*schema.Schema{
+			"filter": dataSourceFiltersSchema(),
+
+			//Computed values
+			"name": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+			"disk_offering_id": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+			"zone_id": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+		},
+	}
+}
+
+func datasourceCloudStackVolumeRead(d *schema.ResourceData, meta interface{}) error {
+	cs := meta.(*cloudstack.CloudStackClient)
+	p := cs.Volume.NewListVolumesParams()
+	csVolumes, err := cs.Volume.ListVolumes(p)
+
+	if err != nil {
+		return fmt.Errorf("Failed to list volumes: %s", err)
+	}
+
+	filters := d.Get("filter")
+	var volumes []*cloudstack.Volume
+
+	for _, v := range csVolumes.Volumes {
+		match, err := applyVolumeFilters(v, filters.(*schema.Set))
+		if err != nil {
+			return err
+		}
+		if match {
+			volumes = append(volumes, v)
+		}
+	}
+
+	if len(volumes) == 0 {
+		return fmt.Errorf("No volume is matching with the specified regex")
+	}
+	//return the latest volume from the list of filtered volumes according
+	//to its creation date
+	volume, err := latestVolume(volumes)
+	if err != nil {
+		return err
+	}
+	log.Printf("[DEBUG] Selected volume: %s\n", volume.Name)
+
+	return volumeDescriptionAttributes(d, volume)
+}
+
+func volumeDescriptionAttributes(d *schema.ResourceData, volume *cloudstack.Volume) error {
+	d.SetId(volume.Id)
+	d.Set("name", volume.Name)
+	d.Set("disk_offering_id", volume.Diskofferingid)
+	d.Set("zone_id", volume.Zoneid)
+
+	return nil
+}
+
+func latestVolume(volumes []*cloudstack.Volume) (*cloudstack.Volume, error) {
+	var latest time.Time
+	var volume *cloudstack.Volume
+
+	for _, v := range volumes {
+		created, err := time.Parse("2006-01-02T15:04:05-0700", v.Created)
+		if err != nil {
+			return nil, fmt.Errorf("Failed to parse creation date of a volume: %s", err)
+		}
+
+		if created.After(latest) {
+			latest = created
+			volume = v
+		}
+	}
+
+	return volume, nil
+}
+
+func applyVolumeFilters(volume *cloudstack.Volume, filters *schema.Set) (bool, error) {
+	var volumeJSON map[string]interface{}
+	v, _ := json.Marshal(volume)
+	err := json.Unmarshal(v, &volumeJSON)
+	if err != nil {
+		return false, err
+	}
+
+	for _, f := range filters.List() {
+		m := f.(map[string]interface{})
+		r, err := regexp.Compile(m["value"].(string))
+		if err != nil {
+			return false, fmt.Errorf("Invalid regex: %s", err)
+		}
+		updatedName := strings.ReplaceAll(m["name"].(string), "_", "")
+		volume := volumeJSON[updatedName].(string)
+		if !r.MatchString(volume) {
+			return false, nil
+		}
+
+	}
+	return true, nil
+}
diff --git a/cloudstack/data_source_cloudstack_volume_test.go b/cloudstack/data_source_cloudstack_volume_test.go
new file mode 100644
index 0000000..147a701
--- /dev/null
+++ b/cloudstack/data_source_cloudstack_volume_test.go
@@ -0,0 +1,63 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package cloudstack
+
+import (
+	"testing"
+
+	"github.com/hashicorp/terraform/helper/resource"
+)
+
+func TestAccVolumeDataSource_basic(t *testing.T) {
+	resourceName := "cloudstack_volume.volume-resource"
+	datasourceName := "data.cloudstack_volume.volume-data-source"
+
+	resource.Test(t, resource.TestCase{
+		PreCheck:  func() { testAccPreCheck(t) },
+		Providers: testAccProviders,
+		Steps: []resource.TestStep{
+			{
+				Config: testVolumeDataSourceConfig_basic,
+				Check: resource.ComposeTestCheckFunc(
+					resource.TestCheckResourceAttrPair(datasourceName, "name", resourceName, "name"),
+				),
+				ExpectNonEmptyPlan: true,
+			},
+		},
+	})
+}
+
+const testVolumeDataSourceConfig_basic = `
+resource "cloudstack_volume" "volume-resource"{
+	name       = "TestVolume"
+  disk_offering_id = "0038adec-5e3e-47df-b4b4-77b5dc8e3338"
+  zone_id = "9a7002b2-09a2-44dc-a332-f2e4e7f01539"
+  }
+
+  data "cloudstack_volume" "volume-data-source"{
+    filter{
+    name = "name"
+    value="TestVolume"
+    }
+	  depends_on = [
+	  cloudstack_volume.volume-resource
+	]
+  }
+  `
diff --git a/cloudstack/data_source_cloudstack_vpc.go b/cloudstack/data_source_cloudstack_vpc.go
new file mode 100644
index 0000000..a473d99
--- /dev/null
+++ b/cloudstack/data_source_cloudstack_vpc.go
@@ -0,0 +1,173 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package cloudstack
+
+import (
+	"encoding/json"
+	"fmt"
+	"log"
+	"regexp"
+	"strings"
+	"time"
+
+	"github.com/apache/cloudstack-go/v2/cloudstack"
+	"github.com/hashicorp/terraform/helper/schema"
+)
+
+func dataSourceCloudstackVPC() *schema.Resource {
+	return &schema.Resource{
+		Read: datasourceCloudStackVPCRead,
+		Schema: map[string]*schema.Schema{
+			"filter": dataSourceFiltersSchema(),
+
+			//Computed values
+			"name": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+
+			"display_text": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+
+			"cidr": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+
+			"vpc_offering_name": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+
+			"network_domain": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+
+			"project": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+
+			"zone_name": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+
+			"tags": tagsSchema(),
+		},
+	}
+}
+
+func datasourceCloudStackVPCRead(d *schema.ResourceData, meta interface{}) error {
+	cs := meta.(*cloudstack.CloudStackClient)
+	p := cs.VPC.NewListVPCsParams()
+	csVPCs, err := cs.VPC.ListVPCs(p)
+
+	if err != nil {
+		return fmt.Errorf("Failed to list VPCs: %s", err)
+	}
+
+	filters := d.Get("filter")
+	var vpcs []*cloudstack.VPC
+
+	for _, v := range csVPCs.VPCs {
+		match, err := applyVPCFilters(v, filters.(*schema.Set))
+		if err != nil {
+			return err
+		}
+		if match {
+			vpcs = append(vpcs, v)
+		}
+	}
+
+	if len(vpcs) == 0 {
+		return fmt.Errorf("No VPC is matching with the specified regex")
+	}
+	//return the latest VPC from the list of filtered VPCs according
+	//to its creation date
+	vpc, err := latestVPC(vpcs)
+	if err != nil {
+		return err
+	}
+	log.Printf("[DEBUG] Selected VPCs: %s\n", vpc.Displaytext)
+
+	return vpcDescriptionAttributes(d, vpc)
+}
+
+func vpcDescriptionAttributes(d *schema.ResourceData, vpc *cloudstack.VPC) error {
+	d.SetId(vpc.Id)
+	d.Set("name", vpc.Name)
+	d.Set("display_text", vpc.Displaytext)
+	d.Set("cidr", vpc.Cidr)
+	d.Set("vpc_offering_name", vpc.Vpcofferingname)
+	d.Set("network_domain", vpc.Networkdomain)
+	d.Set("project", vpc.Project)
+	d.Set("zone_name", vpc.Zonename)
+	d.Set("tags", vpc.Tags)
+
+	return nil
+}
+
+func latestVPC(vpcs []*cloudstack.VPC) (*cloudstack.VPC, error) {
+	var latest time.Time
+	var vpc *cloudstack.VPC
+
+	for _, v := range vpcs {
+		created, err := time.Parse("2006-01-02T15:04:05-0700", v.Created)
+		if err != nil {
+			return nil, fmt.Errorf("Failed to parse creation date of a VPC: %s", err)
+		}
+
+		if created.After(latest) {
+			latest = created
+			vpc = v
+		}
+	}
+
+	return vpc, nil
+}
+
+func applyVPCFilters(vpc *cloudstack.VPC, filters *schema.Set) (bool, error) {
+	var vpcJSON map[string]interface{}
+	k, _ := json.Marshal(vpc)
+	err := json.Unmarshal(k, &vpcJSON)
+	if err != nil {
+		return false, err
+	}
+
+	for _, f := range filters.List() {
+		m := f.(map[string]interface{})
+		log.Print(m)
+		r, err := regexp.Compile(m["value"].(string))
+		if err != nil {
+			return false, fmt.Errorf("Invalid regex: %s", err)
+		}
+		updatedName := strings.ReplaceAll(m["name"].(string), "_", "")
+		log.Print(updatedName)
+		vpcField := vpcJSON[updatedName].(string)
+		if !r.MatchString(vpcField) {
+			return false, nil
+		}
+	}
+	return true, nil
+}
diff --git a/cloudstack/data_source_cloudstack_vpc_test.go b/cloudstack/data_source_cloudstack_vpc_test.go
new file mode 100644
index 0000000..3920f02
--- /dev/null
+++ b/cloudstack/data_source_cloudstack_vpc_test.go
@@ -0,0 +1,72 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package cloudstack
+
+import (
+	"testing"
+
+	"github.com/hashicorp/terraform/helper/resource"
+)
+
+func TestAccVPCDataSource_basic(t *testing.T) {
+	resourceName := "cloudstack_vpc.vpc-resource"
+	datasourceName := "data.cloudstack_vpc.vpc-data-source"
+
+	resource.Test(t, resource.TestCase{
+		PreCheck:  func() { testAccPreCheck(t) },
+		Providers: testAccProviders,
+		Steps: []resource.TestStep{
+			{
+				Config: testVPCDataSourceConfig_basic,
+				Check: resource.ComposeTestCheckFunc(
+					resource.TestCheckResourceAttrPair(datasourceName, "name", resourceName, "name"),
+				),
+				ExpectNonEmptyPlan: true,
+			},
+		},
+	})
+}
+
+const testVPCDataSourceConfig_basic = `
+resource "cloudstack_vpc" "vpc-resource" {
+name         = "test-vpc"
+cidr         = "10.0.0.0/16"
+vpc_offering = "Default VPC Offering"
+zone         = "DC"
+}
+
+data "cloudstack_vpc" "vpc-data-source"{
+  filter{
+  name = "name"
+  value= "test-vpc"
+  }
+  filter{
+  name = "cidr"
+  value= "10.0.0.0/16"
+  }
+  depends_on = [
+	cloudstack_vpc.vpc-resource
+  ]
+}
+
+output "vpc-output" {
+value = "${data.cloudstack_vpc.vpc-data-source}"
+}
+  `
diff --git a/cloudstack/data_source_cloudstack_vpn_connection.go b/cloudstack/data_source_cloudstack_vpn_connection.go
new file mode 100644
index 0000000..c0015bf
--- /dev/null
+++ b/cloudstack/data_source_cloudstack_vpn_connection.go
@@ -0,0 +1,140 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package cloudstack
+
+import (
+	"encoding/json"
+	"fmt"
+	"log"
+	"regexp"
+	"strings"
+	"time"
+
+	"github.com/apache/cloudstack-go/v2/cloudstack"
+	"github.com/hashicorp/terraform/helper/schema"
+)
+
+func dataSourceCloudstackVPNConnection() *schema.Resource {
+	return &schema.Resource{
+		Read: datasourceCloudStackVPNConnectionRead,
+		Schema: map[string]*schema.Schema{
+			"filter": dataSourceFiltersSchema(),
+
+			//Computed values
+			"s2s_customer_gateway_id": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+
+			"s2s_vpn_gateway_id": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+		},
+	}
+}
+
+func datasourceCloudStackVPNConnectionRead(d *schema.ResourceData, meta interface{}) error {
+	cs := meta.(*cloudstack.CloudStackClient)
+	p := cs.VPN.NewListVpnConnectionsParams()
+	csVPNConnections, err := cs.VPN.ListVpnConnections(p)
+
+	if err != nil {
+		return fmt.Errorf("Failed to list VPNs: %s", err)
+	}
+
+	filters := d.Get("filter")
+	var vpnConnections []*cloudstack.VpnConnection
+
+	for _, v := range csVPNConnections.VpnConnections {
+		match, err := applyVPNConnectionFilters(v, filters.(*schema.Set))
+		if err != nil {
+			return err
+		}
+		if match {
+			vpnConnections = append(vpnConnections, v)
+		}
+	}
+
+	if len(vpnConnections) == 0 {
+		return fmt.Errorf("No VPN Connection is matching with the specified regex")
+	}
+	//return the latest VPN Connection from the list of filtered VPN Connections according
+	//to its creation date
+	vpnConnection, err := latestVPNConnection(vpnConnections)
+	if err != nil {
+		return err
+	}
+	log.Printf("[DEBUG] Selected VPN Connections: %s\n", vpnConnection.Id)
+
+	return vpnConnectionDescriptionAttributes(d, vpnConnection)
+}
+
+func vpnConnectionDescriptionAttributes(d *schema.ResourceData, vpnConnection *cloudstack.VpnConnection) error {
+	d.SetId(vpnConnection.Id)
+	d.Set("s2s_customer_gateway_id", vpnConnection.S2scustomergatewayid)
+	d.Set("s2s_vpn_gateway_id", vpnConnection.S2svpngatewayid)
+
+	return nil
+}
+
+func latestVPNConnection(vpnConnections []*cloudstack.VpnConnection) (*cloudstack.VpnConnection, error) {
+	var latest time.Time
+	var vpnConnection *cloudstack.VpnConnection
+
+	for _, v := range vpnConnections {
+		created, err := time.Parse("2006-01-02T15:04:05-0700", v.Created)
+		if err != nil {
+			return nil, fmt.Errorf("Failed to parse creation date of a VPN Connection: %s", err)
+		}
+
+		if created.After(latest) {
+			latest = created
+			vpnConnection = v
+		}
+	}
+
+	return vpnConnection, nil
+}
+
+func applyVPNConnectionFilters(vpnConnection *cloudstack.VpnConnection, filters *schema.Set) (bool, error) {
+	var vpnConnectionJSON map[string]interface{}
+	k, _ := json.Marshal(vpnConnection)
+	err := json.Unmarshal(k, &vpnConnectionJSON)
+	if err != nil {
+		return false, err
+	}
+
+	for _, f := range filters.List() {
+		m := f.(map[string]interface{})
+		log.Print(m)
+		r, err := regexp.Compile(m["value"].(string))
+		if err != nil {
+			return false, fmt.Errorf("Invalid regex: %s", err)
+		}
+		updatedName := strings.ReplaceAll(m["name"].(string), "_", "")
+		log.Print(updatedName)
+		vpnConnectionField := vpnConnectionJSON[updatedName].(string)
+		if !r.MatchString(vpnConnectionField) {
+			return false, nil
+		}
+	}
+	return true, nil
+}
diff --git a/cloudstack/data_source_cloudstack_zone.go b/cloudstack/data_source_cloudstack_zone.go
new file mode 100644
index 0000000..39c8317
--- /dev/null
+++ b/cloudstack/data_source_cloudstack_zone.go
@@ -0,0 +1,121 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package cloudstack
+
+import (
+	"encoding/json"
+	"fmt"
+	"log"
+	"regexp"
+	"strings"
+
+	"github.com/apache/cloudstack-go/v2/cloudstack"
+	"github.com/hashicorp/terraform/helper/schema"
+)
+
+func dataSourceCloudStackZone() *schema.Resource {
+	return &schema.Resource{
+		Read: dataSourceCloudstackZoneRead,
+		Schema: map[string]*schema.Schema{
+			"filter": dataSourceFiltersSchema(),
+
+			//Computed values
+			"name": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+			"dns1": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+			"internal_dns1": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+			"network_type": {
+				Type:     schema.TypeString,
+				Computed: true,
+			},
+		},
+	}
+}
+
+func dataSourceCloudstackZoneRead(d *schema.ResourceData, meta interface{}) error {
+	cs := meta.(*cloudstack.CloudStackClient)
+	p := cs.Zone.NewListZonesParams()
+	csZones, err := cs.Zone.ListZones(p)
+
+	if err != nil {
+		return fmt.Errorf("Failed to list zones: %s", err)
+	}
+	filters := d.Get("filter")
+	var zone *cloudstack.Zone
+
+	for _, z := range csZones.Zones {
+		match, err := applyZoneFilters(z, filters.(*schema.Set))
+		if err != nil {
+			return err
+		}
+		if match {
+			zone = z
+		}
+	}
+
+	if zone == nil {
+		return fmt.Errorf("No zone is matching with the specified regex")
+	}
+	log.Printf("[DEBUG] Selected zone: %s\n", zone.Name)
+
+	return zoneDescriptionAttributes(d, zone)
+}
+
+func zoneDescriptionAttributes(d *schema.ResourceData, zone *cloudstack.Zone) error {
+	d.SetId(zone.Name)
+	d.Set("name", zone.Name)
+	d.Set("dns1", zone.Dns1)
+	d.Set("internal_dns1", zone.Internaldns1)
+	d.Set("network_type", zone.Networktype)
+
+	return nil
+}
+
+func applyZoneFilters(zone *cloudstack.Zone, filters *schema.Set) (bool, error) {
+	var zoneJSON map[string]interface{}
+	k, _ := json.Marshal(zone)
+	err := json.Unmarshal(k, &zoneJSON)
+	if err != nil {
+		return false, err
+	}
+
+	for _, f := range filters.List() {
+		m := f.(map[string]interface{})
+		r, err := regexp.Compile(m["value"].(string))
+		if err != nil {
+			return false, fmt.Errorf("Invalid regex: %s", err)
+		}
+		updatedName := strings.ReplaceAll(m["name"].(string), "_", "")
+		zoneField := zoneJSON[updatedName].(string)
+		if !r.MatchString(zoneField) {
+			return false, nil
+		}
+
+	}
+	return true, nil
+}
diff --git a/cloudstack/data_source_cloudstack_zone_test.go b/cloudstack/data_source_cloudstack_zone_test.go
new file mode 100644
index 0000000..b02bb48
--- /dev/null
+++ b/cloudstack/data_source_cloudstack_zone_test.go
@@ -0,0 +1,66 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package cloudstack
+
+import (
+	"testing"
+
+	"github.com/hashicorp/terraform/helper/resource"
+)
+
+func TestAccZoneDataSource_basic(t *testing.T) {
+	resourceName := "cloudstack_zone.zone-resource"
+	datasourceName := "data.cloudstack_zone.zone-data-source"
+
+	resource.Test(t, resource.TestCase{
+		PreCheck:  func() { testAccPreCheck(t) },
+		Providers: testAccProviders,
+		Steps: []resource.TestStep{
+			{
+				Config: testZoneDataSourceConfig_basic,
+				Check: resource.ComposeTestCheckFunc(
+					resource.TestCheckResourceAttrPair(datasourceName, "name", resourceName, "name"),
+				),
+				ExpectNonEmptyPlan: true,
+			},
+		},
+	})
+}
+
+const testZoneDataSourceConfig_basic = `
+resource "cloudstack_zone" "zone-resource"{
+	name       = "TestZone"
+  dns1       = "8.8.8.8"
+  internal_dns1  =  "172.20.0.1"
+  network_type   =  "Advanced"
+  }
+
+  data "cloudstack_zone" "zone-data-source"{
+
+    filter{
+    name = "name"
+    value="TestZone"
+    }
+	  depends_on = [
+	  cloudstack_zone.zone-resource
+	]
+  
+  }
+  `
diff --git a/cloudstack/provider.go b/cloudstack/provider.go
index 4949c2f..c39914e 100644
--- a/cloudstack/provider.go
+++ b/cloudstack/provider.go
@@ -78,7 +78,17 @@
 		},
 
 		DataSourcesMap: map[string]*schema.Resource{
-			"cloudstack_template": dataSourceCloudstackTemplate(),
+			"cloudstack_template":         dataSourceCloudstackTemplate(),
+			"cloudstack_ssh_keypair":      dataSourceCloudstackSSHKeyPair(),
+			"cloudstack_instance":         dataSourceCloudstackInstance(),
+			"cloudstack_network_offering": dataSourceCloudstackNetworkOffering(),
+			"cloudstack_zone":             dataSourceCloudStackZone(),
+			"cloudstack_service_offering": dataSourceCloudstackServiceOffering(),
+			"cloudstack_volume":           dataSourceCloudstackVolume(),
+			"cloudstack_vpc":              dataSourceCloudstackVPC(),
+			"cloudstack_ipaddress":        dataSourceCloudstackIPAddress(),
+			"cloudstack_user":             dataSourceCloudstackUser(),
+			"cloudstack_vpn_connection":   dataSourceCloudstackVPNConnection(),
 		},
 
 		ResourcesMap: map[string]*schema.Resource{
@@ -109,6 +119,14 @@
 			"cloudstack_vpn_connection":       resourceCloudStackVPNConnection(),
 			"cloudstack_vpn_customer_gateway": resourceCloudStackVPNCustomerGateway(),
 			"cloudstack_vpn_gateway":          resourceCloudStackVPNGateway(),
+			"cloudstack_network_offering":     resourceCloudStackNetworkOffering(),
+			"cloudstack_disk_offering":        resourceCloudStackDiskOffering(),
+			"cloudstack_volume":               resourceCloudStackVolume(),
+			"cloudstack_zone":                 resourceCloudStackZone(),
+			"cloudstack_service_offering":     resourceCloudStackServiceOffering(),
+			"cloudstack_account":              resourceCloudStackAccount(),
+			"cloudstack_user":                 resourceCloudStackUser(),
+			"cloudstack_domain":               resourceCloudStackDomain(),
 		},
 
 		ConfigureFunc: providerConfigure,
diff --git a/cloudstack/resource_cloudstack_account.go b/cloudstack/resource_cloudstack_account.go
new file mode 100644
index 0000000..a0d950f
--- /dev/null
+++ b/cloudstack/resource_cloudstack_account.go
@@ -0,0 +1,123 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package cloudstack
+
+import (
+	"fmt"
+	"log"
+
+	"github.com/apache/cloudstack-go/v2/cloudstack"
+	"github.com/hashicorp/terraform/helper/schema"
+)
+
+func resourceCloudStackAccount() *schema.Resource {
+	return &schema.Resource{
+		Read:   resourceCloudStackAccountRead,
+		Update: resourceCloudStackAccountUpdate,
+		Create: resourceCloudStackAccountCreate,
+		Delete: resourceCloudStackAccountDelete,
+		Schema: map[string]*schema.Schema{
+			"email": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"first_name": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"last_name": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"password": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"username": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"account_type": {
+				Type:     schema.TypeInt,
+				Required: true,
+			},
+			"role_id": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"account": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
+		},
+	}
+}
+
+func resourceCloudStackAccountCreate(d *schema.ResourceData, meta interface{}) error {
+	cs := meta.(*cloudstack.CloudStackClient)
+	email := d.Get("email").(string)
+	first_name := d.Get("first_name").(string)
+	last_name := d.Get("last_name").(string)
+	username := d.Get("username").(string)
+	password := d.Get("password").(string)
+	role_id := d.Get("role_id").(string)
+	account_type := d.Get("account_type").(int)
+	account := d.Get("account").(string)
+
+	// Create a new parameter struct
+	p := cs.Account.NewCreateAccountParams(email, first_name, last_name, password, username)
+	p.SetAccounttype(int(account_type))
+	p.SetRoleid(role_id)
+	if account != "" {
+		p.SetAccount(account)
+	} else {
+		p.SetAccount(username)
+	}
+
+	log.Printf("[DEBUG] Creating Account %s", account)
+	a, err := cs.Account.CreateAccount(p)
+
+	if err != nil {
+		return err
+	}
+
+	log.Printf("[DEBUG] Account %s successfully created", account)
+	d.SetId(a.Id)
+
+	return resourceCloudStackAccountRead(d, meta)
+}
+
+func resourceCloudStackAccountRead(d *schema.ResourceData, meta interface{}) error { return nil }
+
+func resourceCloudStackAccountUpdate(d *schema.ResourceData, meta interface{}) error { return nil }
+
+func resourceCloudStackAccountDelete(d *schema.ResourceData, meta interface{}) error {
+	cs := meta.(*cloudstack.CloudStackClient)
+
+	// Create a new parameter struct
+	p := cs.Account.NewDeleteAccountParams(d.Id())
+	_, err := cs.Account.DeleteAccount(p)
+
+	if err != nil {
+		return fmt.Errorf("Error deleting Account: %s", err)
+	}
+
+	return nil
+}
diff --git a/cloudstack/resource_cloudstack_disk_offering.go b/cloudstack/resource_cloudstack_disk_offering.go
new file mode 100644
index 0000000..daa6b88
--- /dev/null
+++ b/cloudstack/resource_cloudstack_disk_offering.go
@@ -0,0 +1,79 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package cloudstack
+
+import (
+	"log"
+
+	"github.com/apache/cloudstack-go/v2/cloudstack"
+	"github.com/hashicorp/terraform/helper/schema"
+)
+
+func resourceCloudStackDiskOffering() *schema.Resource {
+	return &schema.Resource{
+		Create: resourceCloudStackDiskOfferingCreate,
+		Read:   resourceCloudStackDiskOfferingRead,
+		Update: resourceCloudStackDiskOfferingUpdate,
+		Delete: resourceCloudStackDiskOfferingDelete,
+		Schema: map[string]*schema.Schema{
+			"name": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"display_text": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"disk_size": {
+				Type:     schema.TypeInt,
+				Required: true,
+			},
+		},
+	}
+}
+
+func resourceCloudStackDiskOfferingCreate(d *schema.ResourceData, meta interface{}) error {
+	cs := meta.(*cloudstack.CloudStackClient)
+	name := d.Get("name").(string)
+	display_text := d.Get("display_text").(string)
+	disk_size := d.Get("disk_size").(int)
+
+	// Create a new parameter struct
+	p := cs.DiskOffering.NewCreateDiskOfferingParams(name, display_text)
+	p.SetDisksize(int64(disk_size))
+
+	log.Printf("[DEBUG] Creating Disk Offering %s", name)
+	diskOff, err := cs.DiskOffering.CreateDiskOffering(p)
+
+	if err != nil {
+		return err
+	}
+
+	log.Printf("[DEBUG] Disk Offering %s successfully created", name)
+	d.SetId(diskOff.Id)
+
+	return resourceCloudStackDiskOfferingRead(d, meta)
+}
+
+func resourceCloudStackDiskOfferingRead(d *schema.ResourceData, meta interface{}) error { return nil }
+
+func resourceCloudStackDiskOfferingUpdate(d *schema.ResourceData, meta interface{}) error { return nil }
+
+func resourceCloudStackDiskOfferingDelete(d *schema.ResourceData, meta interface{}) error { return nil }
diff --git a/cloudstack/resource_cloudstack_domain.go b/cloudstack/resource_cloudstack_domain.go
new file mode 100644
index 0000000..4123a6e
--- /dev/null
+++ b/cloudstack/resource_cloudstack_domain.go
@@ -0,0 +1,108 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package cloudstack
+
+import (
+	"fmt"
+	"log"
+
+	"github.com/apache/cloudstack-go/v2/cloudstack"
+	"github.com/hashicorp/terraform/helper/schema"
+)
+
+func resourceCloudStackDomain() *schema.Resource {
+	return &schema.Resource{
+		Read:   resourceCloudStackDomainRead,
+		Update: resourceCloudStackDomainUpdate,
+		Create: resourceCloudStackDomainCreate,
+		Delete: resourceCloudStackDomainDelete,
+		Schema: map[string]*schema.Schema{
+			"name": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"domain_id": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
+			"network_domain": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
+			"parent_domain_id": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
+		},
+	}
+}
+
+func resourceCloudStackDomainCreate(d *schema.ResourceData, meta interface{}) error {
+	cs := meta.(*cloudstack.CloudStackClient)
+	name := d.Get("name").(string)
+	domain_id := d.Get("domain_id").(string)
+	network_domain := d.Get("network_domain").(string)
+	parent_domain_id := d.Get("parent_domain_id").(string)
+
+	// Create a new parameter struct
+	p := cs.Domain.NewCreateDomainParams(name)
+
+	if domain_id != "" {
+		p.SetDomainid(domain_id)
+	}
+
+	if network_domain != "" {
+		p.SetNetworkdomain(network_domain)
+	}
+
+	if parent_domain_id != "" {
+		p.SetParentdomainid(parent_domain_id)
+	}
+
+	log.Printf("[DEBUG] Creating Domain %s", name)
+	domain, err := cs.Domain.CreateDomain(p)
+
+	if err != nil {
+		return err
+	}
+
+	log.Printf("[DEBUG] Domain %s successfully created", name)
+	d.SetId(domain.Id)
+
+	return resourceCloudStackDomainRead(d, meta)
+}
+
+func resourceCloudStackDomainRead(d *schema.ResourceData, meta interface{}) error { return nil }
+
+func resourceCloudStackDomainUpdate(d *schema.ResourceData, meta interface{}) error { return nil }
+
+func resourceCloudStackDomainDelete(d *schema.ResourceData, meta interface{}) error {
+	cs := meta.(*cloudstack.CloudStackClient)
+
+	// Create a new parameter struct
+	p := cs.Domain.NewDeleteDomainParams(d.Id())
+	_, err := cs.Domain.DeleteDomain(p)
+
+	if err != nil {
+		return fmt.Errorf("Error deleting Domain: %s", err)
+	}
+
+	return nil
+}
diff --git a/cloudstack/resource_cloudstack_network_offering.go b/cloudstack/resource_cloudstack_network_offering.go
new file mode 100644
index 0000000..e11ece2
--- /dev/null
+++ b/cloudstack/resource_cloudstack_network_offering.go
@@ -0,0 +1,214 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package cloudstack
+
+import (
+	"fmt"
+	"log"
+
+	"github.com/apache/cloudstack-go/v2/cloudstack"
+	"github.com/hashicorp/terraform/helper/schema"
+)
+
+func resourceCloudStackNetworkOffering() *schema.Resource {
+	return &schema.Resource{
+		Create: resourceCloudStackNetworkOfferingCreate,
+		Read:   resourceCloudStackNetworkOfferingRead,
+		Update: resourceCloudStackNetworkOfferingUpdate,
+		Delete: resourceCloudStackNetworkOfferingDelete,
+		Schema: map[string]*schema.Schema{
+			"name": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"display_text": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"guest_ip_type": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"traffic_type": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+		},
+	}
+}
+
+func resourceCloudStackNetworkOfferingCreate(d *schema.ResourceData, meta interface{}) error {
+	cs := meta.(*cloudstack.CloudStackClient)
+	name := d.Get("name").(string)
+	display_text := d.Get("display_text").(string)
+	guest_ip_type := d.Get("guest_ip_type").(string)
+	traffic_type := d.Get("traffic_type").(string)
+
+	// Create a new parameter struct
+	p := cs.NetworkOffering.NewCreateNetworkOfferingParams(display_text, guest_ip_type, name, []string{}, traffic_type)
+
+	if guest_ip_type == "Shared" {
+		p.SetSpecifyvlan(true)
+		p.SetSpecifyipranges(true)
+	}
+
+	log.Printf("[DEBUG] Creating Network Offering %s", name)
+	n, err := cs.NetworkOffering.CreateNetworkOffering(p)
+
+	if err != nil {
+		return err
+	}
+
+	log.Printf("[DEBUG] Network Offering %s successfully created", name)
+	d.SetId(n.Id)
+
+	return resourceCloudStackNetworkOfferingRead(d, meta)
+}
+
+func resourceCloudStackNetworkOfferingUpdate(d *schema.ResourceData, meta interface{}) error {
+	cs := meta.(*cloudstack.CloudStackClient)
+	d.Partial(true)
+
+	name := d.Get("name").(string)
+
+	// Check if the name is changed and if so, update the network offering
+	if d.HasChange("name") {
+		log.Printf("[DEBUG] Name changed for %s, starting update", name)
+
+		// Create a new parameter struct
+		p := cs.NetworkOffering.NewUpdateNetworkOfferingParams()
+
+		// Set the new name
+		p.SetName(d.Get("name").(string))
+
+		// Update the name
+		_, err := cs.NetworkOffering.UpdateNetworkOffering(p)
+		if err != nil {
+			return fmt.Errorf(
+				"Error updating the name for network offering %s: %s", name, err)
+		}
+
+		d.SetPartial("name")
+	}
+
+	// Check if the display text is changed and if so, update the virtual machine
+	if d.HasChange("display_text") {
+		log.Printf("[DEBUG] Display text changed for %s, starting update", name)
+
+		// Create a new parameter struct
+		p := cs.NetworkOffering.NewUpdateNetworkOfferingParams()
+
+		// Set the new display text
+		p.SetName(d.Get("display_text").(string))
+
+		// Update the display text
+		_, err := cs.NetworkOffering.UpdateNetworkOffering(p)
+		if err != nil {
+			return fmt.Errorf(
+				"Error updating the display text for network offering %s: %s", name, err)
+		}
+
+		d.SetPartial("display_text")
+	}
+
+	// Check if the guest ip type is changed and if so, update the virtual machine
+	if d.HasChange("guest_ip_type") {
+		log.Printf("[DEBUG] Guest ip type changed for %s, starting update", name)
+
+		// Create a new parameter struct
+		p := cs.NetworkOffering.NewUpdateNetworkOfferingParams()
+
+		// Set the new uest ip type
+		p.SetName(d.Get("guest_ip_type").(string))
+
+		// Update the uest ip type
+		_, err := cs.NetworkOffering.UpdateNetworkOffering(p)
+		if err != nil {
+			return fmt.Errorf(
+				"Error updating the guest ip type for network offering %s: %s", name, err)
+		}
+
+		d.SetPartial("guest_ip_type")
+	}
+
+	// Check if the traffic type is changed and if so, update the virtual machine
+	if d.HasChange("traffic_type") {
+		log.Printf("[DEBUG] Traffic type changed for %s, starting update", name)
+
+		// Create a new parameter struct
+		p := cs.NetworkOffering.NewUpdateNetworkOfferingParams()
+
+		// Set the new traffic type
+		p.SetName(d.Get("traffic_type").(string))
+
+		// Update the traffic type
+		_, err := cs.NetworkOffering.UpdateNetworkOffering(p)
+		if err != nil {
+			return fmt.Errorf(
+				"Error updating the traffic type for network offering %s: %s", name, err)
+		}
+
+		d.SetPartial("traffic_type")
+	}
+
+	d.Partial(false)
+
+	return resourceCloudStackInstanceRead(d, meta)
+}
+
+func resourceCloudStackNetworkOfferingDelete(d *schema.ResourceData, meta interface{}) error {
+	cs := meta.(*cloudstack.CloudStackClient)
+
+	// Create a new parameter struct
+	p := cs.NetworkOffering.NewDeleteNetworkOfferingParams(d.Id())
+	_, err := cs.NetworkOffering.DeleteNetworkOffering(p)
+
+	if err != nil {
+		return fmt.Errorf("Error deleting Network Offering: %s", err)
+	}
+
+	return nil
+}
+
+func resourceCloudStackNetworkOfferingRead(d *schema.ResourceData, meta interface{}) error {
+	cs := meta.(*cloudstack.CloudStackClient)
+	log.Printf("[DEBUG] Retrieving Network Offering %s", d.Get("name").(string))
+
+	// Get the Network Offering details
+	n, count, err := cs.NetworkOffering.GetNetworkOfferingByName(d.Get("name").(string))
+
+	if err != nil {
+		if count == 0 {
+			log.Printf("[DEBUG] Network Offering %s does no longer exist", d.Get("name").(string))
+			d.SetId("")
+			return nil
+		}
+
+		return err
+	}
+
+	d.SetId(n.Id)
+	d.Set("name", n.Name)
+	d.Set("display_text", n.Displaytext)
+	d.Set("guest_ip_type", n.Guestiptype)
+	d.Set("traffic_type", n.Traffictype)
+
+	return nil
+}
diff --git a/cloudstack/resource_cloudstack_service_offering.go b/cloudstack/resource_cloudstack_service_offering.go
new file mode 100644
index 0000000..ad887b1
--- /dev/null
+++ b/cloudstack/resource_cloudstack_service_offering.go
@@ -0,0 +1,156 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package cloudstack
+
+import (
+	"fmt"
+	"log"
+
+	"github.com/apache/cloudstack-go/v2/cloudstack"
+	"github.com/hashicorp/terraform/helper/schema"
+)
+
+func resourceCloudStackServiceOffering() *schema.Resource {
+	return &schema.Resource{
+		Create: resourceCloudStackServiceOfferingCreate,
+		Read:   resourceCloudStackServiceOfferingRead,
+		Update: resourceCloudStackServiceOfferingUpdate,
+		Delete: resourceCloudStackServiceOfferingDelete,
+		Schema: map[string]*schema.Schema{
+			"name": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"display_text": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+		},
+	}
+}
+
+func resourceCloudStackServiceOfferingCreate(d *schema.ResourceData, meta interface{}) error {
+	cs := meta.(*cloudstack.CloudStackClient)
+	name := d.Get("name").(string)
+	display_text := d.Get("display_text").(string)
+
+	// Create a new parameter struct
+	p := cs.ServiceOffering.NewCreateServiceOfferingParams(display_text, name)
+
+	log.Printf("[DEBUG] Creating Service Offering %s", name)
+	s, err := cs.ServiceOffering.CreateServiceOffering(p)
+
+	if err != nil {
+		return err
+	}
+
+	log.Printf("[DEBUG] Service Offering %s successfully created", name)
+	d.SetId(s.Id)
+
+	return resourceCloudStackServiceOfferingRead(d, meta)
+}
+
+func resourceCloudStackServiceOfferingRead(d *schema.ResourceData, meta interface{}) error {
+	cs := meta.(*cloudstack.CloudStackClient)
+	log.Printf("[DEBUG] Retrieving Service Offering %s", d.Get("name").(string))
+
+	// Get the Service Offering details
+	s, count, err := cs.ServiceOffering.GetServiceOfferingByName(d.Get("name").(string))
+
+	if err != nil {
+		if count == 0 {
+			log.Printf("[DEBUG] Service Offering %s does no longer exist", d.Get("name").(string))
+			d.SetId("")
+			return nil
+		}
+		return err
+	}
+
+	d.SetId(s.Id)
+	d.Set("name", s.Name)
+	d.Set("display_text", s.Displaytext)
+
+	return nil
+}
+
+func resourceCloudStackServiceOfferingUpdate(d *schema.ResourceData, meta interface{}) error {
+	cs := meta.(*cloudstack.CloudStackClient)
+	d.Partial(true)
+
+	name := d.Get("name").(string)
+
+	// Check if the name is changed and if so, update the service offering
+	if d.HasChange("name") {
+		log.Printf("[DEBUG] Name changed for %s, starting update", name)
+
+		// Create a new parameter struct
+		p := cs.ServiceOffering.NewUpdateServiceOfferingParams(d.Id())
+
+		// Set the new name
+		p.SetName(d.Get("name").(string))
+
+		// Update the name
+		_, err := cs.ServiceOffering.UpdateServiceOffering(p)
+		if err != nil {
+			return fmt.Errorf(
+				"Error updating the name for service offering %s: %s", name, err)
+		}
+
+		d.SetPartial("name")
+	}
+
+	// Check if the display text is changed and if so, update seervice offering
+	if d.HasChange("display_text") {
+		log.Printf("[DEBUG] Display text changed for %s, starting update", name)
+
+		// Create a new parameter struct
+		p := cs.ServiceOffering.NewUpdateServiceOfferingParams(d.Id())
+
+		// Set the new display text
+		p.SetName(d.Get("display_text").(string))
+
+		// Update the display text
+		_, err := cs.ServiceOffering.UpdateServiceOffering(p)
+		if err != nil {
+			return fmt.Errorf(
+				"Error updating the display text for service offering %s: %s", name, err)
+		}
+
+		d.SetPartial("display_text")
+	}
+
+	d.Partial(false)
+
+	return resourceCloudStackServiceOfferingRead(d, meta)
+}
+
+func resourceCloudStackServiceOfferingDelete(d *schema.ResourceData, meta interface{}) error {
+	cs := meta.(*cloudstack.CloudStackClient)
+
+	// Create a new parameter struct
+	p := cs.ServiceOffering.NewDeleteServiceOfferingParams(d.Id())
+	_, err := cs.ServiceOffering.DeleteServiceOffering(p)
+
+	if err != nil {
+		return fmt.Errorf("Error deleting Service Offering: %s", err)
+	}
+
+	return nil
+}
diff --git a/cloudstack/resource_cloudstack_user.go b/cloudstack/resource_cloudstack_user.go
new file mode 100644
index 0000000..aabb7b2
--- /dev/null
+++ b/cloudstack/resource_cloudstack_user.go
@@ -0,0 +1,110 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package cloudstack
+
+import (
+	"fmt"
+	"log"
+
+	"github.com/apache/cloudstack-go/v2/cloudstack"
+	"github.com/hashicorp/terraform/helper/schema"
+)
+
+func resourceCloudStackUser() *schema.Resource {
+	return &schema.Resource{
+		Create: resourceCloudStackUserCreate,
+		Read:   resourceCloudStackUserRead,
+		Update: resourceCloudStackUserUpdate,
+		Delete: resourceCloudStackUserDelete,
+		Schema: map[string]*schema.Schema{
+			"account": {
+				Type:     schema.TypeString,
+				Optional: true,
+			},
+			"email": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"first_name": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"last_name": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"password": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"username": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+		},
+	}
+}
+
+func resourceCloudStackUserCreate(d *schema.ResourceData, meta interface{}) error {
+	cs := meta.(*cloudstack.CloudStackClient)
+	account := d.Get("account").(string)
+	email := d.Get("email").(string)
+	first_name := d.Get("first_name").(string)
+	last_name := d.Get("last_name").(string)
+	password := d.Get("password").(string)
+	username := d.Get("username").(string)
+
+	// Create a new parameter struct
+	p := cs.User.NewCreateUserParams(account, email, first_name, last_name, password, username)
+
+	log.Printf("[DEBUG] Creating User %s", username)
+	u, err := cs.User.CreateUser(p)
+
+	if err != nil {
+		return err
+	}
+
+	log.Printf("[DEBUG] User %s successfully created", username)
+	d.SetId(u.Id)
+
+	return resourceCloudStackUserRead(d, meta)
+}
+
+func resourceCloudStackUserUpdate(d *schema.ResourceData, meta interface{}) error {
+	return resourceCloudStackUserRead(d, meta)
+}
+
+func resourceCloudStackUserDelete(d *schema.ResourceData, meta interface{}) error {
+	cs := meta.(*cloudstack.CloudStackClient)
+
+	// Create a new parameter struct
+	p := cs.User.NewDeleteUserParams(d.Id())
+	_, err := cs.User.DeleteUser(p)
+
+	if err != nil {
+		return fmt.Errorf("Error deleting User: %s", err)
+	}
+
+	return nil
+}
+
+func resourceCloudStackUserRead(d *schema.ResourceData, meta interface{}) error {
+	return nil
+}
diff --git a/cloudstack/resource_cloudstack_volume.go b/cloudstack/resource_cloudstack_volume.go
new file mode 100644
index 0000000..a2fb725
--- /dev/null
+++ b/cloudstack/resource_cloudstack_volume.go
@@ -0,0 +1,115 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package cloudstack
+
+import (
+	"fmt"
+	"log"
+
+	"github.com/apache/cloudstack-go/v2/cloudstack"
+	"github.com/hashicorp/terraform/helper/schema"
+)
+
+func resourceCloudStackVolume() *schema.Resource {
+	return &schema.Resource{
+		Create: resourceCloudStackVolumeCreate,
+		Read:   resourceCloudStackVolumeRead,
+		Delete: resourceCloudStackVolumeDelete,
+		Schema: map[string]*schema.Schema{
+			"name": {
+				Type:     schema.TypeString,
+				Required: true,
+				ForceNew: true,
+			},
+			"disk_offering_id": {
+				Type:     schema.TypeString,
+				Required: true,
+				ForceNew: true,
+			},
+			"zone_id": {
+				Type:     schema.TypeString,
+				Required: true,
+				ForceNew: true,
+			},
+		},
+	}
+}
+
+func resourceCloudStackVolumeCreate(d *schema.ResourceData, meta interface{}) error {
+	cs := meta.(*cloudstack.CloudStackClient)
+	name := d.Get("name").(string)
+	disk_offering_id := d.Get("disk_offering_id").(string)
+	zone_id := d.Get("zone_id").(string)
+
+	//Create a new parameter struct
+	p := cs.Volume.NewCreateVolumeParams()
+	p.SetDiskofferingid(disk_offering_id)
+	p.SetZoneid(zone_id)
+	p.SetName(name)
+
+	log.Printf("[DEBUG] Creating Volume %s", name)
+	v, err := cs.Volume.CreateVolume(p)
+
+	if err != nil {
+		return err
+	}
+
+	log.Printf("[DEBUG] Volume %s successfully created", name)
+	d.SetId(v.Id)
+
+	return resourceCloudStackVolumeRead(d, meta)
+}
+func resourceCloudStackVolumeRead(d *schema.ResourceData, meta interface{}) error {
+	cs := meta.(*cloudstack.CloudStackClient)
+	log.Printf("[DEBUG] Retrieving Volume %s", d.Get("name").(string))
+
+	// Get the Volume details
+	v, count, err := cs.Volume.GetVolumeByName(d.Get("name").(string))
+
+	if err != nil {
+		if count == 0 {
+			log.Printf("[DEBUG] Volume %s does no longer exist", d.Get("name").(string))
+			d.SetId("")
+			return nil
+		}
+		return err
+	}
+
+	d.SetId(v.Id)
+	d.Set("name", v.Name)
+	d.Set("disk_offering_id", v.Diskofferingid)
+	d.Set("zone_id", v.Zoneid)
+
+	return nil
+}
+
+func resourceCloudStackVolumeDelete(d *schema.ResourceData, meta interface{}) error {
+	cs := meta.(*cloudstack.CloudStackClient)
+
+	// Create a new parameter struct
+	p := cs.Volume.NewDeleteVolumeParams(d.Id())
+	_, err := cs.Volume.DeleteVolume(p)
+
+	if err != nil {
+		return fmt.Errorf("Error deleting Volume: %s", err)
+	}
+
+	return nil
+}
diff --git a/cloudstack/resource_cloudstack_zone.go b/cloudstack/resource_cloudstack_zone.go
new file mode 100644
index 0000000..a259f65
--- /dev/null
+++ b/cloudstack/resource_cloudstack_zone.go
@@ -0,0 +1,119 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package cloudstack
+
+import (
+	"fmt"
+	"log"
+
+	"github.com/apache/cloudstack-go/v2/cloudstack"
+	"github.com/hashicorp/terraform/helper/schema"
+)
+
+func resourceCloudStackZone() *schema.Resource {
+	return &schema.Resource{
+		Create: resourceCloudStackZoneCreate,
+		Read:   resourceCloudStackZoneRead,
+		Update: resourceCloudStackZoneUpdate,
+		Delete: resourceCloudStackZoneDelete,
+		Schema: map[string]*schema.Schema{
+			"name": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"dns1": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"internal_dns1": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+			"network_type": {
+				Type:     schema.TypeString,
+				Required: true,
+			},
+		},
+	}
+}
+
+func resourceCloudStackZoneCreate(d *schema.ResourceData, meta interface{}) error {
+	cs := meta.(*cloudstack.CloudStackClient)
+	name := d.Get("name").(string)
+	dns1 := d.Get("dns1").(string)
+	internal_dns1 := d.Get("internal_dns1").(string)
+	network_type := d.Get("network_type").(string)
+
+	// Create a new parameter struct
+	p := cs.Zone.NewCreateZoneParams(dns1, internal_dns1, name, network_type)
+
+	log.Printf("[DEBUG] Creating Zone %s", name)
+	n, err := cs.Zone.CreateZone(p)
+
+	if err != nil {
+		return err
+	}
+
+	log.Printf("[DEBUG] Zone %s successfully created", name)
+	d.SetId(n.Id)
+
+	return resourceCloudStackZoneRead(d, meta)
+}
+
+func resourceCloudStackZoneRead(d *schema.ResourceData, meta interface{}) error {
+	cs := meta.(*cloudstack.CloudStackClient)
+	log.Printf("[DEBUG] Retrieving Zone %s", d.Get("name").(string))
+
+	// Get the Zone details
+	z, count, err := cs.Zone.GetZoneByName(d.Get("name").(string))
+
+	if err != nil {
+		if count == 0 {
+			log.Printf("[DEBUG] Zone %s does no longer exist", d.Get("name").(string))
+			d.SetId("")
+			return nil
+		}
+		return err
+	}
+
+	d.SetId(z.Id)
+	d.Set("name", z.Name)
+	d.Set("dns1", z.Dns1)
+	d.Set("internal_dns1", z.Internaldns1)
+	d.Set("network_type", z.Networktype)
+
+	return nil
+}
+
+func resourceCloudStackZoneUpdate(d *schema.ResourceData, meta interface{}) error { return nil }
+
+func resourceCloudStackZoneDelete(d *schema.ResourceData, meta interface{}) error {
+	cs := meta.(*cloudstack.CloudStackClient)
+
+	// Create a new parameter struct
+	p := cs.Zone.NewDeleteZoneParams(d.Id())
+	_, err := cs.Zone.DeleteZone(p)
+
+	if err != nil {
+		return fmt.Errorf("Error deleting Zone: %s", err)
+	}
+
+	return nil
+}