How to Launch a New Azure DevOps Pipeline Building Block Definition
This guide shows you how to create a building block definition that triggers and executes Azure DevOps pipelines. Azure DevOps pipeline building blocks enable you to leverage your existing CI/CD pipelines for automated resource provisioning and configuration in meshStack.
Prerequisites
Before you begin, ensure you have:
- Access to the Platform Builder in a workspace
- A user with Workspace Owner/Manager permissions
- An Azure DevOps organization with a pipeline configured
- A Personal Access Token (PAT) with Build (read and execute) permissions in Azure DevOps
Challenge
Many organizations already use Azure DevOps for CI/CD automation and have established pipelines for infrastructure provisioning. Instead of recreating this automation in a different tool, meshStack allows you to integrate your existing Azure DevOps pipelines as building blocks, enabling application teams to trigger these pipelines through self-service while maintaining centralized control.
Step by Step Guide
1. Create or Identify Your Azure DevOps Pipeline
Before configuring the building block in meshStack, you need a pipeline in Azure DevOps that will handle the provisioning logic.
Pipeline Requirements:
Your Azure DevOps pipeline receives building block inputs as pipeline parameters. These can include:
- User-provided inputs (e.g., database size, region)
- Static inputs (e.g., API keys, configuration values)
- Metadata inputs (e.g., workspace identifier, project identifier)
- Ephemeral API keys (when configured, provided as parameters
MESHSTACK_API_TOKENandMESHSTACK_ENDPOINT)
Example Azure DevOps Pipeline:
Create a file named azure-pipelines.yml in your repository:
trigger: none # Disable automatic triggers
parameters:
- name: REGION
type: string
default: ''
- name: ENVIRONMENT
type: string
default: ''
- name: WORKSPACE_IDENTIFIER
type: string
default: ''
pool:
vmImage: 'ubuntu-latest'
steps:
- task: Bash@3
displayName: 'Provision Resources'
inputs:
targetType: 'inline'
script: |
echo "Provisioning resources..."
echo "Region: ${{ parameters.REGION }}"
echo "Environment: ${{ parameters.ENVIRONMENT }}"
echo "Workspace: ${{ parameters.WORKSPACE_IDENTIFIER }}"
# Your provisioning logic here
# For example: Terraform, ARM templates, Azure CLI commands
# Access building block inputs as pipeline parameters via template expressions
# Example: ${{ parameters.REGION }}, ${{ parameters.ENVIRONMENT }}, etc.
Finding Your Pipeline ID:
- Navigate to your pipeline in Azure DevOps
- Open the pipeline and look at the URL:
https://dev.azure.com/{organization}/{project}/_build?definitionId={pipelineId} - Note the
definitionIdvalue - this is your Pipeline ID
2. Create an Azure DevOps Integration in meshStack
You can create an Azure DevOps integration either before creating the building block definition, or during the building block definition creation wizard.
To create an integration in advance:
- Navigate to the Admin Area in meshStack
- Go to Settings > Integrations
- Click Create Integration and select Azure DevOps
- Fill in the integration details:
- Integration Name: A descriptive name (e.g., "Production Azure DevOps")
- Organization: Your Azure DevOps organization name
- Azure DevOps Base URL: Typically
https://dev.azure.com(or your Azure DevOps Server URL) - Personal Access Token: A PAT with Build (read and execute) permissions
Creating a Personal Access Token:
-
In Azure DevOps, click your profile icon and select Personal access tokens
-
Click New Token
-
Give it a descriptive name (e.g., "meshStack Building Blocks")
-
Set appropriate expiration
-
Select Custom defined scopes
-
Check Build (Read & execute)
-
Click Create and copy the token
-
Test the connection using the Test Azure DevOps Connection button
-
Save the integration
3. Create the Building Block Definition
Now you can create the building block definition that uses your Azure DevOps pipeline:
- Navigate to Platform Builder in your workspace
- Go to Building Blocks > Definitions
- Click Create new Definition
Select Implementation Type
When creating a new building block definition, you'll first select the Implementation Type. Choose Azure DevOps Pipeline.
General Configuration
- Definition Name: A user-friendly name that will appear in the marketplace (e.g., "Azure Database Provisioning")
- Description: Explain what the building block does and what resources it provisions
Building Block Type:
Choose whether this building block provisions resources at the workspace or tenant level:
- Workspace Building Block: Provisions resources for the workspace
- Tenant Building Block: Provisions resources for specific tenants/projects
Supported Platforms:
This setting is only relevant if you selected Tenant Building Block as the type.
If you're creating a tenant building block, choose which platforms this building block can provision resources for. Users will only see this building block for projects with tenants on these platforms.
- Support and Documentation: Provide links to additional resources for users
Use in Landing Zone Only:
- Enable this if the building block should automatically execute when tenants are created in a landing zone
- Leave disabled if users should add it manually from the marketplace
Notification User:
- Add email addresses to receive notifications about failed executions or required platform engineer input
Building Block Run Control:
Choose who can trigger building block runs and view detailed logs:
- Platform Team Only: Only platform teams can manually trigger runs; workspace users only see user-level messages
- Platform Team and Workspace Users: Both platform teams and workspace users can trigger runs and view all logs
Tags
Assign tags to your building block definition if required by your meshStack configuration.
Implementation
Assignment:
- One: The building block can only be assigned once per project or workspace
- Multiple: Users can create multiple instances
Azure DevOps Configuration:
- Azure DevOps Integration: Select the integration you created earlier
- Azure DevOps Project: Enter the name of the project containing your pipeline
- Pipeline ID: Enter the pipeline ID (found in the URL as described above)
Execution Mode:
Choose how meshStack should track the pipeline execution:
- Synchronous: meshStack automatically tracks the pipeline execution and updates the building block status based on the pipeline result. Use this when you only need basic success/failure tracking and don't need to publish pipeline outputs back to meshStack.
- Asynchronous (Required for outputs): The building block remains in pending state, and your pipeline must update the status via the meshStack API using the provided
MESHSTACK_RUN_URLandMESHSTACK_RUN_TOKEN. Use this mode if your pipeline needs to report custom statuses or outputs to meshStack.
Choose Synchronous mode when you don't need pipeline outputs or custom status handling—this is simpler and meshStack handles all status tracking automatically. Choose Asynchronous mode when you need to publish outputs from your pipeline to meshStack or implement custom status logic.
Ephemeral API Keys (Optional):
If your pipeline needs to interact with the meshStack API, enable ephemeral API keys in this section:
- Enable Use Ephemeral API Keys
- Select the required permissions (e.g.,
BUILDINGBLOCK_SAVE,TENANT_LIST) - Your pipeline will receive:
MESHSTACK_API_TOKEN: Temporary bearer token (as a parameter)MESHSTACK_ENDPOINT: meshStack API URL (as a parameter)
See How to Use Ephemeral API Keys for more details.
4. Configure Building Block Inputs
Define the inputs your pipeline needs. These will be passed as pipeline parameters to your Azure DevOps pipeline.
Common Input Types:
- String: Simple text values
- Number: Numeric values
- Boolean: True/false values
- Selection: Dropdown with predefined options
- User Permissions: List of users and their roles (for platforms not natively supported by meshStack)
- Code: Complex structured data (JSON, YAML, HCL)
- File: File uploads
Input Configuration:
For each input:
- Click Add Input
- Set the Input Key (e.g.,
REGION) - this becomes the pipeline parameter name - Choose the Input Type
- Set Source:
- Static: Pre-configured value
- User: Users provide the value when adding the building block
- Metadata: Automatically derived metadata from meshStack (workspace, project info, etc.)
- Enable Sensitive if the input contains secrets (encrypts the value)
Example Input Configuration:
| Input Key | Type | Source | Description |
|---|---|---|---|
| REGION | Selection | User | Azure region for resources |
| ENVIRONMENT | String | User | Environment name (dev/prod) |
| WORKSPACE_IDENTIFIER | String | Metadata | Current workspace identifier |
| DATABASE_SIZE | Selection | User | Database tier selection |
5. Configure Building Block Outputs (Optional)
If your pipeline generates values that users or other building blocks need, configure outputs:
- Click Add Output
- Set the Output Key (e.g.,
DATABASE_CONNECTION_STRING) - Set Visibility:
- Admin and User: Visible to both platform teams and application teams
- Admin Only: Only visible to platform teams
Outputs from Azure DevOps pipelines are only supported in Asynchronous execution mode. Use Synchronous execution only if you don't need to capture outputs in meshStack. In Asynchronous mode, your pipeline must write outputs back to meshStack via the meshStack API using the MESHSTACK_RUN_URL and MESHSTACK_RUN_TOKEN parameters.
6. Test Your Building Block
Before publishing to the marketplace:
- Click Save to save your building block definition
- Create a test building block instance in a project or workspace
- Monitor the pipeline execution in Azure DevOps
- Check the building block run details in meshStack for logs and status
- Verify that inputs are correctly passed as pipeline parameters
- Test error scenarios to ensure proper error handling
7. Publish to Marketplace
Once testing is complete:
- Click Publish to make the building block available in the marketplace
- Users can now discover and add your building block to their projects
Example: Complete Database Provisioning Building Block
Here's a complete example of an Azure DevOps pipeline for provisioning an Azure SQL Database:
trigger: none
parameters:
- name: DATABASE_NAME
type: string
- name: DATABASE_SIZE
type: string
- name: REGION
type: string
- name: WORKSPACE_IDENTIFIER
type: string
- name: PROJECT_IDENTIFIER
type: string
variables:
- group: azure-credentials # Variable group with Azure service principal
pool:
vmImage: 'ubuntu-latest'
steps:
- task: AzureCLI@2
displayName: 'Provision Azure SQL Database'
inputs:
azureSubscription: 'production-service-connection'
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
# Create resource group
RESOURCE_GROUP="meshstack-${{ parameters.WORKSPACE_IDENTIFIER }}-${{ parameters.PROJECT_IDENTIFIER }}"
az group create --name $RESOURCE_GROUP --location ${{ parameters.REGION }}
# Create SQL Server
SERVER_NAME="sql-${{ parameters.WORKSPACE_IDENTIFIER }}-${{ parameters.PROJECT_IDENTIFIER }}"
ADMIN_PASSWORD=$(openssl rand -base64 32)
az sql server create \
--name $SERVER_NAME \
--resource-group $RESOURCE_GROUP \
--location ${{ parameters.REGION }} \
--admin-user sqladmin \
--admin-password "$ADMIN_PASSWORD"
# Create SQL Database
az sql db create \
--resource-group $RESOURCE_GROUP \
--server $SERVER_NAME \
--name ${{ parameters.DATABASE_NAME }} \
--service-objective ${{ parameters.DATABASE_SIZE }}
echo "Database provisioned successfully"