Let's Play With Terraform External Providers
These external providers cannot all called with the same method, so here's how we can switch it up.
Join the DZone community and get the full member experience.
Join For FreeWith Terraform, in order to use an existing resource in a new resource we want to create, we can use a data source. It's powerful and easy to understand and manipulate, but the thing to know is that you can't retrieve every data source type as you want. Indeed, several data source types can't be retrieved with filter, but several another can.
For example, you can retrieve an existing VPC by its tag name:
# VPC
data "aws_vpc" "vpc-dzone" {
filter {
name = "tag:Name"
values = ["myvpc-for-dzone-article"]
}
}
It's cool, useful, but unfortunately, this filtering is not possible for every resource.
In my case, I needed to retrieve an existing (network) load balancer, in AWS, and then give the information in order to create an AWS Route 53.
So the solution is to:
1. Create a script which retrieves the resource
2. Use the result of the script in a Terraform data source, with an external provider
3. Use this special data in the resource you want to create
1. The Script
my_module/scripts/get_elb.sh :
#!/bin/bash
set -e
kubectl get svc mygateway -n istio-system -o json | jq .status.loadBalancer.ingress[0]
This script returns a JSON object with a Kubernetes (Istio) gateway (which is an AWS Load Balancer):
$ ./my_module/scripts/get_elb.sh
{
"hostname": "a123456789gsfgfsgfsg12134gsgsg78-123456789dfdsf45545fdsf.elb.eu-central-1.amazonaws.com"
}
2. The Data Source with Terraform External Provider
my_module/data.tf :
data"external""elb"{
program= ["bash", "${path.module}/scripts/get_elb.sh"]
}
3. The Definition of Wanted Resource
my_module/aws_r53.tf:
resource "aws_route53_record""mymodule_CNAME" {
zone_id="${data.aws_route53_zone.my_zone.zone_id}"
name="${var.domain_name}"
type="CNAME"
records= ["${data.external.elb.result.hostname}"]
ttl="${var.route53_ttl}"
}
Finally, apply your Terraform resources definition in order to create your resources.
You can now check providers used by Terraform in your project & modules:
$ terraform providers
.
├── provider.aws ~> 1.24.0
└── module.my_module
├── provider.aws (inherited)
└── provider.external
That's it!
Opinions expressed by DZone contributors are their own.
Comments