Generate Rust Bindings
In this section, we will go over the things you need to do to set up custom generated bindings. We recommend using an empty library crate for doing so.
Adding tf-bindgen
We will start by adding tf-bindgen
to our Project. Because it is utilized by both our build script and the generated code, we need to add it twice. You can use the following command to add the latest version from the repository:
cargo add -p "docker" \
--git "https://github.com/robert-oleynik/tf-bindgen.git" \
"tf-bindgen"
cargo add --build -p "docker" \
--git "https://github.com/robert-oleynik/tf-bindgen.git" \
"tf-bindgen"
Setup Build Script
As already mentioned, we will leverage Cargo's support for build scripts to generate the bindings for our provider. Thereto, we will create a new build.rs
in our crate:
// build.rs
use std::path::PathBuf;
fn main() {
println!("cargo:rerun-if-changed=terraform.toml");
let bindings = tf_bindgen::Builder::default()
.config("terraform.toml")
.generate()
.unwrap();
let out_dir = PathBuf::from(std::env::var("OUT_DIR").unwrap());
bindings.write_to_file(out_dir, "terraform.rs").unwrap();
}
This script will read the provider specified in the terraform.toml
file. In addition, it will parse the provider information and generate the corresponding Rust structs for it. The resulting bindings will be stored in the terraform.rs
inside our build directory.
As you may have noticed, we did not create a terraform.toml
yet. We will use this file to specify the providers we want to generate bindings for. A provider can be specified by adding <provider name> = "<provider version>"
to the [provider]
section of this TOML document. We will utilize the same version format as used by Cargo (see Specifying Dependencies). In the example below, we will use the docker provider locked to version 3.0.2
:
# terraform.toml
[provider]
"kreuzwerker/docker" = "=3.0.2"
Setup Module
Now we have generated our bindings, but we did not import them yet. To achieve that, we need to include the generated terraform.rs
file into our crate.
// src/lib.rs
include!(concat!(env!("OUT_DIR"), "/terraform.rs"));
tf-bindgen
will declare a module for each provider specified. So if you only declared a single provider, you may want to re-export these bindings to the current scope (e.g. pub use docker::*;
in case of the docker provider).