# Move module call to config branch and specify Terraform sample into
This section introduce Cycloid stacks concept to improve the reusability of your stack.
During the last step we created a Terraform module and used it in a
main.tf file, inside our
stacks branch. This step will make it more flexible and follow Cycloid stacks concept.
Keep in mind a stack can be deployed several times for differents environments or projects. The common way to do is to create a Terraform module in the
stacks branch. A Terraform module should be generic and describe an application. This mean if we want for an application to create 2 environments
prod we might want the exact same infrastructure but with smaller instance size on staging. So we will describe the infrastructure in a Terraform module and call this module 2 time (one for each env) using different parameters for the instance type.
As well this concept can also be applied to others technologies like Ansible.
This is where you apply Cycloid stacks concept. To make it simple there is no technologies limitation, it's just a way to split a
template (here the Terraform module) and an
parameters of a template (here Terraform module call).
To do it in our usecase, we will transform the call of the Terraform module
main.tf in a sample file. Each time someone will use your stack, it will use the Terraform module from the
stacks branch and automatically push the parameters of the module in a
config branch using your sample file. We will go more into details about it in this step.
Follow those steps to apply all changes described in this step
As described above let's define our new
main.tf.sample as a sample in Cycloid stack (similarly to the pipeline variables sample file), we will define the Terraform sample in
config: default: ... # Configuration of terraform to setup the infrastructure terraform: instance: path: 'terraform/main.tf.sample' destination: '($ project $)/terraform/($ environment $)/main.tf'
Those lines define the path of your stack sample in the
stacks branch and the expected path for the sample after user configuration in the
After this change, the next time you create a project or a new environment with this stack, the example of Terraform file to put in the Git
config branch will be displayed, letting the user to specify is own configuration:
Then it will be automatically pushed into his config repository
Unfortunatly this does not apply to an existing env, this is why we created the config branch and put manually this file in the commands above.
Cycloid special vars can be used in
.cycloid.yml file, in our case
'($ project $)/terraform/($ environment $)/main.tf' will be rendered by
Now to make your pipeline take into account, you need to apply the concept of merging
config that you will defined in the pipeline with the following changes:
- Add a
gitresource for our new
- Add merge stack and config sample as describe in produce a configured stack from stack and config section.
# Branch used to store the config of the stack config_git_branch: config
We define a pipeline variable to specify the branch for our new
git resource. And as well create a new git resource for the config branch:
resources: ... # The Terraform config (will be merged with the stack) - name: git_config type: git source: uri: ((git_repository)) branch: ((config_git_branch)) private_key: ((git_ssh_key)) paths: - ((project))/terraform/((env))/*
paths section here to limitate the trigger of the pipeline only if the configuration for this specific project and env change.
Then we need to merge our stack and our config inside the pipeline. To do it we will use the same tips as the previous step based on YAML Alias indicators.
# YAML anchors shared: - &task-merge-stack-and-config task: merge-stack-and-config config: platform: linux image_resource: type: docker-image source: repository: cycloid/cycloid-toolkit tag: latest run: path: /usr/bin/merge-stack-and-config inputs: - name: git_config path: "config" - name: git_stack path: "stack" outputs: - name: merged-stack path: "merged-stack" params: CONFIG_PATH: ((project))/terraform/((env)) STACK_PATH: stack-sample/terraform
This task call a script provided by cycloid in our cycloid-toolkit image to merge our 2 expected inputs
config and put the result of the merge in a
This merge also take
STACK_PATH as params related to the expected path of Terraform files defined in
Last change, add
task-merge-stack-and-config task and
git_config resource in our Terraform jobs to merge our config and stack before running the Terraform resource.
jobs: ... - name: terraform-plan plan: - do: - get: git_stack trigger: true - get: git_config trigger: true - get: git_code trigger: true passed: - unittest - *task-merge-stack-and-config - *task-get-commit - put: tfstate params: plan_only: true terraform_source: merged-stack/ var_files: - extracted-vars/terraform.tfvars - name: terraform-apply plan: - do: - get: git_stack trigger: false passed: - terraform-plan - get: git_config trigger: false passed: - terraform-plan - get: tfstate trigger: false passed: - terraform-plan - get: git_code passed: - terraform-plan - *task-merge-stack-and-config - *task-get-commit - put: tfstate params: plan_run: true terraform_source: merged-stack/ var_files: - extracted-vars/terraform.tfvars
The code above add the
get call of our
git_config resource then use the YAML anchor to add a merge task before.
Then we also changed the
terraform_source from terraform (
put: tfstate) to use the output of our merge
merged-stack instead of the Terraform code from the stack branch.
Add and commit those changes in Git:
git add . git commit -m "Step 5" git push origin stacks
Get back to Cycloid's dashboard, click on the
Refresh pipeline button .