diff --git a/cloudstack/provider.go b/cloudstack/provider.go index 72090147..e766d6c7 100644 --- a/cloudstack/provider.go +++ b/cloudstack/provider.go @@ -126,6 +126,7 @@ func Provider() *schema.Provider { "cloudstack_ipaddress": resourceCloudStackIPAddress(), "cloudstack_kubernetes_cluster": resourceCloudStackKubernetesCluster(), "cloudstack_kubernetes_version": resourceCloudStackKubernetesVersion(), + "cloudstack_loadbalancer": resourceCloudStackLoadBalancer(), "cloudstack_loadbalancer_rule": resourceCloudStackLoadBalancerRule(), "cloudstack_network": resourceCloudStackNetwork(), "cloudstack_network_acl": resourceCloudStackNetworkACL(), diff --git a/cloudstack/resource_cloudstack_loadbalancer.go b/cloudstack/resource_cloudstack_loadbalancer.go new file mode 100644 index 00000000..8f296702 --- /dev/null +++ b/cloudstack/resource_cloudstack_loadbalancer.go @@ -0,0 +1,182 @@ +// +// 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 ( + "github.com/apache/cloudstack-go/v2/cloudstack" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func resourceCloudStackLoadBalancer() *schema.Resource { + return &schema.Resource{ + Create: resourceCloudStackLoadBalancerCreate, + Read: resourceCloudStackLoadBalancerRead, + Delete: resourceCloudStackLoadBalancerDelete, + + Schema: map[string]*schema.Schema{ + "algorithm": { + Description: "load balancer algorithm (source, roundrobin, leastconn)", + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "instanceport": { + Description: "the TCP port of the virtual machine where the network traffic will be load balanced to", + Type: schema.TypeInt, + Required: true, + ForceNew: true, + }, + + "name": { + Description: "name of the load balancer", + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "networkid": { + Description: "The guest network the load balancer will be created for", + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "scheme": { + Description: "the load balancer scheme. Supported value in this release is Internal", + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "sourceipaddressnetworkid": { + Description: "the network id of the source ip address", + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "sourceport": { + Description: "the source port the network traffic will be load balanced from", + Type: schema.TypeInt, + Required: true, + ForceNew: true, + }, + + "description": { + Description: "the description of the load balancer", + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + + "sourceipaddress": { + Description: "the source IP address the network traffic will be load balanced from", + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + + "virtualmachineids": { + Description: "the list of IDs of the virtual machine that are being assigned to the load balancer rule(i.e. virtualMachineIds=1,2,3)", + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + } +} + +func resourceCloudStackLoadBalancerCreate(d *schema.ResourceData, meta interface{}) error { + cs := meta.(*cloudstack.CloudStackClient) + + p := cs.LoadBalancer.NewCreateLoadBalancerParams( + d.Get("algorithm").(string), + d.Get("instanceport").(int), + d.Get("name").(string), + d.Get("networkid").(string), + d.Get("scheme").(string), + d.Get("sourceipaddressnetworkid").(string), + d.Get("sourceport").(int), + ) + if v, ok := d.GetOk("description"); ok { + p.SetDescription(v.(string)) + } + if v, ok := d.GetOk("sourceipaddress"); ok { + p.SetSourceipaddress(v.(string)) + } + + r, err := cs.LoadBalancer.CreateLoadBalancer(p) + if err != nil { + return err + } + + if v, ok := d.GetOk("virtualmachineids"); ok { + vmIds := v.([]interface{}) + for _, vmId := range vmIds { + assignParams := cs.LoadBalancer.NewAssignToLoadBalancerRuleParams(r.Id) + assignParams.SetVirtualmachineids([]string{vmId.(string)}) + _, err := cs.LoadBalancer.AssignToLoadBalancerRule(assignParams) + if err != nil { + return err + } + } + } + + d.SetId(r.Id) + + return resourceCloudStackLoadBalancerRead(d, meta) +} + +func resourceCloudStackLoadBalancerRead(d *schema.ResourceData, meta interface{}) error { + cs := meta.(*cloudstack.CloudStackClient) + + r, _, err := cs.LoadBalancer.GetLoadBalancerByID(d.Id()) + if err != nil { + return err + } + + d.Set("algorithm", r.Algorithm) + d.Set("name", r.Name) + d.Set("network_id", r.Networkid) + d.Set("sourceipaddressnetworkid", r.Sourceipaddressnetworkid) + + var vmIds []string + for _, vm := range r.Loadbalancerinstance { + vmIds = append(vmIds, vm.Id) + } + d.Set("virtualmachineids", vmIds) + + return nil +} + +func resourceCloudStackLoadBalancerDelete(d *schema.ResourceData, meta interface{}) error { + cs := meta.(*cloudstack.CloudStackClient) + + _, err := cs.LoadBalancer.DeleteLoadBalancer(cs.LoadBalancer.NewDeleteLoadBalancerParams(d.Id())) + if err != nil { + return err + } + + return nil +} diff --git a/website/docs/r/loadbalancer.html.markdown b/website/docs/r/loadbalancer.html.markdown new file mode 100644 index 00000000..cbca7c49 --- /dev/null +++ b/website/docs/r/loadbalancer.html.markdown @@ -0,0 +1,62 @@ +--- +layout: "cloudstack" +page_title: "CloudStack: cloudstack_loadbalancer" +sidebar_current: "docs-cloudstack-resource-loadbalancer" +description: |- + Creates an internal load balancer. +--- + +# cloudstack_loadbalancer + +Creates an internal load balancer. + +## Example Usage + +Basic usage: + +```hcl +resource "cloudstack_loadbalancer" "example" { + algorithm = "Source" + description = "Example Load Balancer" + instanceport = "8081" + name = "internal-lb-example" + networkid = "0ae8fa84-c78e-441a-8628-917d276c7d5c" + scheme = "Internal" + sourceipaddressnetworkid = "0ae8fa84-c78e-441a-8628-917d276c7d5c" + sourceport = "8081" + virtualmachineids = [ "48600f99-d890-472c-bc1a-7379af22727c", "749485a1-4081-49cd-9668-1d160ac94488", "9bbf3c6d-c8b8-42e8-ab37-e4f60a71f61d" ] +} +``` + +## Argument Reference + +The following arguments are supported: + +* `algorithm` - (Required) load balancer algorithm (source, roundrobin, leastconn). +* `description` - (Optional) the description of the load balancer. +* `instanceport` - (Required) the TCP port of the virtual machine where the network traffic will be load balanced to. +* `name` - (Required) name of the load balancer. +* `networkid` - (Required) The guest network the load balancer will be created for. +* `scheme` - (Required) the load balancer scheme. Supported value in this release is Internal. +* `sourceipaddressnetworkid` - (Required) the network id of the source ip address. +* `sourceport` - (Required) the source port the network traffic will be load balanced from. +* `sourceipaddress` - (Optional) the source IP address the network traffic will be load balanced from. +* `virtualmachineids` - (Optional) the list of IDs of the virtual machine that are being assigned to the load balancer rule(i.e. virtualMachineIds=1,2,3). + + +## Attributes Reference + +The following attributes are exported: + +* `id` - the Load Balancer ID. + + + +## Import + +A load balancer can be imported; use `` as the import ID. For +example: + +```shell +terraform import cloudstack_loadbalancer.example eefce154-e759-45a4-989a-9a432792801b +```