Configuring CI/CD on Azure

Last modified: April 22, 2024

1 Introduction

This document explains the configuration options available when configuring a Continuous Integration and Delivery (CI/CD) solution for Private Mendix Platform on the Azure DevOps service.

1.1 Prerequisites

To configure the CI/CD pipeline, prepare the following:

  • An Azure organization where you want to build your Mendix app.
  • An Azure blob or an AWS S3 endpoint where you can store the built MDA files.

2 Configuring the CI/CD Pipeline

If you have an Azure organization, you can set Azure as your CI System in Settings > DevOps > CI/CD. You need to first obtain a Personal Access Token, and then configure the followings settings:

Finally, you must also register your Kubernetes cluster.

2.1 Obtaining a Personal Access Token

A Personal Access Token (PAT) is used to authenticate in Azure DevOps. For information about obtaining the token, see Create a PAT in the Azure DevOps documentation.

2.2 Configuring Azure Blob Settings

The settings in this section configure the Azure blob settings.

  • Azure Blob URL - For example, https://{your domain name}.blob.core.windows.net/pmp.
  • Azure Blob Token - This secret value is used to access the Azure Blob storage.

2.3 Configuring Build Images Setting

The settings in this section configure the S3 bucket.

  • S3 Endpoint - For example, Cloud Object Storage - Amazon S3 - AWS.
  • S3 Bucket Name - Your S3 bucket name, for example, mybucket.
  • Region - For example, ap-southeast-1.
  • Access Key ID - This ID value is used to access the S3 bucket.
  • Secret Access Key - This secret key value is used to access the S3 bucket.

2.4 Registering a Kubernetes Cluster

Before creating any environments, you must register your Kubernetes clusters by doing the following steps:

  1. Click Register New Cluster.

  2. Configure the following values:

    • Cluster Name - Specify a name for the cluster.

    • API Server - Specify your Kubernetes API server.

    • Token - You must first create a service account, cluster role, and cluster role binding in the cluster, and then get the service account’s token. For reference, see the following shell script:

       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      
      # create ServiceAccount, ClusterRole, and ClusterRoleBinding
      kubectl apply -f << EOF -
      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: mxplatform-cicd
        namespace: kube-system
      ---
      apiVersion: v1
      kind: Secret
      metadata:
        name: mxplatform-cicd
        namespace: kube-system
        annotations:
          kubernetes.io/service-account.name: mxplatform-cicd
      type: kubernetes.io/service-account-token
      ---
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRole
      metadata:
        name: mxplatform-cicd
      rules:
      - apiGroups:
        - ""
        resources:
        - namespaces
        verbs:
        - list
      - apiGroups:
        - privatecloud.mendix.com
        resources:
        - storageplans
        verbs:
        - list
      - apiGroups:
        - privatecloud.mendix.com
        resources:
        - mendixapps
        verbs:
        - '*'
      ---
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRoleBinding
      metadata:
        name: mxplatform-cicd
      subjects:
      - kind: ServiceAccount
        name: mxplatform-cicd
        namespace: kube-system
      roleRef:
        kind: ClusterRole
        name: mxplatform-cicd
        apiGroup: rbac.authorization.k8s.io
      EOF
      
      # get service account token:
      kubectl get secret mxplatform-cicd -nkube-system -o jsonpath='{.data.token}'|base64 -d
      # for openshift cluster
      kubectl get secret mxplatform-cicd -nkube-system -o jsonpath='{.metadata.annotations.openshift\.io/token-secret\.value}'
      
  3. Optionally, enable the Help Me feature. For reference, see the following shell script:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    
    # create ServiceAccount, ClusterRole, and ClusterRoleBinding
    kubectl apply -f << EOF -
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: mxplatform-cicd
      namespace: kube-system
    ---
    apiVersion: v1
    kind: Secret
    metadata:
      name: mxplatform-cicd
      namespace: kube-system
      annotations:
        kubernetes.io/service-account.name: mxplatform-cicd
    type: kubernetes.io/service-account-token
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
        name: mxplatform-cicd
    rules:
    - apiGroups:
        - ""
        resources:
        - namespaces
        verbs:
        - list
    - apiGroups:
        - ""
        resources:
        - deployments
        verbs:
        - get
        - list
        - watch
    - apiGroups:
        - ""
        resources:
        - pods
        verbs:
        - get
        - list
    - apiGroups:
        - ""
        resources:
        - pods/log
        verbs:
        - get
    - apiGroups:
        - ""
        resources:
        - events
        verbs:
        - get
        - list
    - apiGroups:
        - privatecloud.mendix.com
        resources:
        - storageplans
        verbs:
        - list
    - apiGroups:
        - privatecloud.mendix.com
        resources:
        - mendixapps
        verbs:
        - '*'
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
        name: mxplatform-cicd
    subjects:
    - kind: ServiceAccount
        name: mxplatform-cicd
        namespace: kube-system
    roleRef:
        kind: ClusterRole
        name: mxplatform-cicd
        apiGroup: rbac.authorization.k8s.io
    EOF
    
    # get service account token:
    kubectl get secret mxplatform-cicd -nkube-system -o jsonpath='{.data.token}'|base64 -d
    # for openshift cluster
    kubectl get secret mxplatform-cicd -nkube-system -o jsonpath='{.metadata.annotations.openshift\.io/token-secret\.value}'
    
  4. Click Save.

  5. Click the newly created cluster and expand it, and then click Retrieve Namespace(s) to retrieve all the namespace and storage plans.

    Namespaces without any storage plan are skipped. This step requires the Mendix Operator to be installed and configured. You can repeat this step as required to retrieve additional namespaces.

  6. After the cluster is registered, create environments with the cluster, namespace and plans.

3 Architecture of the CI/CD Pipeline

The diagrams in this section present the architecture and components of the pipeline. The architecture is different depending on whether you enabled the Auto Detect Mx Version build image setting.

3.1 Architecture with the Auto Detect Mx Version Setting Enabled

The following diagram shows the architecture of the pipeline if you enable the Auto Detect Mx Version setting. For more information, see Build Images Setting.

Auto Detect Mx Runtime Version

3.2 Architecture with the Auto Detect Mx Version Setting Disabled

The following diagram shows the architecture of the pipeline if you disable the Auto Detect Mx Version setting. For more information, see Build Images Setting.

User Input Mx Runtime Version