Had the following code in a cloud-init config:
1 |
RUNNERTOKEN=$(curl -s -XPOST -H "authorization: token _REPLACETOKEN_" https://api.github.com/repos/_REPLACEREPO_/actions/runners/registration-token | jq -r .token) |
During cloud-init it gave me a “Failed to Shellify” error in /var/log/cloud-init.log
and one of the messages just above it was the following:
runcmd.9: {‘RUNNERTOKEN=$(curl -s -XPOST -H “authorization’: ‘token _REPLACETOKEN_” https://api.github.com/repos/_REPLACEREPO_/actions/runners/registration-token | jq -r .token)’} is not valid under any of the given schemas
Thanks to a StackOverflow post I realised my error. I was typing in commands under the runcmd
section as if it were a Bash script or something like a Dockerfile but obviously that’s not the case. From the docs you can see the following:
1 2 3 4 5 6 7 8 |
# runcmd contains a list of either lists or a string # each item will be executed in order at rc.local like level with # output to the console # - runcmd only runs during the first boot # - if the item is a list, the items will be properly executed as if # passed to execve(3) (with the first arg as the command). # - if the item is a string, it will be simply written to the file and # will be interpreted by 'sh' |
So it either expects something along the line of the ENTRYPOINT and CMD lines in a Dockerfile – a list of an executable and its arguments – or just a string that it can pass to the shell for execution. All I had to thus do was put the erroneous line in single quotes and the next time cloud-init had no complaints. Yay!
Also, it’s not so obvious from the docs but you can use shell variables in a cloud-init file as all the commands run in a single shell instance that keeps variables between each command. Consider the following:
1 2 3 |
runcmd: - 'RUNNERTOKEN=$(curl -s -XPOST -H "authorization: token _REPLACETOKEN_" https://api.github.com/repos/_REPLACEREPO_/actions/runners/registration-token | jq -r .token)' - RUNNER_ALLOW_RUNASROOT=1 ./config.sh --url https://github.com/_REPLACEREPO_ --token $RUNNERTOKEN --unattended |
I am able to assign a shell variable RUNNERTOKEN
in the first line and use it in the second line.