2 min read | by Jordi Prats
To be able to execute an arbitrary command to retrieve some data and being able to use it as a variable in terraform we can use the external data-source
To be able to read the data the command will have to output the data using JSON. For example, if we want to use the following data in terraform:
$ kubectl get deployment pet2cattle -n pet2cattle -o jsonpath='{.spec.template.spec.containers[0].env[?(@.name == "MINIO_BUCKET")].value}' pet2cattle
We will have to transform it somehow so it is in JSON, for example by simulating a map with a single key-value pair:
$ kubectl get deployment pet2cattle -n pet2cattle -o jsonpath='{"{"}"minio-bucket": "{.spec.template.spec.containers[0].env[?(@.name == "MINIO_BUCKET")].value}"}' {"minio-bucket": "pet2cattle"}
Once the command we want to run output is a JSON, it is ready to be used using the external data-source in terraform. To do so we might have to scape some characters but the is going to be pretty much the same:
data "external" "minio_bucket" { program = ["sh", "-c", "kubectl get deployment pet2cattle -n pet2cattle -o jsonpath='{\"{\"}\"minio-bucket\": \"{.spec.template.spec.containers[0].env[?(@.name == \"MINIO_BUCKET\")].value}\"}'"] }
If we output the result using:
output "minio_bucket" { value = data.external.minio_bucket.result }
We will able to see that the result of the external data source it's going to be the JSON output structure:
$ terraform apply -auto-approve data.external.minio_bucket: Refreshing state... Apply complete! Resources: 0 added, 0 changed, 0 destroyed. Outputs: minio_bucket = { "minio-bucket" = "pet2cattle" }
On the pet2cattle github you'll find the terraform-external-datasource repository with the Kubernetes resources and the terraform code to be able to test this code: Clone the repository and create the Kubernetes resources using kubectl apply:
$ kubectl apply -f k8s_resources.yaml namespace/pet2cattle created deployment.apps/pet2cattle created
Once the resources are present on the cluster you just need to run terraform init and then terraform apply to see the described output value
Posted on 17/08/2021