I like to include smoke tests [ST] in my Terraform [TF] deployments just to make sure I didn’t overlook anything obvious. One such way is to interact with a resource that invokes other resources, such as an HTTP endpoint that is routed through API gateways, application containers and databases.
An easy and portable way to do this with Terraform is declaring a null_resource [NR] with a local-exec provisioner [LE] that invokes a curl [CU] like this:
resource "null_resource" "test-containerapp-helloworld" {
provisioner "local-exec" {
command = "curl --insecure --silent --fail $URL"
interpreter = ["bash", "-c"]
environment = {
URL = "http://my-app.azure.net"
}
}
depends_on = [azurerm_container_app.containerapp-helloworld]
}
Declaring a null_resource is the way I chose to insert custom logic into the deployment without creating any resources in the target infrastructure. The local-exec provisioner executes a curl command on the client machine which will fetch the target URL and fail if it returns anything other than an 200 code. Variable substitution works here, so a dynamic URL can be constructed by referencing variables and resource outputs. Obviously more complex logic like grepping for a specific output or running test script can be executed here. The depends_on attribute ensures that the test runs only after the resource-under-test has been created (here: a container app).
Update 2023.03.02
Sometimes services can take a while to start even after the deployment is complete, so a liveness probe would initially fail. In that case a simple script that polls over the service until it returns a ready status (or times out) looks like this:
resource "null_resource" "test-containerapp-helloworld" {
provisioner "local-exec" {
command = <<EOM
echo Trying "$URL"
timeout 120s bash -c 'until curl --silent --fail --show-error --retry-connrefused "$URL" > /dev/null; do sleep 5; done' && echo ok || echo not ok
EOM
interpreter = ["bash", "-c"]
environment = {
URL = "${azurerm_api_management.apim-service.gateway_url}/${azurerm_api_management_api.api-helloworld.path}"
}
}
depends_on = [azurerm_container_app.containerapp-helloworld, azurerm_api_management_api.api-helloworld]
}
References
[ST] Smoke testing
https://en.wikipedia.org/wiki/Smoke_testing_(software)
[TF] Terraform
https://www.terraform.io/
[NR] null_resource
https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource
[LE] local-exec provisioner
https://developer.hashicorp.com/terraform/language/resources/provisioners/local-exec
[CU] curl man page
https://curl.se/docs/manpage.html