Hello,
I have an issue in terraform where I’m running a data external that I’m using to connect over SSH to a virtual machine that I’m creating before that:
data "external" "vault_transit_token" {
program = ["ssh", "-o", "StrictHostKeyChecking=no", "root@${var.vault_transit["ip_address"]}", <<EOF
sleep 15
token=$(cat /etc/vault.d/.vault/transit_token)
jq -n --arg token "$token" '{"token":$token}'
EOF
]
depends_on = [
vsphere_virtual_machine.vault_transit
]
}
So the data depends on the ‘vault_transit’ vm, so that I make sure it runs afterwards.
The problem that I’m having is that when ssh is running, the VM hasn’t booted properly yet, so I need to wait a little bit still, as I get ‘connection refused’.
Is there a way I could maybe make it retry until it works or delay the task entirely or something to that effect?
Hi @lethargosapatheia,
The external
data source isn’t designed to handle this situation itself, but since it runs arbitrary code you could perhaps tell the data source to run a wrapper script which itself tries running this command in a loop, possibly with sleep
commands to make it poll politely, and then only exit once the ssh
command returns a successful exit code.
Another option would be to configure a provisioner on the vsphere_virtual_machine.vault_transit
resource which uses remote-exec
to run a do-nothing command over SSH. Terraform only considers a resource to have been fully created once its provisioners are complete, so you can use the provisioner’s built-in support for polling SSH to delay completion of this resource until SSH is available. The data source depends on the VM, and so it won’t be read until after the VM is “complete”.
1 Like
Hi @lethargosapatheia,
You could try using the time_sleep
resource to set up a delay.
That would look like the following:
resource "time_sleep" "wait_30_seconds" {
create_duration = "30s"
depends_on = [vsphere_virtual_machine.vault_transit]
}
data "external" "vault_transit_token" {
program = ["ssh", "-o", "StrictHostKeyChecking=no", "root@${var.vault_transit["ip_address"]}", <<EOF
sleep 15
token=$(cat /etc/vault.d/.vault/transit_token)
jq -n --arg token "$token" '{"token":$token}'
EOF
]
depends_on = [
time_sleep.wait_30_seconds
]
}
Hope this helps!
1 Like