Debugging Atlas HCL Using print()
With features such as composite schemas, custom rules, schema linting, and more, the atlas.hcl
file can get complex.
To validate or debug the file, you can use print
statements as you commonly would with other languages.
Example 1
To ensure that the proper value is being assigned to a variable, simply wrap it in a print statement:
data "runtimevar" "myip" {
url = "https://api.ipify.org?format=json"
}
locals {
ip = print(data.runtimevar.myip)
}
env "test" {
url = "mysql://user:pass@localhost:3306/my_db"
}
The print statement is evaluated when reached after running a command that accesses the file, such as atlas schema inspect --env test
.
After running the command, ip
is printed and I see a JSON in the output where I expected a string containing my IP address:
{"ip":"127.0.0.1"}
Now I know to decode and index the JSON to get the proper output.
data "runtimevar" "myip" {
url = "https://api.ipify.org?format=json"
}
locals {
ip = print(jsondecode(data.runtimevar.myip)["ip"])
}
127.0.0.1
Example 2
To ensure that an operation gives the proper result without assigning it to a variable, use the _
placeholder:
data "runtimevar" "myip" {
url = "https://api.ipify.org?format=json"
}
locals {
_ = print(data.runtimevar.myip)
}
Example 3
Let's look at a more involved example that combines these two methods:
data "external" "envfile" {
program = [
"node",
"./envfile.js"
]
}
locals {
envfile = jsondecode(data.external.envfile)
}
env "test" {
url = "mysql://${local.envfile.DB_USER}:${local.envfile.DB_PASS}@localhost:3306/${local.envfile.DB_NAME}"
dev = "docker://mysql/latest/dev"
}
Here, I use a program defined in envfile.js
that returns my .env
file as a JSON object. Then, I'm using
jsonencode
to save the result as a local JSON variable to access the environment variables.
To check that the JSON encoding of my .env
file and the resulting URL are correct, I can add print statements and see
if I get the expected results:
data "external" "envfile" {
program = [
"node",
"./envfile.js"
]
}
locals {
envfile = jsondecode(data.external.envfile)
_ = print(local.envfile["COMPANY_NAME"])
}
env "test" {
url = print("mysql://${local.envfile.DB_USER}:${local.envfile.DB_PASS}@$localhost:3306/${local.envfile.DB_NAME}")
dev = "docker://mysql/latest/dev"
}
At the beginning of my CLI output, we get the results of the print statements:
ariga
mysql://root:pass@localhost:3306/example
Keep in mind when placing print statements that their results are outputted as they are evaluated, so foreach
statements could cause duplicate outputs, printing variables that have yet to be assigned could lead to errors,
and so on.