docker-compose/rancher-compose marked as dirty
Terraform Version
$ terraform -v
Terraform v0.10.4
Using terraform-provider-rancher_v0.2.0_x4
Affected Resource(s)
rancher_stack
Repro
My docker-compose file:
1│version: '2'
2│services:
3│ docker-registry:
4│ image: registry:2
5│ labels:
6│ traefik.enable: true
7│ traefik.port: 5000
8│ volumes:
9│ - docker-registry-data:/var/lib/registry
10│
11│volumes:
12│ docker-registry-data:
13│ driver: rancher-nfs
14│ external: true
Terraform thinks the server docker-compose is:
1│version: '2'
2│volumes:
3│ docker-registry-data:
4│ external: true
5│ driver: rancher-nfs
6│services:
7│ docker-registry:
8│ image: registry:2
9│ volumes:
10│ - docker-registry-data:/var/lib/registry
11│ labels:
12│ traefik.port: '5000'
13│ traefik.enable: 'true'
Expected Behaviour
After applying the resource, I would expect it not to be marked as dirty
Actual Behaviour
Resource is marked as dirty so Terraform wants to push a modification
Steps to Reproduce
terraform applyterraform plan
This is because you have to quote the numbers and booleans in your yaml file. I suppose that the yaml format has some automatic value typing and you have to cast numbers and booleans into strings for libcompose.
It's a bit more than that it turns out. You have to quote the numbers and booleans except in the top-level volumes block.
Well in a way that makes sense.
The boolean under the volumes key is really mapped to a boolean in the volume driver I guess, whereas boolean under the labels and env keys are strings.
I don't know what to do with this issue. Is it really one? Should we transparently cast booleans and integers to strings in the source yaml bedore passing it to libcompose to compare with what exists on Rancher?
@raphink an opinion?
Same happens with command where it gets converted into a list on the rancher backend.
Another bit of weirdness is that if you create a stack with an external volume called A, then remove it at a later time, the volume stays in the rancher docker-compose.yml forever. That seems like a rancher bug though (could be wrong).
It's really confusing seeing that it always has changes that need applying even when it doesn't. It also makes using scripts hard as you have to know about this weirdness.
So, to summarise what I've found so far:
- Values in the
labelsmap must be entered as strings nullvalues in the rancher-compose.yml must be removedcommandshould be a list, not a string- Entries like
privilegedmust still be booleans - (Unrelated) Creating an external volume and then deleting it never removes it from the server's docker-compose.yml
One more thing I just found; When you have a port mapping, "110:110" needs to be 110:110/tcp
We are already using libcompose to normalize the files before comparing them, so I don't see what else can be reasonably done to avoid these differences…
libcompose only deals with plain compose files. I think this provider would have to mutate the input compose file the same way that rancher does it.
We should try and find the lib that Rancher uses for that. @cloudnautique any idea?