0

How can I dynamically pass multiple Role ARNs defined in my Bitbucket repository environment variable to a step variable in my pipeline?

I have three Role ARNs defined in my Bitbucket repository environment variable, named OIDC_ROLE_ARN_dev, OIDC_ROLE_ARN_stage, and OIDC_ROLE_ARN_master, corresponding to the branch names dev, stage, and master, respectively. I want to dynamically select the appropriate Role ARN based on the current branch and use it as a step variable.

I've attempted to achieve this using Indirect expansion like OIDC_ROLE_ARN="OIDC_ROLE_ARN_${BITBUCKET_BRANCH}" and then using ${!OIDC_ROLE_ARN}. While this works fine locally, it throws a syntax error "bad substitution" in the pipeline environment.

Here's my pipeline step:

- step: &build-and-push-fitserver-image
    name: Build and Push fitServer Image to ECR
    oidc: true
    script:
      - OIDC_ROLE_ARN="OIDC_ROLE_ARN_${BITBUCKET_BRANCH}"
      - docker build -t fitserver:${BITBUCKET_BRANCH} -t fitserver:latest .
      - pipe: atlassian/aws-ecr-push-image:2.4.0
        variables:
          AWS_OIDC_ROLE_ARN: ${!OIDC_ROLE_ARN}
          IMAGE_NAME: fitserver
          TAGS: "${BITBUCKET_BRANCH} latest"

Could someone please suggest a way to resolve this issue without using if-else conditions?

1 Answer 1

0

If you only use a variable for deployments, you can define its value for each deployment environment instead of a global value for all pipelines.

See https://support.atlassian.com/bitbucket-cloud/docs/variables-and-secrets/#Deployment-variables

Then, you can use the different value with the same name, as well as the additional $BITBUCKET_DEPLOYMENT_ENVIRONMENT.

definitions:
  yaml-enchors:
    - &deploy-step
        name: Build and Push fitServer Image to ECR
        oidc: true
        script:
          - docker build -t fitserver:${BITBUCKET_DEPLOYMENT_ENVIRONMENT} -t fitserver:latest .
          - pipe: atlassian/aws-ecr-push-image:2.4.0
            variables:
              AWS_OIDC_ROLE_ARN: ${AWS_ROLE_ARN}
              IMAGE_NAME: fitserver
              TAGS: "${BITBUCKET_DEPLOYMENT_ENVIRONMENT} latest"

pipelines:
  branches:
    dev:
      - step:
        <<: *deploy-step
        deployment: development
    stage:
      - step:
        <<: *deploy-step
        deployment: staging
    master:
      - step:
        <<: *deploy-step
        deployment: production

Othewise, your try with ${!OIDC_ROLE_ARN} is in the right path, but note you used it in the pipe instruction and not in a shell instruction.

For each instruction in the script list, the pipeline runner will either

  • eval it in a shell if it is a YAML scalar string
  • execute a pipe if it is a YAML mapping

Now, pipes have some support for variable substitution (e.g. $FOO, ${BAR}), but they are not a shell. If some syntax is not supported, just eval the indirected variable in a string instruction before the pipe!

- step: &build-and-push-fitserver-image
    name: Build and Push fitServer Image to ECR
    oidc: true
    deployment: xxx
    script:
      - OIDC_ROLE_ARN_VAR="OIDC_ROLE_ARN_${BITBUCKET_DEPLOYMENT_ENVIRONMENT}"
      - OIDC_ROLE_ARN=${!OIDC_ROLE_ARN_VAR}
      - docker build -t fitserver:${BITBUCKET_DEPLOYMENT_ENVIRONMENT} -t fitserver:latest .
      - pipe: atlassian/aws-ecr-push-image:2.4.0
        variables:
          AWS_OIDC_ROLE_ARN: ${OIDC_ROLE_ARN}
          IMAGE_NAME: fitserver
          TAGS: "${BITBUCKET_DEPLOYMENT_ENVIRONMENT} latest"

Not the answer you're looking for? Browse other questions tagged or ask your own question.