AWS CodeBuild buildspec bash 语法错误:用 if 语句替换错误
Posted
技术标签:
【中文标题】AWS CodeBuild buildspec bash 语法错误:用 if 语句替换错误【英文标题】:AWS CodeBuild buildspec bash syntax error: bad substitution with if statement 【发布时间】:2020-12-17 20:36:34 【问题描述】:背景:
我正在使用 AWS CodeBuild buildspec.yml 来遍历 GitHub 存储库中的目录。在遍历目录路径 $TF_ROOT_DIR
之前,我使用 bash if 语句来检查 GitHub 分支名称 $BRANCH_NAME
是否在环境变量 $LIVE_BRANCHES
中。正如您在下面的错误屏幕截图中所见,bash if 语句输出错误:syntax error: bad substitution
。当我在本地 bash 脚本中重现 if 语句时,if 语句按预期工作。
这是 CodeBuild 项目中定义的环境变量:
这是来自 buildspec.yml 的相关 sn-p:
version: 0.2
env:
shell: bash
phases:
build:
commands:
- |
if [[ " $LIVE_BRANCHES[*] " == *"$BRANCH_NAME"* ]]; then
# Iterate only through BRANCH_NAME directory
TF_ROOT_DIR=$TF_ROOT_DIR/*/$BRANCH_NAME/
else
# Iterate through both dev and prod directories
TF_ROOT_DIR=$TF_ROOT_DIR/*/
fi
- echo $TF_ROOT_DIR
这是显示语法错误的构建日志:
这是用于重现 CodeBuild 项目的 AWS CodeBuild 项目 JSON:
"projects": [
"name": "terraform_validate_plan",
"arn": "arn:aws:codebuild:us-west-2:xxxxx:project/terraform_validate_plan",
"description": "Perform terraform plan and terraform validator",
"source":
"type": "GITHUB",
"location": "https://github.com/marshall7m/sparkify_end_to_end.git",
"gitCloneDepth": 1,
"gitSubmodulesConfig":
"fetchSubmodules": false
,
"buildspec": "deployment/CI/dev/cfg/buildspec_terraform_validate_plan.yml",
"reportBuildStatus": false,
"insecureSsl": false
,
"secondarySources": [],
"secondarySourceVersions": [],
"artifacts":
"type": "NO_ARTIFACTS",
"overrideArtifactName": false
,
"cache":
"type": "NO_CACHE"
,
"environment":
"type": "LINUX_CONTAINER",
"image": "hashicorp/terraform:0.12.28",
"computeType": "BUILD_GENERAL1_SMALL",
"environmentVariables": [
"name": "TF_ROOT_DIR",
"value": "deployment",
"type": "PLAINTEXT"
,
"name": "LIVE_BRANCHES",
"value": "(dev, prod)",
"type": "PLAINTEXT"
这是相关的构建规范文件内容:(buildspec_terraform_validate_plan.yml
)
version: 0.2
env:
shell: bash
parameter-store:
AWS_ACCESS_KEY_ID_PARAM: TF_AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY_PARAM: TF_AWS_SECRET_ACCESS_KEY_ID
phases:
install:
commands:
# install/incorporate terraform validator?
pre_build:
commands:
# CodeBuild environment variables
# BRANCH_NAME -- GitHub branch that triggered the CodeBuild project
# TF_ROOT_DIR -- Directory within branch ($BRANCH_NAME) that will be iterated through for terraform planning and testing
# LIVE_BRANCHES -- Branches that represent a live cloud environment
- export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID_PARAM
- export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY_PARAM
- bash -version || echo "$BASH_VERSION" || bash --version
- |
if [[ -z "$BRANCH_NAME" ]]; then
# extract branch from github webhook
BRANCH_NAME=$(echo $CODEBUILD_WEBHOOK_HEAD_REF | cut -d'/' -f 3)
fi
- "echo Triggered Branch: $BRANCH_NAME"
- |
if [[ " $LIVE_BRANCHES[*] " == *"$BRANCH_NAME"* ]]; then
# Iterate only through BRANCH_NAME directory
TF_ROOT_DIR=$TF_ROOT_DIR/*/$BRANCH_NAME/
else
# Iterate through both dev and prod directories
TF_ROOT_DIR=$TF_ROOT_DIR/*/
fi
- "echo Terraform root directory: $TF_ROOT_DIR"
build:
commands:
- |
for dir in $TF_ROOT_DIR; do
#get list of non-hidden directories within $dir/
service_dir_list=$(find "$dir" -type d | grep -v '/\.')
for sub_dir in $service_dir_list; do
#if $sub_dir contains .tf or .tfvars files
if (ls $sub_dir/*.tf) > /dev/null 2>&1 || (ls $sub_dir/*.tfvars) > /dev/null 2>&1; then
cd $sub_dir
echo ""
echo "*************** terraform init ******************"
echo "******* At directory: $sub_dir ********"
echo "*************************************************"
terraform init
echo ""
echo "*************** terraform plan ******************"
echo "******* At directory: $sub_dir ********"
echo "*************************************************"
terraform plan
cd - > /dev/null
fi
done
done
鉴于这只是一个附带项目,所有可能与此问题相关的文件都在公共 repo here 中。
更新
尝试添加 #!/bin/bash
shebang 行但导致 CodeBuild 错误:
Phase context status code: COMMAND_EXECUTION_ERROR Message: Error while executing command: #!/bin/bash
version: 0.2
env:
shell: bash
phases:
build:
commands:
- |
#!/bin/bash
if [[ " $LIVE_BRANCHES[*] " == *"$BRANCH_NAME"* ]]; then
# Iterate only through BRANCH_NAME directory
TF_ROOT_DIR=$TF_ROOT_DIR/*/$BRANCH_NAME/
else
# Iterate through both dev and prod directories
TF_ROOT_DIR=$TF_ROOT_DIR/*/
fi
- echo $TF_ROOT_DIR
解决方案
正如@Marcin 所述,我在 Codebuild (aws/codebuild/standard:4.0) 中使用了 AWS 托管映像,并在 install
阶段下载了 Terraform。
phases:
install:
commands:
- wget https://releases.hashicorp.com/terraform/$TERRAFORM_VERSION/terraform_$TERRAFORM_VERSION_linux_amd64.zip -q
- unzip terraform_$TERRAFORM_VERSION_linux_amd64.zip && mv terraform /usr/local/bin/
【问题讨论】:
【参考方案1】:我尝试重现您的问题,但对我来说一切正常。
我注意到的唯一一件事是您使用的是$BRANCH_NAME
,但它没有在任何地方定义。但即使缺少$BRANCH_NAME
,您发布的buildspec.yml
也能正常运行。
使用hashicorp/terraform:0.12.28
图像更新
【讨论】:
我故意省略了确定 $BRANCH_NAME 的代码,以使代码 sn-p 与问题相关。但是您可以从代码构建日志屏幕截图中的输出echo $BRANCH_NAME
中看到 $BRANCH_NAME 的定义。感谢您的尝试,不幸的是我还没有找到解决这个奇怪问题的方法。
@Marshallm 是否可以使用能够重现问题的示例来更新问题?据我所见并记得您当前的示例按预期工作,并且不允许重现该问题。随后,难以协助。
我添加了代码构建项目 json 和完整的构建规范文件。如果需要,所有文件都在公共 repo here.
@Marshallm 我的进一步测试表明hashicorp/terraform:0.12.28
中没有bash
。以相反的方式进行构建会不会更容易,即使用 AWS 托管映像进行 CodeBuild,并在其上安装 terraform?
啊,这就是为什么,我盲目地认为 hashcorp/terraform:0.12.28 会加入 bash。我猜 syntax error: bad substitution
错误让我失望,我认为该错误与 bash 密切相关。我采纳了您关于使用 AWS 托管映像的建议,并在我的帖子中反映了这一变化。感谢@Marcin 的所有帮助!以上是关于AWS CodeBuild buildspec bash 语法错误:用 if 语句替换错误的主要内容,如果未能解决你的问题,请参考以下文章
如何在 AWS CodeBuild 上运行 docker-compose?