Selective service deployment with bitbucket pipelines in a monorepo with multiple microservices
M

1

10

We have a serverless framework project with different microservices in a monorepo. The structure of the project looks like:

project-root/
|-services/
  |-service1/
    |-handler.py
    |-serverless.yml
  |-service2/
  ...
  |-serviceN/
...
|-bitbucket-pipelines.yml

As you can see, each service has its own deployment file (serverless.yml).

We want to deploy only the services that have been modified in a push/merge and, as we are using bitbucket-pipelines, we prefer to use its features to get this goal.

After doing a little research, we've found the changesets property that can condition a step to the changed files inside a directory. So, for each service we could add in out bitbucket-pipelines.yml something like:

- step:
   name: step1
   script:
      - echo "Deploy service 1"
      - ./deploy service1
   condition:
      changesets:
         includePaths:
            # only files directly under service1 directory
            - "service1/**"

This seems like a perfect match, but the problem with this approach is that we must write a step for every service we have in the repo, and, if we add more services we will have to add more steps, and this affects maintainability and readability.

Is there any way to make a for loop with a parametrized step where the input parameter is the name of the service?

On the other hand, we could make a custom script that handles the condition and the deployment detecting the changes itself. Even if we prefer the bitbucket-native approach, we are open to other options; what's the best way to do this in a script?

Malpighiaceous answered 25/11, 2020 at 10:22 Comment(0)
B
1

Closest you can get would be reusing a yaml anchor for deployment steps and match custom deployment environments with your services.

definitions:
  yaml-anchors:
    - &deploy-step
        name: Deploy
        script:
          - echo "Deploy $BITBUCKET_DEPLOYMENT_ENVIRONMENT"
          - ./deploy $BITBUCKET_DEPLOYMENT_ENVIRONMENT

pipelines:
  branches:
    main:
      - parallel:

        - step:
          <<: *deploy-step
          deployment: service1
          condition:
            changesets:
              includePaths:
                - service1/**

        - step:
          <<: *deploy-step
          deployment: service2
          condition:
            changesets:
              includePaths:
                - service2/**

        # ...

        - step:
          <<: *deploy-step
          deployment: serviceN
          condition:
            changesets:
              includePaths:
                - serviceN/**

Bonus: Bitbucket will track each microservice deployment independently.

I doubt BITBUCKET_DEPLOYMENT_ENVIRONMENT can be interpolated in the includePaths block so this is still quite verbose. If you manage to smarten your deploy script to detect the file changes for you, then you could reduce this to

definitions:
  yaml-anchors:
    - &deploy-step
        name: Deploy
        script:
          - echo "Deploy $BITBUCKET_DEPLOYMENT_ENVIRONMENT"
          - ./deploy $BITBUCKET_DEPLOYMENT_ENVIRONMENT

pipelines:
  branches:
    main:
      - parallel:

        - step:
          <<: *deploy-step
          deployment: service1
        - step:
          <<: *deploy-step
          deployment: service2
        # ...
        - step:
          <<: *deploy-step
          deployment: serviceN

But beware there is a short limit to the amount of custom deployment environments you can have.

Betthel answered 28/3, 2023 at 16:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.