shalb / cluster.dev

Cloud-native infrastructure templating. Creating cloud installers for SaaS. Replication of complex cloud-native infrastructures.
https://docs.cluster.dev/
GNU Affero General Public License v3.0
401 stars 36 forks source link

Passing values from remoteState to source template file of kubernetes unit #285

Closed kinseii closed 2 months ago

kinseii commented 2 months ago

Problem with passing values from remoteState to source template file of kubernetes unit.

---
kind: StackTemplate
name: qwerty
units:
  - name: qwerty-credentials
    type: tfmodule
    source: git::ssh://git@qwerty.qwerty/tf-module-qwerty//?ref=v0.1.0
    inputs:
      key_vault: {{ insertYAML .variables.key_vault }}
      secret_name_map:
        username: username
        password: password

  - name: qwerty-creds-k8s-secret
    type: kubernetes
    provider_conf:
      config_context: {{ .variables.cluster_name }}
    source: ./../../_templates/qwerty-creds-k8s-secret.yaml
    depends_on: this.qwerty-credentials
{{- $NAMESPACE := .variables.qwerty_namespace -}}
{{- $USERNAME := remoteState "this.qwerty-credentials.secret_values_map[\"username\"]" -}}
{{- $PASSWORD := remoteState "this.qwerty-credentials.secret_values_map[\"password\"]" -}}
---
apiVersion: v1
kind: Secret
metadata:
  name: qwerty-credentials
  namespace: {{ $NAMESPACE }}
data:
  username: {{ $USERNAME | b64enc }}
  password: {{ $PASSWORD | b64enc }}
type: Opaque

The qwerty-credentials unit gets the strings from the Key Vault and passes it to the qwerty-credentials-k8s-secret unit to create a secret with those strings. After deploy we get the following error:

00:02:20 [ERROR] unit: 'qwerty-aks-us-1.qwerty-creds-k8s-secret':
exit status 1, error output:
 ╷
│ Error: Reference to undeclared resource
│
│   on main.tf line 10, in resource "kubernetes_secret" "qwerty_credentials":
│   10:     "username" = data.terraform_remote_state.qwerty-aks-us-1-qwerty-credentials.outputs.secret_values_map["username"]
│
│ A data resource "terraform_remote_state"
│ "qwerty-aks-us-1-qwerty-credentials" has not been declared in the
│ root module.
╵
╷
│ Error: Reference to undeclared resource
│
│   on main.tf line 11, in resource "kubernetes_secret" "qwerty_credentials":
│   11:     "password" = data.terraform_remote_state.qwerty-aks-us-1-qwerty-credentials.outputs.secret_values_map["password"]
│
│ A data resource "terraform_remote_state"
│ "qwerty-aks-us-1-qwerty-credentials" has not been declared in the
│ root module.

I looked at the ./cluster.dev/cache directory and there are two .tf files created there. One is a backend definition for saving the state file and the other is this one:

provider "kubernetes" {
  config_context = "qwerty-aks-us-1"
}
resource "kubernetes_secret" "qwerty_credentials" {
  metadata {
    name      = "qwerty-credentials"
    namespace = "qwerty"
  }
  data = {
    "username" = data.terraform_remote_state.qwerty-aks-us-1-qwerty-credentials.outputs.secret_values_map["username"]
    "password" = data.terraform_remote_state.qwerty-aks-us-1-qwerty-credentials.outputs.secret_values_map["password"]
  }
  type = "Opaque"
}

So it seems that the kubernetes module, when creating a secret and passing a value to it from the state file via the remoteState function, is not creating the necessary terraform data-source and possibly other resources needed to do so.

Cluster.dev Version: cdev version v0.9.5

romanprog commented 2 months ago

Interesting problem, should works. I'll check

romanprog commented 2 months ago

I understood what the problem. Unfortunately, remoteState reference functions do not work with other templating functions.

username: {{ $USERNAME | b64enc }}

Problem is here | b64enc. Data processing in templating occurs at the initial stage before the generation of the terraform code and even before the processing of the output function, which will also not work in this case. And in the case of remoteState, data processing is generally on the terraform side. Therefore, no go-template functions are allowed in pipes after insertYaml, remoteState and output. I also encountered this problem more than once, but it is not possible to solve it even for output. Cdev is limited by the yaml syntax and templating process. The implementation of remoteState/output functions is quite complex. I recommend use local terraform wrapper modules for such data transformations.

kinseii commented 2 months ago

I understood what the problem. Unfortunately, remoteState reference functions do not work with other templating functions.

username: {{ $USERNAME | b64enc }}

Problem is here | b64enc. Data processing in templating occurs at the initial stage before the generation of the terraform code and even before the processing of the output function, which will also not work in this case. And in the case of remoteState, data processing is generally on the terraform side. Therefore, no go-template functions are allowed in pipes after insertYaml, remoteState and output. I also encountered this problem more than once, but it is not possible to solve it even for output. Cdev is limited by the yaml syntax and templating process. The implementation of remoteState/output functions is quite complex. I recommend use local terraform wrapper modules for such data transformations.

OK, I'll check it, thank you!

kinseii commented 2 months ago

It works, thank you!