Skip to content

Commit

Permalink
Merge pull request #169 from YuWang24/INS-18257-PrivateLink-provision…
Browse files Browse the repository at this point in the history
…ing-support-from-terraform-provider

Ins 18257 privatelink provisioning support from terraform provider
  • Loading branch information
admintfprovider authored May 24, 2022
2 parents 9718351 + 50bbb0a commit e2ec6ce
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 19 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ BIN_NAME=terraform-provider-instaclustr
# for VERSION, don't add prefix "v", e.g., use "1.9.8" instead of "v1.9.8" as it could break circleCI stuff


VERSION=1.22.1
VERSION=1.23.0

INSTALL_FOLDER=$(HOME)/.terraform.d/plugins/terraform.instaclustr.com/instaclustr/instaclustr/$(VERSION)/darwin_amd64

Expand Down
39 changes: 39 additions & 0 deletions acc_test/data/valid_pivatelink_kafka_cluster_create.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
provider "instaclustr" {
username = "%s"
api_key = "%s"
api_hostname = "%s"
}

resource "instaclustr_cluster" "validPrivateLinkKafka" {
cluster_name = "example_kafka_privatelink"
node_size = "KFK-PRD-r6g.large-250"
data_centre = "US_WEST_2"
sla_tier = "NON_PRODUCTION"
private_network_cluster = true
cluster_network = "192.168.0.0/18"
wait_for_state = "RUNNING"
cluster_provider = {
name = "AWS_VPC"
}
rack_allocation = {
number_of_racks = 3
nodes_per_rack = 1
}

bundle {
bundle = "KAFKA"
version = "3.0.0"
options = {
auto_create_topics = true
client_encryption = false
delete_topics = true
number_partitions = 3
advertised_host_name = "kafka.test.com"
zookeeper_node_count = 3
}
}

private_link {
iam_principal_arns = ["arn:aws:iam::123456789012:root"]
}
}
26 changes: 26 additions & 0 deletions acc_test/resource_cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,32 @@ func TestValidApacheZookeeperClusterCreate(t *testing.T) {
})
}

func TestValidPrivateLinkKafkaClusterCreate(t *testing.T) {
testAccProvider := instaclustr.Provider()
testAccProviders := map[string]terraform.ResourceProvider{
"instaclustr": testAccProvider,
}
validConfig, _ := ioutil.ReadFile("data/valid_pivatelink_kafka_cluster_create.tf")
username := os.Getenv("IC_USERNAME")
apiKey := os.Getenv("IC_API_KEY")
hostname := getOptionalEnv("IC_API_URL", instaclustr.DefaultApiHostname)
oriConfig := fmt.Sprintf(string(validConfig), username, apiKey, hostname)
resource.ParallelTest(t, resource.TestCase{
Providers: testAccProviders,
CheckDestroy: testCheckResourceDeleted("validPrivateLinkKafka", hostname, username, apiKey),
Steps: []resource.TestStep{
{
Config: oriConfig,
Check: resource.ComposeTestCheckFunc(
testCheckResourceValid("validPrivateLinkKafka"),
testCheckResourceCreated("validPrivateLinkKafka", hostname, username, apiKey),
checkClusterRunning("validPrivateLinkKafka", hostname, username, apiKey),
),
},
},
})
}

