Open devurandom opened 3 years ago
@devurandom Thank you for the thoughtful and thorough suggestion. We'll consider making the suggested changes.
Although there is a slight inconvenience to having two state sets, the suggested change above works good for me. Any update in interest in making the change, or receiving a pull request for one?
The pattern I'm currently learning to develop with adds a stateless module for the k8s "test" resources so I can reuse the module for local development using microk8s too. A ${PROJ}-${ENV}-resources
module sets up the cluster and writes a json file with the k8s host, token, and cluster_ca_certificate (which makes it k8s vendor generic). Next the ${PROJ}-${ENV}-services
reads in that json file to configure the kubernetes and helm providers, as well as the ingress controller (if DigitalOcean), and finally invokes the ${PROJ}-k8s-services
module to do things like the deployment, service, and ingress records. Later on I'd just pass through additional configuration if needed.
This is a late follow-up on the technique of using
depends_on
to order the invocation of modules in #564.The
depends_on = [var.cluster_id]
trick also works when applied todata "digitalocean_kubernetes_cluster" "primary"
. In fact it appears that having it anywhere inside the module is sufficient. Removing it from the module (e.g. becauseresource "local_file" "kubeconfig"
is not used or wanted) will make the module fail in the plan phase (when usingterraform apply
: before the plan is shown for confirmation by the user):Terraform 0.13 supports
depends_on
between modules: https://www.terraform.io/docs/language/meta-arguments/depends_on.htmlI tried using that, but Terraform complains:
The documentation is quite explicit that this does not work:
The module developer's guide goes into more detail why it does not work (and also explains the reasons that led to these design choices -- not quoted here):
One might get the idea to simply move the
provider
block to the root module and use thedata "digitalocean_kubernetes_cluster" "primary"
trick withdepends_on = [module.doks-cluster]
and feed the attributes of the data source into the provider. However, this is also explicitly discouraged by the documentation:The reason why this works in the example of #564, even though all providers are global and should be instantiated early in the plan phase, appears to be because the
kubernetes
provider does not make any HTTP calls to the cluster until it actually tries to create resources. Thedepends_on
ensures that this does not happen too early. However, thekubernetes-alpha
provider, for example, calls the cluster very early (AFAIK to learn about the resources it supports), which will fail even with the explicitdepends_on
:Hence, to save users trouble and hard-to-debug errors, I suggest to split the example code into two separate root modules: One to create the cluster using just the digitalocean provider, and one using the digitalocean and kubernetes providers to install something on the cluster. The only information that would have to be exchanged (manually or via a remote state data source) would be the
cluster_name
, since all other information is already shared viadata "digitalocean_kubernetes_cluster" "primary"
.