Skip to main content

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:

atlas.hcl
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.

atlas.hcl
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:

atlas.hcl
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:

atlas.hcl
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:

atlas.hcl
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.