ARM 模板参数的 Azure 管道迭代

问题描述 投票:0回答:1

我有一个如下的二头肌文件,用于使用 azure devops 管道创建到

resourceGroup
范围的角色分配。

主要.二头肌

targetScope = 'resourceGroup'

@description('Principal type of the assignee.')
@allowed([
  'Device'
  'ForeignGroup'
  'Group'
  'ServicePrincipal'
  'User'
])
param principalType string

@description('the id for the role defintion, to define what permission should be assigned')
param RoleDefinitionId string

@description('the id of the principal that would get the permission')
param principalId string

@description('the role deffinition is collected')
resource roleDefinition 'Microsoft.Authorization/roleDefinitions@2018-01-01-preview' existing = {
  scope: subscription()
  name: RoleDefinitionId
}

resource RoleAssignment 'Microsoft.Authorization/roleAssignments@2020-10-01-preview' = {
  name: guid(resourceGroup().id, RoleDefinitionId, principalId)
  properties: {
    roleDefinitionId: roleDefinition.id
    principalId: principalId
    principalType: principalType
  }
}

这是我的管道,我想在其中构建二头肌并将多个原则 iD 作为数组传递。但它失败了

管道.yaml。

parameters:
- name: roleList
  type: object

stages:
- stage: BuilD_Roles_ARM_Artifact
  displayName: 'Build_ARM_Template'           
  jobs:
  - ${{ each role in parameters.roleList }}:
    - job: BuilD_ARM_Artifact_${{ role.environment }}_${{ role.rolesname }}
      displayName: '${{ role.rolesname }}'
      variables:
      - name: subscription
        ${{ if or(eq(role.environment, 'development'), eq(role.environment, 'staging')) }}:          
          value: 'mynonprod'
        ${{ if eq(role.environment, 'production')}}:
          value: "myprod"
        ${{ if eq(role.environment, 'dr')}}:
          value: "mydr"          
      workspace:
        clean: all
      pool:
        ${{ if eq(role.environment, 'development')}}:
          name: devpool
        ${{ if eq(role.environment, 'staging')}}:
          name: stagepool
        ${{ if eq(role.environment, 'production')}}:
          name: az-prod-spoke
        ${{ if eq(role.environment, 'dr')}}:
          name: drpool     
      steps:
      - bash: |      
          resourceGroup=${{ role.resourceGroup }}
          echo "##vso[task.setvariable variable=resourceGroup]$resourceGroup"
          principalType=${{ role.principalType }}
          echo "##vso[task.setvariable variable=principalType]$principalType"
          principalid=${{ role.principalid }}
          echo "##vso[task.setvariable variable=principalid]$principalid"
          roleDefinitionId=${{ role.roleDefinitionId }}
          echo "##vso[task.setvariable variable=roleDefinitionId]$roleDefinitionId"
      - bash: az bicep build --file template/main.bicep
        displayName: 'Compile Bicep to ARM'
      - task: qetza.replacetokens.replacetokens-task.replacetokens@3
        inputs:
          rootDirectory: '$(System.DefaultWorkingDirectory)/'
          targetFiles: '$(System.DefaultWorkingDirectory)/template/parameters.json'
          encoding: 'auto'
          writeBOM: true
          actionOnMissing: 'warn'
          keepToken: false
          tokenPrefix: '#{'
          tokenSuffix: '}#'
          useLegacyPattern: false
          enableTelemetry: true
      - task: AzureCLI@2
        displayName: "validate the templates"
        inputs:
          azureSubscription: ${{ variables.subscription }}
          scriptType: 'bash'
          scriptLocation: 'inlineScript'
          inlineScript: 'az group deployment validate --resource-group $(resourceGroup) --template-file $(System.DefaultWorkingDirectory)/template/main.json --parameters $(System.DefaultWorkingDirectory)/template/parameters.json'
      - task: AzureCLI@2
        displayName: "verify the change result"
        inputs:
          azureSubscription: ${{ variables.subscription }}
          scriptType: 'bash'
          scriptLocation: 'inlineScript'
          inlineScript: 'az deployment group what-if --resource-group $(resourceGroup) --template-file $(System.DefaultWorkingDirectory)/template/main.json --parameters $(System.DefaultWorkingDirectory)/template/parameters.json'                
      - task: PublishBuildArtifacts@1
        inputs:
          PathtoPublish: '$(System.DefaultWorkingDirectory)/template/'
          ArtifactName: 'arm-source-${{ role.environment }}-${{ role.rolesname }}'
          publishLocation: 'Container'
        name: "Publish_arm_code"
        displayName: "Publish arm code as build artifact"
    
