patternbashMinor
Defining and using bash functions in AWS CodeBuild
Viewed 0 times
codebuildusingawsandfunctionsbashdefining
Problem
I thought I could slightly improve readability of repetitive
This can be called like so:
And this will replace all instances of the text
I get the same error defining the bash function with the alternative syntax:
I have read that buildspec version 0.1 used a separate shell process for each command, which would have caused this problem, but I am using buildspec version 0.2, so these commands should be sharing the same shell.
Of course I can just stick with the repetitive sed calls, but am I correct in understanding that bash functions cannot be used in buildspec commands at all? Is there a better way to get these secrets into a configuration file?
sed calls when inserting secrets into a file with AWS CodeBuild. I defined a bash function:replaceConfig() { sed -i 's|{'$1'}|'${!1}'|' config.json; }This can be called like so:
replaceConfig DB_PASSWORDAnd this will replace all instances of the text
{DB_PASSWORD} in config.json with the value held in secret environment variable DB_PASSWORD. Unfotunately, this does not work in CodeBuild. Inspecting the log file, I see:[Container] 2020*07*31 15:44:40 Running command replaceConfig DB_USERNAME
*codebuild*output*tmp*script.sh: line 4: replaceConfig: command not foundI get the same error defining the bash function with the alternative syntax:
function replaceConfig { sed -i 's|{'$1'}|'${!1}'|' config.json; }I have read that buildspec version 0.1 used a separate shell process for each command, which would have caused this problem, but I am using buildspec version 0.2, so these commands should be sharing the same shell.
Of course I can just stick with the repetitive sed calls, but am I correct in understanding that bash functions cannot be used in buildspec commands at all? Is there a better way to get these secrets into a configuration file?
version: 0.2
run-as: root
env:
shell: bash
variables:
AWS_REGION: us-east-2
secrets-manager:
DB_USERNAME: db-credentials:username
DB_PASSWORD: db-credentials:password
DB_HOST: db-credentials:host
....
phases:
....
post_build:
commands:
- replaceConfig() { sed -i 's|{'$1'}|'${!1}'|' config.json; }
- replaceConfig DB_USERNAME
- replaceConfig DB_PASSWORD
- replaceConfig DB_HOST
....
Solution
Bash functions (even when exported) are not preserved across
-
Combine steps which need the function in a single step. E.g.
-
Source the file with the functions you need in every step. This may sound laborious, but can be automated via the
But since this file will be sourced in every step (regardless if it's needed or not) and even in bash scripts called along the way, you should take care to indeed only put function definitions in there.
commands steps. This is in contrast to exported env variables, so it seems AWS is doing some shenanigans behind the scenes to prevent it. I see two basic options to work around that:-
Combine steps which need the function in a single step. E.g.
commands:
- |
replaceConfig() { sed -i 's|{'$1'}|'${!1}'|' config.json; }
replaceConfig DB_USERNAME &&
replaceConfig DB_PASSWORD &&
replaceConfig DB_HOST
-
Source the file with the functions you need in every step. This may sound laborious, but can be automated via the
BASH_ENV environment variable. E.g. let's say you put all the functions you need in a codbuild-helper.bash file in your project root, then you can do:env:
shell: bash
variables:
AWS_REGION: us-east-2
BASH_ENV: "$CODEBUILD_SRC_DIR/codebuild-helper.bash"
secrets-manager:
DB_USERNAME: db-credentials:username
DB_PASSWORD: db-credentials:password
DB_HOST: db-credentials:host
....
phases:
....
post_build:
commands:
- replaceConfig DB_USERNAME
- replaceConfig DB_PASSWORD
- replaceConfig DB_HOST
....
But since this file will be sourced in every step (regardless if it's needed or not) and even in bash scripts called along the way, you should take care to indeed only put function definitions in there.
Context
StackExchange DevOps Q#12110, answer score: 1
Revisions (0)
No revisions yet.