Reputation: 62836
Here is a code snippet:
stages:
- stage: Apply
dependsOn: Plan
variables:
OVERRIDE_ADO_ENVIRONMENT: $[ dependencies.Plan.outputs['Plan.IsTerraformPlanEmpty.OVERRIDE_ADO_ENVIRONMENT'] ]
condition: and(succeeded(), ${{ parameters.terraform_apply }})
jobs:
- deployment: Apply
environment: ${{ coalesce(variables.OVERRIDE_ADO_ENVIRONMENT, parameters.ado_environment) }}
strategy:
runOnce:
deploy:
steps:
- template: start.yaml
- template: terraform_init.yaml
parameters:
I know the build variable OVERRIDE_ADO_ENVIRONMENT
is declared correctly, because I can use it in the condition
to skip the Apply
stage completely.
However, this is incorrect. Even if the plan is empty, there could be a change in the terraform output variables. Therefore I must run the Apply logic always. However, there is no need for approvals in this case.
Therefore I would like to switch the environment to the one in the OVERRIDE_ADO_ENVIRONMENT
build variable which is a special environment with no approvals.
However, trying to run this pipeline produces the following error message:
Job Apply: Environment $[ dependencies could not be found. The environment does not exist or has not been authorized for use.
From which I conclude we cannot use a build variable, albeit computed in a previous stage.
The question is - what is the least painful way to implement this logic? If at all possible.
I tried an approach where I create two stages with a condition that is affected by the output variable from the previous stage. However, I found out that:
Here is my attempt to use this approach
parameters:
- name: terraform_apply
type: boolean
- name: ado_environment
- name: working_directory
- name: application
default: terraform
- name: apply_stages
type: object
default:
- name: ApplyNonEmptyPlan
displayName: Apply Non Empty Plan
tf_plan_tag: TF_NON_EMPTY_PLAN
- name: ApplyEmptyPlan
displayName: Apply Empty Plan
tf_plan_tag: TF_EMPTY_PLAN
ado_environment: Empty TF Plan
stages:
- ${{ each apply_stage in parameters.apply_stages }}:
- stage: ${{ apply_stage.name }}
displayName: ${{ apply_stage.displayName }}
dependsOn: Plan
variables:
TF_PLAN_TAG: $[ stageDependencies.Plan.Plan.outputs['IS_TERRAFORM_PLAN_EMPTY.TF_PLAN_TAG'] ]
condition: and(succeeded(), ${{ parameters.terraform_apply }}, eq(variables['TF_PLAN_TAG'], '${{ apply_stage.tf_plan_tag }}'))
jobs:
- deployment: ${{ apply_stage.name }}
environment: ${{ coalesce(apply_stage.ado_environment, parameters.ado_environment) }}
strategy:
runOnce:
deploy:
steps:
- template: start.yaml
Upvotes: 0
Views: 452
Reputation: 8310
Environment creation happens at compile
time before run
time. It doesn't support dynamic environment
name. Hence, in the code snippet shared below, each element in
coalesce
should be known(or hardcode) before you run the pipeline, it cannot depends on the output calculated from previous stage.
environment: ${{ coalesce(variables.OVERRIDE_ADO_ENVIRONMENT, parameters.ado_environment) }}
and
environment: ${{ coalesce(apply_stage.ado_environment, parameters.ado_environment) }}
Upvotes: 0