- stage: Create_RoleAssignment
  displayName: 'Create RoleAssignment'                 
  jobs:
  - ${{ each role in parameters.roleList }}:        
    - deployment: deploy_role_${{ role.environment }}_${{ role.rolesname }}
      displayName: '${{ role.rolesname }}'
      variables:
      - name: resourceGroup
        value: ${{ role.resourceGroup }}          
      - name: subscription
        ${{ if or(eq(role.environment, 'development'), eq(role.environment, 'staging')) }}:          
          value: 'mynonprod'
        ${{ if eq(role.environment, 'production')}}:
          value: "myprod"
        ${{ if eq(role.environment, 'dr')}}:
          value: "mydr"
      ${{ if eq(variables.subscription, 'mynonprod') }}:
        environment: NON-PROD-RBAC      
      ${{ if eq(variables.subscription, 'myprod') }}:
        environment: PROD-RBAC
      ${{ if eq(variables.subscription, 'mydr') }}:
        environment: DR-RBAC
      pool:
        ${{ if eq(variables.subscription, 'mynonprod') }}:          
          name: devpool
        ${{ if eq(variables.subscription, 'mytest') }}:
          name: stagepool
        ${{ if eq(variables.subscription, 'myprod') }}:
          name: az-prod-spoke
        ${{ if eq(variables.subscription, 'mydr') }}:
          name: drpool                 
      strategy:
        runOnce:
          deploy:
            steps:
            - download: none
            - task: DownloadBuildArtifacts@0
              inputs:
                artifactName: 'arm-source-${{ role.environment }}-${{ role.rolesname }}'
                downloadPath: $(System.ArtifactsDirectory)              
            - task: CopyFiles@2
              inputs:
                sourceFolder: $(System.ArtifactsDirectory)/arm-source-${{ role.environment }}-${{ role.rolesname }}
                contents: '**'
                targetFolder: $(System.DefaultWorkingDirectory)/arm-source-${{ role.environment }}-${{ role.rolesname }}
                cleanTargetFolder: true
            - task: AzureCLI@2
              displayName: "Create the change result"
              inputs:
                azureSubscription: ${{ variables.subscription }}
                scriptType: 'bash'
                scriptLocation: 'inlineScript'
                inlineScript: 'az deployment group create --resource-group $(resourceGroup) --template-file $(System.DefaultWorkingDirectory)/arm-source-${{ role.environment }}-${{ role.rolesname }}/main.json --parameters $(System.DefaultWorkingDirectory)/arm-source-${{ role.environment }}-${{ role.rolesname }}/parameters.json'

这是我的管道输入文件

name: $(Build.SourceBranchName)-$(Build.BuildId)
trigger: none

stages:
- template: azure-pipeline.yaml
  parameters:
    roleList:
    - rolesname: rolename1
      environment: development
      scope: resourcegroup
      principalType: Group     
      principalid: xxxxxxxxxxx,yyyyyyyy, zzzzzzzzz
      roleDefinitionId: acdxxxxxxxxxxxxxxxxxxxxx    # reader id
      resourceGroup: myrg-1

    - rolesname: rolename2
      environment: development      
      scope: resourcegroup
      principalType: Group     
      principalid: aaaaaaaa,bbbbbbbbbb,cccccccccc         
      roleDefinitionId: acdxxxxxxxxxxxxxxxxxxxxx    # reader id
      resourceGroup: myrg-2

    - rolesname: rolename3
      environment: development      
      scope: resourcegroup
      principalType: Group     
      principalid:          
      roleDefinitionId: acdxxxxxxxxxxxxxxxxxxxxx    # reader id
      resourceGroup: myrg-3

