Building upon @don_crissti's answer, which is definitely correct, but it doesn't address a last mile concern in the question, which is:
I want to replace $INSTANCE_ID in the file with the value of the INSTANCE_ID
Interpolating a file, "in-place", using envsubst, is actually trickier than it would appear, given that read and write operations are (mostly) done concurrently, and are often parallel, when more than one cpu is available.
Eenvsubst reads against STDIN, and writes against STDOUT, we can't simply read, interpolate and redirect stdout to the same template file:
/ # </tmp/tmpl cat
hello $PATH
/ # </tmp/tmpl envsubst
hello /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
/ # </tmp/tmpl envsubst >/tmp/tmpl
/ # </tmp/tmpl cat
/ # stat /tmp/tmpl
File: /tmp/tmpl
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
There are a lot of ways to approach this, but the all boil down to: write the interpolated result to a buffer or write to a different file. Because your example looks config and deploy related, I prefer to use a make
esque build and install workflow, where we write the interpolated results to a dist
or build
directory, and then work against that.
# copy configuration/manifest/etc to dist directory, and then interpolate tmpl; not tested at all
$ cp -rf path/to/configs ./dist
$ find -L path/to/configs -type f -print0 \
| xargs -0 -n1 -- sh -c '<"$$1" envsubst >"dist/$$1"' _
Cheers from Linkoping ;)