citrix / terraform-provider-citrixadc

Part of NetScaler Automation Toolkit | https://github.com/netscaler/automation-toolkit
https://registry.terraform.io/providers/citrix/citrixadc
Apache License 2.0
119 stars 59 forks source link

Can't change state of gslbservice from disabled=>enabled after initial set #53

Closed Priteshkal closed 5 years ago

Priteshkal commented 5 years ago

Hi,

I am trying to do blue-green application deployments using GSLB as my application switch between blue-green application stack.

To begin with, I have my blue stack (lb_vserver->lb_servicegroup->servers) set as a "Disabled" service making traffic going only to my green stack (lb_vserver->lb_servicegroup->servers) which is set as an "enabled" gslbservice.

Now when I want to go in and do a application switch, I am trying to use terraform to update the state of my blue stack to "enabled" but I am getting the following errors on apply:

Error: Error applying plan:

1 error(s) occurred:

* netscaler_gslbservice.blue_stack_service_1: 1 error(s) occurred:

* netscaler_gslbservice.blue_stack_service_1: Error updating gslbservice <app>-<env>-blue-stack-service-ssl-443

Terraform does not automatically rollback in the face of errors.
Instead, your Terraform state file has been partially updated with
any resources that successfully completed. Please address the error
above and apply again to incrementally change your infrastructure.

From the log file I see that:

plugin.terraform-provider-netscaler_v0.11.10: 2019/07/24 13:09:16 [DEBUG] go-nitro: response Status: 599 Netscaler specific error
2019-07-24T13:09:16.105-0500 [DEBUG] plugin.terraform-provider-netscaler_v0.11.10: 2019/07/24 13:09:16 [INFO] go-nitro: error = { "errorcode": 278, "message": "Invalid argument [state]", "severity": "ERROR" }
2019/07/24 13:09:16 [TRACE] root: eval: *terraform.EvalWriteState
2019/07/24 13:09:16 [TRACE] root: eval: *terraform.EvalApplyProvisioners
2019/07/24 13:09:16 [TRACE] root: eval: *terraform.EvalIf
2019/07/24 13:09:16 [TRACE] root: eval: *terraform.EvalWriteState
2019/07/24 13:09:16 [TRACE] root: eval: *terraform.EvalWriteDiff
2019/07/24 13:09:16 [TRACE] root: eval: *terraform.EvalApplyPost
2019/07/24 13:09:16 [ERROR] root: eval: *terraform.EvalApplyPost, err: 1 error(s) occurred:

* netscaler_gslbservice.blue_stack_service_1: Error updating gslbservice <app>-<env>-blue-stack-service-ssl-443
2019/07/24 13:09:16 [ERROR] root: eval: *terraform.EvalSequence, err: 1 error(s) occurred:

* netscaler_gslbservice.blue_stack_service_1: Error updating gslbservice <app>-<env>-blue-stack-service-ssl-443

The plan for this update shows correct updates but while applying them it fails.

tfm plan
2019-07-24 13:30:05 [INFO] Git repository is at: ****
2019-07-24 13:30:05 [INFO] Validating terraform files ...
2019-07-24 13:30:06 [INFO] Verifying configured backend ...
2019-07-24 13:30:06 [INFO] Generating plan ...
  ~ netscaler_gslbservice.blue_stack_service_1
      state:   "DISABLED" => "ENABLED"

Please let me know what you think is happening here since this service enable-disable is an integral part of our blue-green application deployment.

Thanks

chiradeep commented 5 years ago

checking with the api team on this. 'state' is a read-write property https://developer-docs.citrix.com/projects/netscaler-nitro-api/en/12.0/configuration/global-server-load-balancing/gslbvserver/gslbvserver/#properties OTOH, there is also enable/disable API available on this object.

giorgos-nikolopoulos commented 5 years ago

This is a bug in the provider.

The state attribute is relevant only when creating the resource. To change the state after creation you need to apply the disable or enable NITRO operation on the resource.

The following bash script shows how it is done.


enable_glsb_vserver () {
curl \
-H "Content-Type: application/json" \
-H "X-NITRO-USER: nsroot" \
-H "X-NITRO-PASS: nsroot" \
-d "{\"gslbvserver\": { \"name\": \"${SERVERNAME}\" }}" \
-k \
https://$NSIP/nitro/v1/config/gslbvserver?action=enable
}

disable_glsb_vserver () {
curl \
-H "Content-Type: application/json" \
-H "X-NITRO-USER: nsroot" \
-H "X-NITRO-PASS: nsroot" \
-d "{\"gslbvserver\": { \"name\": \"${SERVERNAME}\" }}" \
-k \
https://$NSIP/nitro/v1/config/gslbvserver?action=disable
}

The solution is to take into account when the state attribute of the resource is different from the actual object attribute and then apply the disable/enable operation along with any other attribute changes.

We will address this as soon as we can.

Priteshkal commented 5 years ago

Just wondering if there has been any progress on this?

giorgos-nikolopoulos commented 5 years ago

No, not at the moment.

Priteshkal commented 5 years ago

Just wondering if this work has been planned? Trying to get a timeline estimate for our sprint.

giorgos-nikolopoulos commented 5 years ago

I am currently working on this issue.

There are a lot of resources that do not do the state handling correctly at the moment and I would like to put all these changes together in a single PR.

The full PR will handle correct disable/enable operation for the following resources

My estimate is that I will have the PR ready by mid next week.

I will let you know if there are any delays.

giorgos-nikolopoulos commented 5 years ago

Pull request #56 resolves the issue of correctly handling the state attribute change after creation of the resource.

Release v0.12.2 is the first one that contains this fix.

@Priteshkal let us know if this works out for you.

Priteshkal commented 5 years ago

Thank You @giorgos-nikolopoulos! This works perfectly. Appreciate it.