所以首先我将二头肌构建为 ARM 文件,并在循环中用管道变量替换变量,这会一起创建多个 ARM 模板。

所以我正在寻找两件事。

  1. 对于每个角色分配,我将能够通过输入传递 PrincipleID 列表。如果我添加多个 PrincipleID,上述模板语法将失败

  2. 寻找一种方法来迭代所有角色参数(如果添加了任何更改)并拥有带有输入的单个 ARM 模板。这样它将生成一个 ARM 构建工件,仅用于修改角色分配项。

添加修改后的文件

新的二头肌文件

targetScope = 'resourceGroup' 

@description('Principal type of the assignee.')
@allowed([
  'Device'
  'ForeignGroup'
  'Group'
  'ServicePrincipal'
  'User'
])
param principalType string

@description('the id for the role defintion, to define what permission should be assigned')
param RoleDefinitionId string

@description('the id of the principal that would get the permission')
param principalId string

@description('the role deffinition is collected')
resource roleDefinition 'Microsoft.Authorization/roleDefinitions@2018-01-01-preview' existing = {
  scope: subscription()
  name: RoleDefinitionId
}

resource RoleAssignment 'Microsoft.Authorization/roleAssignments@2020-10-01-preview' = [for id in split(principalId, ','): {
  name: guid(resourceGroup().id, RoleDefinitionId, principalId)
  properties: {
    roleDefinitionId: roleDefinition.id
    principalId: principalId
    principalType: principalType
  }
}]

参数文件

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
     "principalType": {
         "value": "#{principalType}#"
     },
     "RoleDefinitionId": {
       "value": "#{RoleDefinitionId}#"          
     },     
     "principalId": {
       "value": "#{principalId}#"
     }
  } 
}

管道文件。

  - rolesname: readerall
    environment: development      
    scope: resourcegroup
    principalType: Group     
    principalid: aaaaaaaaaaaaaa,bbbbbbbbbbbbbbbbb,ccccccccccccccccccccc,ddddddddddddddddddddd
    roleDefinitionId: acddxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    resourceGroup: aks-rg

  - rolesname: reader_apimrg_all
    environment: development      
    scope: resourcegroup
    principalType: Group     
    principalid: aaaaaaaaaaaaaa,bbbbbbbbbbbbbbbbb,ccccccccccccccccccccc,ddddddddddddddddddddd
    roleDefinitionId: acddxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    resourceGroup: apim-rg


  - rolesname: reader_lawrg_all
    environment: development      
    scope: resourcegroup
    principalType: Group     
    principalid: aaaaaaaaaaaaaa,bbbbbbbbbbbbbbbbb,ccccccccccccccccccccc,ddddddddddddddddddddd
    roleDefinitionId: acddxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    resourceGroup: la-rg
azure azure-resource-manager azure-bicep
1个回答
1
投票

这里主体 ID 以字符串形式传递:

principalid: xxxxxxxxxxx,yyyyyyyy,zzzzzzzzz

在二头肌文件中,您可以拆分字符串以创建多个角色分配:

resource roleAssignments 'Microsoft.Authorization/roleAssignments@2020-10-01-preview' = [for id in split(principalId, ','): {
  name: guid(resourceGroup().id, RoleDefinitionId, id)
  properties: {
    roleDefinitionId: roleDefinition.id
    principalId: id
    principalType: principalType
  }
}]

关于你的第二个问题,听起来很复杂。您可能需要一个准备任务,该任务将迭代并检查哪些角色分配已存在,然后创建一个复杂的对象以传递到二头肌文件。因为 ARM API 是幂等的,所以不确定为什么您只尝试部署新的更改?

© www.soinside.com 2019 - 2024. All rights reserved.