[FEATURE REQ]
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 25/100
Research direction
Start by reviewing publisher.yml, publisher-with-env.yml, and the referenced configuration.qa.yaml in the Azure DevOps pipeline, then trace how product artifacts and environment configuration are passed to the publisher. Done means the product is published to QA or production with that environment's values rather than unchanged development values, with the behavior documented or reproduced by a test.
Written by the indexing model from the issue text.
Description
Please describe the feature.
Hi i going to create APIM for Dev, QA, Prod env for my client this is new requirement. i am having issue when i publish the product from dev to qa, and prod. this is below listed activity i have done.
1, created 3 APIM like dev, qa and prod envs.
2, manually create APIs, backends, named values, products, subscriptions in dev env.
3, Extract the dev env APIM resources and entities using extractor pipeline in azure devops pipeline.
4, artifacts were stored in the repos, this contains APIs, backends, named values etc.
5, now i am going to publish the all above created entities in dev to qa using config.qa.yaml. this contains qa env based backend url, named values secrets and product policy yamls. backend and named values were created as expected. but product is publishing as expected from config.qa.yaml file.
6, backend, named values were published from config.qa.yml file, but product has been published which is same like dev env getting from artifacts.
7, so product has not been published as expected
Note:
provide me the exact yaml file for publish the product to another envs, because we are having unique token for individual envs.
kindly provide me the solution ASAP, i have been working for long time. but still issue not resolved.
because we are new for APIOPS and myself only explain about APIOPS to the client. so provide me the detailed step by step solution.
this is my publisher.yml files.
trigger: none
branches:
include:
- main
paths:
exclude:
- tools/*
parameters:
-
name: LOCATION_NAME
displayName: 'Location name:'
default: cus
values:- cus
-
name: ENV_CHOICE
displayName: 'Environment name:'
default: dev
values:- poc
- dev
- qa
- qa2
- pims
- prd
- name: COUNT
displayname: 'count values:'
default: 01
values:
- 01
- 02
- 03
- 04
- name: PROJECT
displayname: 'Project name:'
default: ars
values:
- ars
- name: COMMIT_ID
type: string
displayName: Choose "publish-all-artifacts-in-repo" only when you want to force republishing all artifacts (e.g. after build failure). Otherwise stick with the default behavior of "publish-artifacts-in-last-commit"
default: publish-artifacts-in-last-commit
values:- publish-artifacts-in-last-commit
- publish-all-artifacts-in-repo
variables:
-
group: ARS-apim-automation
-
name: System.Debug
value: false -
name: API_OUTPUT_FOLDER_PATH
value: 'artifacts' -
name: RG_NAME
${{ if and(eq(parameters.ENV_CHOICE, 'poc'), eq(parameters.LOCATION_NAME, 'cus') )}}:
value: $(RESOURCE_GROUP_NAME_POC)
${{ if and(eq(parameters.ENV_CHOICE, 'dev'), eq(parameters.LOCATION_NAME, 'cus') )}}:
value: $(RESOURCE_GROUP_NAME_DEV)
${{ if and(eq(parameters.ENV_CHOICE, 'qa'), eq(parameters.LOCATION_NAME, 'cus') )}}:
value: $(RESOURCE_GROUP_NAME_QA)
${{ if and(eq(parameters.ENV_CHOICE, 'qa2'), eq(parameters.LOCATION_NAME, 'cus') )}}:
value: $(RESOURCE_GROUP_NAME_QA2)
${{ if and(eq(parameters.ENV_CHOICE, 'pims'), eq(parameters.LOCATION_NAME, 'cus') )}}:
value: $(RESOURCE_GROUP_NAME_PIMS)
${{ if and(eq(parameters.ENV_CHOICE, 'prd'), eq(parameters.LOCATION_NAME, 'cus') )}}:
value: $(RESOURCE_GROUP_NAME_PRD) -
name: APIM_INSTANCE_NAME
${{ if and(eq(parameters.ENV_CHOICE, 'poc'), eq(parameters.LOCATION_NAME, 'cus') )}}:
value: $(APIM_NAME_POC)
${{ if and(eq(parameters.ENV_CHOICE, 'dev'), eq(parameters.LOCATION_NAME, 'cus') )}}:
value: $(APIM_NAME_DEV)
${{ if and(eq(parameters.ENV_CHOICE, 'qa'), eq(parameters.LOCATION_NAME, 'cus') )}}:
value: $(APIM_NAME_QA)
${{ if and(eq(parameters.ENV_CHOICE, 'qa2'), eq(parameters.LOCATION_NAME, 'cus') )}}:
value: $(APIM_NAME_QA2)
${{ if and(eq(parameters.ENV_CHOICE, 'pims'), eq(parameters.LOCATION_NAME, 'cus') )}}:
value: $(APIM_NAME_PIMS)
${{ if and(eq(parameters.ENV_CHOICE, 'prd'), eq(parameters.LOCATION_NAME, 'cus') )}}:
value: $(APIM_NAME_PRD) -
name: SERVICE_CONN_NAME
${{ if and(or(eq(parameters.ENV_CHOICE, 'dev'), eq(parameters.ENV_CHOICE, 'poc'), eq(parameters.ENV_CHOICE, 'qa'), eq(parameters.ENV_CHOICE, 'qa2')), eq(parameters.LOCATION_NAME, 'cus')) }}:
value: $(SERVICE_CONNECTION_NAME_NPRD)
${{ else }}:
value: $(SERVICE_CONNECTION_NAME_PRD) -
name: ENV_NAME
value: 'apim-${{ parameters.ENV_CHOICE }}-${{ parameters.LOCATION_NAME }}'
stages:
- stage: push_APIM_changes_to_${{ parameters.ENV_CHOICE }}
displayName: Push APIM changes to ${{ parameters.ENV_CHOICE }}
jobs:- deployment: push_APIM_changes_to_${{ parameters.ENV_CHOICE }}
displayName: Push APIM changes to ${{ parameters.ENV_CHOICE }}
pool:
vmImage: ubuntu-latest
environment: ${{ variables.ENV_NAME }}
strategy:
runOnce:
deploy:
steps:
- template: run-publisher-with-env.yml
parameters:
API_MANAGEMENT_SERVICE_OUTPUT_FOLDER_PATH: ${{ variables.API_OUTPUT_FOLDER_PATH }}
RESOURCE_GROUP_NAME: ${{ variables.RG_NAME }}
API_MANAGEMENT_SERVICE_NAME: ${{ variables.APIM_INSTANCE_NAME }}
CONFIGURATION_YAML_PATH: $(Build.SourcesDirectory)/tools/configs/${{ parameters.LOCATION_NAME }}/configuration.${{ parameters.ENV_CHOICE }}.yaml
#CONFIGURATION_YAML_PATH: $(Build.SourcesDirectory)/tools/configs/cus/configuration.qa.yaml
ENVIRONMENT: ${{ variables.ENV_NAME }}
COMMIT_ID: ${{ parameters.COMMIT_ID }}
SERVICE_CONNECTION_NAME: ${{ variables.SERVICE_CONN_NAME }}
- deployment: push_APIM_changes_to_${{ parameters.ENV_CHOICE }}
this is my publisher-with-env.yml:
parameters:
- name: API_MANAGEMENT_SERVICE_OUTPUT_FOLDER_PATH
type: string
displayName: Folder where the artifacts reside
default: "artifacts" - name: ENVIRONMENT
type: string
displayName: Environment to display - name: RESOURCE_GROUP_NAME
default: ant-rg-apim-poc
type: string
displayName: Resource Group Name - name: API_MANAGEMENT_SERVICE_NAME
type: string
displayName: APIM Instance Name
default: "" - name: CONFIGURATION_YAML_PATH
type: string
displayName: Optional configuration file (target environment publishing into) - name: COMMIT_ID
type: string
default: publish-artifacts-in-last-commit - name: SERVICE_CONNECTION_NAME
type: string
default: ARS-ApiOps
steps:
-
script: echo Provided configuration was ${{ parameters.CONFIGURATION_YAML_PATH }}
displayName: Print the name of the yaml configuration file if provided -
script: echo Provided app service name was ${{ parameters.API_MANAGEMENT_SERVICE_NAME }}
displayName: Print the name of the apim service name if provided -
checkout: self
fetchDepth: 0 -
task: AzureCLI@2
displayName: Set publishing variables
inputs:
azureSubscription: "${{parameters.SERVICE_CONNECTION_NAME}}"
scriptType: pscore
scriptLocation: inlineScript
inlineScript: |
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
$VerbosePreference = "Continue"
$InformationPreference = "Continue"Write-Host "##vso[task.setvariable issecret=true;variable=AZURE_BEARER_TOKEN]$(az account get-access-token --query "accessToken" --output tsv)" Write-Host "##vso[task.setvariable issecret=true;variable=AZURE_CLIENT_ID]$env:servicePrincipalId" Write-Host "##vso[task.setvariable issecret=true;variable=AZURE_CLIENT_SECRET]$env:servicePrincipalKey" Write-Host "##vso[task.setvariable issecret=true;variable=AZURE_TENANT_ID]$env:tenantId" if (-not $env:AZURE_SUBSCRIPTION_ID) { $subscriptionCount = az account list --query "length([])" --output tsv if ($subscriptionCount -eq 1) { $subscriptionId = az account list --query "[0].id" --output tsv Write-Host "Setting AZURE_SUBSCRIPTION_ID environment variable to: $subscriptionId" Write-Host "##vso[task.setvariable issecret=true;variable=AZURE_SUBSCRIPTION_ID]$($subscriptionId)" } elseif ($subscriptionCount -gt 1) { Write-Host "Multiple subscriptions are accessible. Please set the AZURE_SUBSCRIPTION_ID environment variable manually." exit 1 } } else { Write-Host "AZURE_SUBSCRIPTION_ID is already set to: $env:AZURE_SUBSCRIPTION_ID" }addSpnToEnvironment: true
failOnStandardError: true -
${{ if ne(parameters.CONFIGURATION_YAML_PATH, '') }}:
- task: qetza.replacetokens.replacetokens-task.replacetokens@6
displayName: "Perform namevalue secret substitution in ${{ parameters.CONFIGURATION_YAML_PATH }}"
inputs:
sources: ${{ parameters.CONFIGURATION_YAML_PATH }}
encoding: "auto"
addBOM: true
logLevel: "off"
missingVarLog: "warn"
missingVarAction: "none"
tokenPrefix: "{#"
tokenSuffix: "#}"
- task: qetza.replacetokens.replacetokens-task.replacetokens@6
-
task: PowerShell@2
displayName: Fetch publisher
inputs:
targetType: "inline"
script: |
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
$VerbosePreference = "Continue"
$InformationPreference = "Continue"Write-Information "Downloading publisher..." $publisherFileName = "publisher.linux-x64" $publisherFinalFileName = "publisher" if ("$(Agent.OS)" -like "*win*") { $publisherFileName = "publisher.win-x64.exe" $publisherFinalFileName = "publisher.exe" } elseif ("$(Agent.OS)" -like "*mac*" -and "$(Agent.OSArchitecture)" -like "*arm*") { $publisherFileName = "publisher.osx-arm64" } elseif ("$(Agent.OS)" -like "*mac*" -and "$(Agent.OSArchitecture)" -like "*x86_64*") { $publisherFileName = "publisher.osx-x64" } $uri = "https://github.com/Azure/apiops/releases/download/$(apiops_release_version)/$publisherFileName" $destinationFilePath = Join-Path "$(Agent.TempDirectory)" $publisherFinalFileName Invoke-WebRequest -Uri "$uri" -OutFile "$destinationFilePath" if ("$(Agent.OS)" -like "*linux*") { Write-Information "Setting file permissions..." & chmod +x "$destinationFilePath" if ($LASTEXITCODE -ne 0) { throw "Setting file permissions failed."} } Write-Host "##vso[task.setvariable variable=PUBLISHER_FILE_PATH]$destinationFilePath" Write-Information "Execution complete."failOnStderr: true
pwsh: true -
task: PowerShell@2
displayName: Run publisher for ${{ parameters.ENVIRONMENT}} environment
inputs:
targetType: "inline"
script: |
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
$VerbosePreference = "Continue"
$InformationPreference = "Continue"& "$(PUBLISHER_FILE_PATH)" if ($LASTEXITCODE -ne 0) { throw "Running publisher failed."} Write-Information "Execution complete."failOnStderr: true
pwsh: true
env:
AZURE_BEARER_TOKEN: $(AZURE_BEARER_TOKEN)
AZURE_CLIENT_ID: $(AZURE_CLIENT_ID)
AZURE_CLIENT_SECRET: $(AZURE_CLIENT_SECRET)
AZURE_TENANT_ID: $(AZURE_TENANT_ID)
AZURE_SUBSCRIPTION_ID: $(AZURE_SUBSCRIPTION_ID)
AZURE_RESOURCE_GROUP_NAME: ${{ parameters.RESOURCE_GROUP_NAME }}
API_MANAGEMENT_SERVICE_OUTPUT_FOLDER_PATH: $(Build.SourcesDirectory)/${{ parameters.API_MANAGEMENT_SERVICE_OUTPUT_FOLDER_PATH }}
${{ if ne( parameters['API_MANAGEMENT_SERVICE_NAME'], '' ) }}:
API_MANAGEMENT_SERVICE_NAME: ${{ parameters.API_MANAGEMENT_SERVICE_NAME }}
${{ if eq( parameters['COMMIT_ID'], 'publish-artifacts-in-last-commit' ) }}:
COMMIT_ID: $(Build.SourceVersion)
${{ if ne( parameters['CONFIGURATION_YAML_PATH'], '' ) }}:
CONFIGURATION_YAML_PATH: ${{ parameters.CONFIGURATION_YAML_PATH }}
check this above mentioned files and provide the steps.
- Dominant language
- C#
- Stars
- 448
- Forks
- 247
- PR merge metrics
- No merged PRs in 30d
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from Azure/apiops
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
Difficulty 4/5 3-5 days Newbie friendliness 55/100
-
Difficulty 3/5 1-2 days Newbie friendliness 45/100
-
Difficulty 5/5 Over a week Newbie friendliness 35/100
-
Difficulty 4/5 3-5 days Newbie friendliness 35/100
Similar issues
-
type/automation type/tech-debt
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
t/bug
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
-
ci-failure-cause test-failure
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
-
area:auth FE mvp P3
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
klasolsson81/jobbliggaren#1788 ·