func TestAccClusterCredentials(t *testing.T) {
testAccProviders := map[string]terraform.ResourceProvider{
"instaclustr": instaclustr.Provider(),
Expand Down
7 changes: 7 additions & 0 deletions docs/resources/cluster.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ A resource for managing clusters on Instaclustr Managed Platform. A cluster cont
| `oidc_provider` | The ID of an OIDC provider to be used for Elasticsearch Kibana or OpenSearch Dashboards. OIDC providers must be set in Console Cluster Resources to be available for use. | Optional |
| `cluster_id` | Returns the Cluster ID as a UUID | READ ONLY |
| `default_data_centre_id` | Returned the default Data Centre ID as a UUID | READ ONLY |
| `private_link` | Creates a PrivateLink cluster, see [here](https://www.instaclustr.com/support/documentation/useful-information/privatelink/) for more details. PrivateLink can only be supported on AWS_VPC for Kafka currently. See below for its properties. | Optional, but Required for creating a PrivateLink cluster.

### cluster_provider

Expand All @@ -48,6 +49,12 @@ A resource for managing clusters on Instaclustr Managed Platform. A cluster cont
| `number_of_racks` | Number of racks to use when allocating nodes. Max allowed is 5 | Required |
| `nodes_per_rack` | Number of nodes per rack. Max allowed is 10 | Required |

`private_link`

| Property | Description | Default |
|----------------------|----------------------------------------------------------------|----------|
| `iam_principal_arns` | List of IAM Principal ARNs to add to the endpoint service | Required |

`bundle`

| Property | Description | Default |
Expand Down
45 changes: 45 additions & 0 deletions instaclustr/resource_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,24 @@ func resourceCluster() *schema.Resource {
ForceNew: true,
},

"private_link": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"iam_principal_arns": {
Type: schema.TypeList,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Optional: true,
ForceNew: true,
},
},
},
},

