If you're working with aws and using terraform for ci/cd automation, you have the option to work with CodePipeline and CodeBuild. In CodeBuild you should define your buildspec.yml file as a command list to make your build process.
You have two options: first, read the buildspec.yml file from the source and the second is to use an embedded file.
Using the second option when using terraform has many advantages:
- you are using a single file for many pipelines
- changing and maintenance is easy
I had to do this for some of my projects. I had several repos with the same technology and pipeline read buildspec.yml
from code. Later we had to do some changes and I was forced to modify all of them.I decided to embed buildspec.yml
file in my terraform and manage it using parameters.
The first step was to load buildspec.yml
from local and as my previous experiences i tried to use template_file
:
data "template_file" "buildspec" {
template = "${file("${path.module}/buildspec.yml")}"
}
But it failed!
Error: failed to render : <template_file>:16,32-33: Extra characters after interpolation expression; Expected a closing brace to end the interpolation expression, but found extra characters.
│
│ with module.pipeline.data.template_file.buildspec,
│ on ../../../../modules/cicd_ecs_github_embed/main.tf line 172, in data "template_file" "buildspec":
│ 172: data "template_file" "buildspec" {
│
I used it before for loading CodeBuild Policy and CodePipleine policy templates. Anyway, by searching more I found template_file
use to see files as a template and except some placeholder like ${var}
to fill it. and my file has some $var
placeholder that would be filled from CodeBuild!
Solution 1: use local_file
you can ignore using template_file for this step if you dont want to pass any params to it at this stage.
So I moved to use another terraform object local_file
:
data "local_file" "buildspec_local" {
filename = "${path.module}/buildspec.yml.tmpl"
}
and then in my CodeBuild :
source {
buildspec = data.local_file.buildspec_local.content
git_clone_depth = 0
insecure_ssl = false
report_build_status = false
type = "CODEPIPELINE"
}
solution 2: escape ${} in buildspec
If you really want to pass some dynamic parameters in your buildspec.yml
file , you should escape ${var:option}
parameters. because terraform expect all variable in simple ${var}
format ,when you're using some special tag like IMAGE_TAG=${COMMIT_HASH:=latest}
it gives error, so escape this parameter by double $ character s below :
- IMAGE_TAG=$${COMMIT_HASH:=latest}
Now you can pass your desired variables in template file and escape CodeBuild specific variables:
data "template_file" "buildspec" {
template = "${file("${path.module}/buildspec.yml")}"
vars = {
#feed dynamic variables I need
ps_asset_s3_bucket="${var.ps_asset_s3_bucket_key}"
...
}
and then load it in source
section of your code build
I hope this experience be useful for you.
Top comments (0)