Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support more properties for azurerm_kubernetes_cluster #5824

Closed

Conversation

neil-yechenwei
Copy link
Contributor

@neil-yechenwei neil-yechenwei commented Feb 20, 2020

fixes #5646

Copy link
Collaborator

@katbyte katbyte left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @neil-yechenwei,

Could we get a test that sets these new properties? thanks

@neil-yechenwei
Copy link
Contributor Author

@katbyte , thanks for you comments. I added test case to support new properties.

Copy link
Collaborator

@katbyte katbyte left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding the test @neil-yechenwei, i've given this a proper review and left some comments inline.

website/docs/r/kubernetes_cluster.html.markdown Outdated Show resolved Hide resolved
"allocated_outbound_port": {
Type: schema.TypeInt,
Optional: true,
Default: -1,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the reason for -1 here? can't we just do d.GetOk() and only pass along the value if it is specified?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope. Because d.GetOk() will return "0" for TypeInt when you didn't specify "allocated_outbound_port" in tf config. Then service side would set this property as "0" but actually I don't want to set it as "0". I just want to set it as nil.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GetOk returns a int, bool, if the property isn't set i believe the boolean will be false? @neil-yechenwei

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. The boolean will be false if the property isn't set in tf config. But actually sometimes we don't want to set it as "false". We just want to set it as nil when the property isn't set in tf config.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@neil-yechenwei, does this not work:

	if port, ok := config["allocated_outbound_port"].(int); ok {
		profile.AllocatedOutboundPorts = utils.Int32(int32(port))
	}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry - poor wording there. I believe that a read-back value from the API for AllocatedOutboundPorts will contain the default value 0, not nil, so we should be fine to set Computed and let the zero value pass through? The user can not set nil explicitly, and omitting the setting should use the default since it must have a value between 0 and 64,000?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jackofallops , sorry, I don't think so. Service API would return nil when the property isn't set in tfconfig. So I think user is able to set it as nil without breaking change. If we set this property must be between 0 and 64000, then breaking change would happen. So I have a concern. When breaking change is allowed in terraform? The breaking change in here is allowed?

tfconfig without outbound_ports_allocated:

provider "azurerm" {
  features {}
}

resource "azurerm_resource_group" "test" {
  name     = "acctestRG-aks-%d"
  location = "westus2"
}

resource "azurerm_kubernetes_cluster" "test" {
  name                = "acctestaks%d"
  location            = azurerm_resource_group.test.location
  resource_group_name = azurerm_resource_group.test.name
  dns_prefix          = "acctestaks%d"
  kubernetes_version  = "%s"

  linux_profile {
    admin_username = "acctestuser%d"

    ssh_key {
      key_data = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqaZoyiz1qbdOQ8xEf6uEu1cCwYowo5FHtsBhqLoDnnp7KUTEBN+L2NxRIfQ781rxV6Iq5jSav6b2Q8z5KiseOlvKA/RF2wqU0UPYqQviQhLmW6THTpmrv/YkUCuzxDpsH7DUDhZcwySLKVVe0Qm3+5N2Ta6UYH3lsDf9R9wTP2K/+vAnflKebuypNlmocIvakFWoZda18FOmsOoIVXQ8HWFNCuw9ZCunMSN62QGamCe3dL5cXlkgHYv7ekJE15IA9aOJcM7e90oeTqo+7HTcWfdu0qQqPWY5ujyMw/llas8tsXY85LFqRnr3gJ02bAscjc477+X+j/gkpFoN1QEmt [email protected]"
    }
  }

  default_node_pool {
    name       = "default"
    node_count = 1
    vm_size    = "Standard_DS2_v2"
  }

  service_principal {
    client_id     = "%s"
    client_secret = "%s"
  }

  network_profile {
    network_plugin    = "kubenet"
    load_balancer_sku = "Standard"
    load_balancer_profile {
      managed_outbound_ip_count = 2
    }
  }
}

terraform schema:

"load_balancer_profile": {
							Type:     schema.TypeList,
							MaxItems: 1,
							ForceNew: true,
							Optional: true,
							Computed: true,
							Elem: &schema.Resource{
								Schema: map[string]*schema.Schema{
									"outbound_ports_allocated": {
										Type:         schema.TypeInt,
										Optional:     true,
										Default:      0,
										ValidateFunc: validation.IntBetween(0, 64000),
									},

The result of outbound_ports_allocated from service API:
image

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @neil-yechenwei
I meant the following for the schema:

						"load_balancer_profile": {
							Type:     schema.TypeList,
							MaxItems: 1,
							ForceNew: true,
							Optional: true,
							Computed: true,
							Elem: &schema.Resource{
								Schema: map[string]*schema.Schema{
									"outbound_ports_allocated": {
										Type:         schema.TypeInt,
										Optional:     true,
										Computed:     true,
										ValidateFunc: validation.IntBetween(0, 64000),
									},

And can I see the read comes back with a 0 from the API:
image

image

with config:

 network_profile {
    network_plugin    = "kubenet"
    load_balancer_sku = "Standard"
    load_balancer_profile {
      managed_outbound_ip_count = 2
      idle_timeout_in_minutes   = 10
    }

Does that help explain what I mean?

Copy link
Contributor Author

@neil-yechenwei neil-yechenwei Mar 21, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jackofallops , sorry, Do you mean user must set property "outbound_ports_allocated" as 0~64000 for all created services including already existing services by user? If yes, I still think your change would cause breaking change which would impact other already existing services created by user. Maybe some user doesn't expect this change impacts their already provisioned service. So I am asking does hashicorp allow breaking change for here this situation. If it's allowed, I can update this PR to force user to set this property as 0-64000.
And I've tried your above changes, you actually already set this property outbound_ports_allocated as 0 in request body before calling service API so that you would get 0 from service side. Actually service API would return nil as default when this property isn't set in request body. Please see my below example. If my understanding is incorrect, could you commit whole changes of your solution to this PR for better understanding? Thanks.

tfconfig without property outbound_ports_allocated:

provider "azurerm" {
  features {}
}

resource "azurerm_resource_group" "test" {
  name     = "acctestRG-aks-%d"
  location = "westus2"
}

resource "azurerm_kubernetes_cluster" "test" {
  name                = "acctestaks%d"
  location            = azurerm_resource_group.test.location
  resource_group_name = azurerm_resource_group.test.name
  dns_prefix          = "acctestaks%d"
  kubernetes_version  = "%s"

  linux_profile {
    admin_username = "acctestuser%d"

    ssh_key {
      key_data = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqaZoyiz1qbdOQ8xEf6uEu1cCwYowo5FHtsBhqLoDnnp7KUTEBN+L2NxRIfQ781rxV6Iq5jSav6b2Q8z5KiseOlvKA/RF2wqU0UPYqQviQhLmW6THTpmrv/YkUCuzxDpsH7DUDhZcwySLKVVe0Qm3+5N2Ta6UYH3lsDf9R9wTP2K/+vAnflKebuypNlmocIvakFWoZda18FOmsOoIVXQ8HWFNCuw9ZCunMSN62QGamCe3dL5cXlkgHYv7ekJE15IA9aOJcM7e90oeTqo+7HTcWfdu0qQqPWY5ujyMw/llas8tsXY85LFqRnr3gJ02bAscjc477+X+j/gkpFoN1QEmt [email protected]"
    }
  }

  default_node_pool {
    name       = "default"
    node_count = 1
    vm_size    = "Standard_DS2_v2"
  }

  service_principal {
    client_id     = "%s"
    client_secret = "%s"
  }

  network_profile {
    network_plugin    = "kubenet"
    load_balancer_sku = "Standard"
    load_balancer_profile {
      managed_outbound_ip_count = 2
    }
  }
}

terraform schema:

"load_balancer_profile": {
							Type:     schema.TypeList,
							MaxItems: 1,
							ForceNew: true,
							Optional: true,
							Computed: true,
							Elem: &schema.Resource{
								Schema: map[string]*schema.Schema{
									"outbound_ports_allocated": {
										Type:         schema.TypeInt,
										Optional:     true,
										Computed:     true,
										ValidateFunc: validation.IntBetween(0, 64000),
									},

Do not set property outbound_ports_allocated before calling service api:
image

Getting value of property outbound_ports_allocated from Service API:
image

So service API would return nil NOT 0 when you didn't set this property in tfconfig.

Copy link
Contributor Author

@neil-yechenwei neil-yechenwei Mar 24, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jackofallops , I've double confirmed with this service owner. They said property "AllocatedOutboundPorts" would be set to “0” and property “IdleTimeoutInMinutes” would be set to “30” in service side when we don't set these two properties in request body. So I've updated code. Please have a look. Thanks.

The answer from service owner:
Today, if a customer doesn’t set them explicitly then we don’t fill the two properties from the AKS side but they do get filled on the SLB side with the defaults.

@neil-yechenwei
Copy link
Contributor Author

@katbyte , Thanks for your comments. I've updated code.

@katbyte katbyte added this to the v2.1.0 milestone Mar 5, 2020
Copy link
Collaborator

@katbyte katbyte left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @neil-yechenwei, one last comment about use of GetOK

@neil-yechenwei
Copy link
Contributor Author

@katbyte , I've answered your concern. Please have a look.

@ghost ghost removed the waiting-response label Mar 6, 2020
"allocated_outbound_port": {
Type: schema.TypeInt,
Optional: true,
Default: -1,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@neil-yechenwei, does this not work:

	if port, ok := config["allocated_outbound_port"].(int); ok {
		profile.AllocatedOutboundPorts = utils.Int32(int32(port))
	}

@@ -273,6 +273,10 @@ A `load_balancer_profile` block supports the following:

~> **NOTE:** These options are mutually exclusive. Note that when specifying `outbound_ip_address_ids` ([azurerm_public_ip](/docs/providers/azurerm/r/public_ip.html)) the SKU must be `Standard`.

* `allocated_outbound_port` - (Optional) Count of desired allocated SNAT port per VM for the cluster load balancer. Must be between `0` and `64000` inclusive.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what this property is, an allocated port or the number of ports? count here, (and the API being ports) lead me to believe it's a count? if so we should change the name? maybe

Suggested change
* `allocated_outbound_port` - (Optional) Count of desired allocated SNAT port per VM for the cluster load balancer. Must be between `0` and `64000` inclusive.
* `outbound_ports_allocated` - (Optional) Number of desired SNAT port for each VM in the clusters load balancer. Must be between `0` and `64000` inclusive.

or maybe outbound_port_count?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated with outbound_ports_allocated

website/docs/r/kubernetes_cluster.html.markdown Outdated Show resolved Hide resolved
website/docs/r/kubernetes_cluster.html.markdown Outdated Show resolved Hide resolved
@neil-yechenwei
Copy link
Contributor Author

neil-yechenwei commented Mar 10, 2020

@katbyte , yes. below code you suggested doesn't work. Because the code "config["allocated_outbound_port"].(int)" would return "0" when tfconfig doesn't specify the property "allocated_outbound_port" and there is no "Default: -1". Then the property "profile.AllocatedOutboundPorts" would be set as "0" and pass to service side and “0” is meaningful for this property in service side. But actually I just want to set this property as "nil" when tf config doesn't specify this property. So if I use below code, I cannot distinguish user specified "0" or nil. Maybe it's a bug in terraform, right?

if port, ok := config["allocated_outbound_port"].(int); ok {
profile.AllocatedOutboundPorts = utils.Int32(int32(port))
}

@ghost ghost removed the waiting-response label Mar 10, 2020
@tombuildsstuff tombuildsstuff self-assigned this Mar 27, 2020
@evenh
Copy link
Contributor

evenh commented Mar 30, 2020

Thanks for this work @neil-yechenwei! Is there more work that remains or just reviewing?

@tombuildsstuff tombuildsstuff modified the milestones: v2.5.0, v2.6.0 Apr 8, 2020
@tombuildsstuff tombuildsstuff modified the milestones: v2.6.0, v2.7.0 Apr 16, 2020
@katbyte katbyte modified the milestones: v2.7.0, v2.8.0 Apr 23, 2020
@etiennetremel
Copy link

Thanks for putting this through @neil-yechenwei, any chance to get this merged?

@katbyte katbyte modified the milestones: v2.8.0, v2.9.0 Apr 30, 2020
@tombuildsstuff tombuildsstuff modified the milestones: v2.9.0, v2.11.0 May 7, 2020
@tombuildsstuff tombuildsstuff modified the milestones: v2.11.0, v2.12.0 May 19, 2020
@tombuildsstuff tombuildsstuff modified the milestones: v2.12.0, v2.13.0 May 27, 2020
@tombuildsstuff tombuildsstuff removed the request for review from katbyte May 27, 2020 09:29
tombuildsstuff added a commit that referenced this pull request Jun 3, 2020
Porting over the changes from #5824

X-Committed-With: neil-yechenwei
tombuildsstuff added a commit that referenced this pull request Jun 4, 2020
Porting over the changes from #5824

X-Committed-With: neil-yechenwei
@tombuildsstuff tombuildsstuff modified the milestones: v2.13.0, v2.14.0 Jun 4, 2020
tombuildsstuff added a commit that referenced this pull request Jun 5, 2020
Porting over the changes from #5824

X-Committed-With: neil-yechenwei
@tombuildsstuff
Copy link
Contributor

hey @neil-yechenwei

Thanks for this PR - apologies for the delayed review here!

Since there's a number of other Pull Requests currently open for AKS - to be able to merge all of these without them all conflicting, I've pulled these commits locally, squashed them, fix the comments and then combined them into a single branch.

As such, whilst I'd like to thank you for opening this Pull Request, I'm going to close this in favour of #7233 which integrates these changes (and the other open AKS PR's - and includes some of the other open Feature Requests).

Thanks!

tombuildsstuff added a commit that referenced this pull request Jun 8, 2020
Porting over the changes from #5824

X-Committed-With: neil-yechenwei
@ghost
Copy link

ghost commented Jun 11, 2020

This has been released in version 2.14.0 of the provider. Please see the Terraform documentation on provider versioning or reach out if you need any assistance upgrading. As an example:

provider "azurerm" {
    version = "~> 2.14.0"
}
# ... other configuration ...

@ghost
Copy link

ghost commented Jul 5, 2020

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. If you feel I made an error 🤖 🙉 , please reach out to my human friends 👉 [email protected]. Thanks!

@ghost ghost locked and limited conversation to collaborators Jul 5, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support for new managed cluster load balancer profile settings in kubernetes
7 participants