"bundles": {
Type: schema.TypeSet,
Optional: true,
Expand Down Expand Up @@ -631,6 +649,11 @@ func resourceCluster() *schema.Resource {
Optional: true,
ForceNew: true,
},
"advertised_host_name": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
},
},
},
Expand Down Expand Up @@ -797,6 +820,7 @@ func resourceClusterCreate(d *schema.ResourceData, meta interface{}) error {
if err != nil {
return err
}

var createData = CreateRequest{
ClusterName: d.Get("cluster_name").(string),
Bundles: bundles,
Expand All @@ -808,6 +832,16 @@ func resourceClusterCreate(d *schema.ResourceData, meta interface{}) error {
OidcProvider: fmt.Sprintf("%v", d.Get("oidc_provider")),
}

var privateLinkConfig PrivateLinkConfig
if len(d.Get("private_link").([]interface{})) > 0 && d.Get("private_link").([]interface{})[0] != nil {
privateLink := d.Get("private_link").([]interface{})[0].(map[string]interface{})
err := mapstructure.Decode(privateLink, &privateLinkConfig)
if err != nil {
return fmt.Errorf("[Error] Error decoding the privateLink config to PrivateLinkConfig: %w", err)
}
createData.PrivateLink = &privateLinkConfig
}

dataCentre := d.Get("data_centre").(string)
dataCentres, err := getDataCentres(d)
if err != nil {
Expand Down Expand Up @@ -1434,6 +1468,17 @@ func resourceClusterRead(d *schema.ResourceData, meta interface{}) error {
d.Set("cluster_network", cluster.DataCentres[0].CdcNetwork)
d.Set("data_centre_custom_name", cluster.DataCentres[0].CdcName)

privateLink := make(map[string]interface{}, 0)
privateLinkConfigList := make([]map[string]interface{}, 0)
err = mapstructure.Decode(cluster.DataCentres[0].PrivateLink, &privateLink)
if err != nil {
return fmt.Errorf("[Error] Error decoding the privateLink config to a map: %w", err)
}
if len(privateLink) > 0 && privateLink["iam_principal_arns"] != nil {
privateLinkConfigList = append(privateLinkConfigList, privateLink)
}
d.Set("private_link", privateLinkConfigList)

if err := deleteAttributesConflict(resourceCluster().Schema, d, "data_centre"); err != nil {
return err
}
Expand Down
43 changes: 25 additions & 18 deletions instaclustr/structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ type BundleOptions struct {
CadenceTargetOpensearchVPCType string `json:"targetOpenSearchVpcType,omitempty" mapstructure:"target_opensearch_vpc_type,omitempty"`
CadenceTargetKafkaDataCentreID string `json:"targetKafkaCdcId,omitempty" mapstructure:"target_kafka_data_centre_id,omitempty"`
CadenceTargetKafkaVPCType string `json:"targetKafkaVpcType,omitempty" mapstructure:"target_kafka_vpc_type,omitempty"`
AdvertisedHostName string `json:"advertisedHostName,omitempty" mapstructure:"advertised_host_name,omitempty"`
}

type ClusterProvider struct {
Expand Down Expand Up @@ -100,6 +101,11 @@ type CreateRequest struct {
PCICompliantCluster string `json:"pciCompliantCluster,omitempty"`
RackAllocation *RackAllocation `json:"rackAllocation,omitempty"`
OidcProvider string `json:"oidcProvider,omitempty"`
PrivateLink *PrivateLinkConfig `json:"privateLink,omitempty" mapstructure:"private_link,omitempty"`
}

type PrivateLinkConfig struct {
IAMPrincipalARNs *[]string `json:"iamPrincipalARNs,omitempty" mapstructure:"iam_principal_arns,omitempty"`
}

type DataCentreCreateRequest struct {
Expand Down Expand Up @@ -149,24 +155,25 @@ type ClusterListItem struct {
}

type DataCentre struct {
ID string `json:"id,omitempty"`
Name string `json:"name" mapstructure:"name"`
CdcName string `json:"cdcName,omitempty" mapstructure:"cdcName"`
Provider string `json:"provider,omitempty"`
CdcNetwork string `json:"cdcNetwork,omitempty"`
Bundles []string `json:"bundles,omitempty"`
ClientEncryption bool `json:"clientEncryption,omitempty"`
PasswordAuthentication bool `json:"passwordAuthentication,omitempty"`
UserAuthorization bool `json:"userAuthorization,omitempty"`
UsePrivateBroadcastRPCAddress bool `json:"usePrivateBroadcastRPCAddress,omitempty"`
PrivateIPOnly bool `json:"privateIPOnly,omitempty"`
Nodes []Node `json:"nodes,omitempty"`
NodeCount int `json:"nodeCount,omitempty"`
EncryptionKeyId string `json:"encryptionKeyId,omitempty"`
ResizeTargetNodeSize string `json:"resizeTargetNodeSize,omitempty"`
DataCentreRegion string `json:"dataCentre,omitempty" mapstructure:"data_centre_region"`
CdcStatus string `json:"cdcStatus,omitempty"`
RackAllocation *RackAllocation `json:"rackAllocation,omitempty" mapstructure:"rack_allocation,omitempty"`
ID string `json:"id,omitempty"`
Name string `json:"name" mapstructure:"name"`
CdcName string `json:"cdcName,omitempty" mapstructure:"cdcName"`
Provider string `json:"provider,omitempty"`
CdcNetwork string `json:"cdcNetwork,omitempty"`
Bundles []string `json:"bundles,omitempty"`
ClientEncryption bool `json:"clientEncryption,omitempty"`
PasswordAuthentication bool `json:"passwordAuthentication,omitempty"`
UserAuthorization bool `json:"userAuthorization,omitempty"`
UsePrivateBroadcastRPCAddress bool `json:"usePrivateBroadcastRPCAddress,omitempty"`
PrivateIPOnly bool `json:"privateIPOnly,omitempty"`
Nodes []Node `json:"nodes,omitempty"`
NodeCount int `json:"nodeCount,omitempty"`
EncryptionKeyId string `json:"encryptionKeyId,omitempty"`
ResizeTargetNodeSize string `json:"resizeTargetNodeSize,omitempty"`
DataCentreRegion string `json:"dataCentre,omitempty" mapstructure:"data_centre_region"`
CdcStatus string `json:"cdcStatus,omitempty"`
RackAllocation *RackAllocation `json:"rackAllocation,omitempty" mapstructure:"rack_allocation,omitempty"`
PrivateLink *PrivateLinkConfig `json:"privateLink,omitempty" mapstructure:"private_link,omitempty"`
}

type Node struct {
Expand Down

0 comments on commit e2ec6ce

Please sign in to comment.