your programing

스크립트가 서비스 연결에 액세스하는 방법(Azure Devops 파이프라인)

lovepro 2023. 4. 22. 22:35
반응형

스크립트가 서비스 연결에 액세스하는 방법(Azure Devops 파이프라인)

https://learn.microsoft.com/en-us/azure/devops/pipelines/library/service-endpoints에 따르면 다양한 서비스 연결 유형이 있습니다.프로젝트 레벨에서 일련의 서비스 접속을 간단하게 관리할 수 있으며, 이를 표시/편집할 수 있는 사용자를 제한하기 위한 권한을 설정할 수 있습니다.이 모든 것이 좋습니다.

그러나 빌드 파이프라인에서 스크립트 단계를 사용하여 서비스 연결에 액세스하는 방법을 찾을 수 없습니다.예를 들어 Azure 서비스 주체의 자격 증명을 나타내는 서비스 연결이 있다고 가정합니다.스크립트 단계에서 해당 자격 증명에 액세스하고 싶습니다.

이들을 활용한 스크립트 스텝은 어떻게 작성해야 합니까?

서비스 연결에는 연결된 서비스에만 적용되는 데이터가 포함되므로(일반 서비스 연결은 규칙을 증명하는 예외임) Bash 태스크에서 강력한 유형의 속성을 사용할 수 없습니다.대신 환경 변수를 검토하고 서비스 연결 데이터를 수동으로 처리할 수 있습니다.

Azure DevOps 저장소의 작업 중 일부를 조사한 결과 서비스 연결 및 해당 데이터가 빌드 태스크를 실행하는 에이전트의 환경 변수로 채워진 것으로 보입니다.서비스 접속은 지정된 방법을 통해 취득됩니다.name에 다음 regex를 문자열로 합니다.

process.env[name.replace(/\./g, '_').toUpperCase()];

다양한 Service Endpoint 데이터의 취득은 vsts-task-lib/task 모듈에 포함되어 있기 때문에 소비량이 많은 태스크는 다음과 같은 코드를 쓸 수 있습니다.

taskLib.getEndpointAuthorization('SYSTEMVSSCONNECTION', false);

taskLib.getEndpointDataParameter('MYSERVICECONNECTION', 'SOME_PARAMETER_NAME', false);

taskLib.getEndpointUrl('MYSERVICECONNECTION', false) // <-- last param indicates required or not

따라서 추가 커스터마이즈 없이 bash 스크립트로 서비스 연결에 액세스하려면 다음을 권장합니다.

a)a) 정보의 합니다.a )는 환경변수를 설정합니다.system.debug환경 변수입니다.않은 을 사용하여 " 징후가 연결 빌드 해야 할 .따라서 사용하는 서비스 연결 이름을 입력하는 커스텀 빌드 태스크를 생성해야 할 수 있습니다.

b) 위의 bash 스크립트에서 설명한 대로 변수에서 원하는 값을 읽습니다.서비스 접속 변수명은 다음과 같이 계산할 수 있습니다.

   var dataParam = getVariable('ENDPOINT_DATA_' + id + '_' + key.toUpperCase());  

데이터 스키마/구조를 결정하려면 이 작업을 반복해야 할 수 있습니다.

저도 계속 궁금했어요.해결방법은 기본적인 '스크립트'(또는 'Bash') 태스크가 아닌 'Azure CLI' 태스크를 사용하는 것입니다.이것은 표면적으로는 Az CLI 명령어를 실행하기 위한 것이지만 표준 Bash 스크립트(또는 PSCore)만 실행할 수 있습니다.

이 작업을 실행할 때 존재하는 환경변수를 조사하면 'ENDPOINT_DATA_'가 앞에 붙은 변수에 서비스 연결에 대한 많은 정보가 표시됩니다.이것은 Josh E가 말했던 것과 일치한다.Azure 서브스크립션 ID, 이름, 서비스 원칙 객체 ID 등이 포함됩니다.

필요에 따라 서비스 원칙 세부 정보를 환경에 추가할 수도 있습니다.여기에는 SPN 키인 테넌트가 포함됩니다.비밀 환경변수로서의 ID 등

태스크는 다음과 같습니다.

- task: AzureCLI@2
  displayName: 'Azure CLI'
  inputs:
    scriptType: bash
    scriptLocation: inlineScript
    azureSubscription: '<Service Connection Name>'
    inlineScript: |
      env | sort

- task: AzureCLI@2
  displayName: 'Azure CLI, with SPN info'
  inputs:
    scriptType: bash
    scriptLocation: inlineScript
    azureSubscription: '<Service Connection Name>'
    addSpnToEnvironment: true
    inlineScript: |
      env | sort

물론 이 모든 것은 Azure Cloud Service Connections에만 해당됩니다.다른 서비스 커넥션에서도 사용할 수 있는 유사한 기술이 있을 수 있지만, 아직 조사하지 않았습니다.

bash Task를 실행하기 직전에 로그인하는 명령어와 함께 Kubectl 태스크를 사용하면 호스트 이름을 인증하거나 사용할 필요가 없습니다.

KUBERNETESNODE와 SERVICE PROTOCOL은 제가 선험적으로 설정한 파이프라인 변수입니다.

      - task: Kubernetes@1
        displayName: 'Kubernetes Login'
        # This is needed to run kubectl command from bash.
        inputs:
          connectionType: 'Kubernetes Service Connection'
          kubernetesServiceEndpoint: '<Service Connection Name>'
          command: 'login'

      - task: Bash@3
        displayName: 'Run Component Test'        
        inputs:
          targetType: 'inline'
          script: |
            #Get the Node Port
            nodePort=`kubectl get --namespace $(Build.BuildId) svc <service name> -o=jsonpath='{.spec.ports[0].nodePort}'`
            #Run Newman test
            newman run postman/Service.postman_collection.json --global-var host=$KUBERNETESNODE --global-var protocol=$SERVICEPROTOCOL --global-var port=$nodePort -r junit

스크립트/툴에서 ARM 배치와 동일한 서비스 연결을 사용하고 있습니다.

변수를 내보내기 위해 다음 템플릿을 만들었습니다.

parameters:
- name: azureSubscription
  type: string
- name: exportAsOutput
  type: boolean
  default: false
  
steps:  
- task: AzureCLI@2
  name: exported_azure_credentials
  displayName: 'Export Azure Credentials'
  inputs:
    azureSubscription: '${{ parameters.azureSubscription }}'
    scriptType: pscore
    scriptLocation: inlineScript
    addSpnToEnvironment: true
    ${{ if eq(parameters.exportAsOutput, true) }}:
      inlineScript: |
        Write-Host "##vso[task.setvariable variable=AZURE_TENANT_ID]$env:tenantId"
        Write-Host "##vso[task.setvariable variable=AZURE_TENANT_ID;isOutput=true]$env:tenantId"
        Write-Host "##vso[task.setvariable variable=AZURE_CLIENT_ID]$env:servicePrincipalId"
        Write-Host "##vso[task.setvariable variable=AZURE_CLIENT_ID;isOutput=true]$env:servicePrincipalId"
        Write-Host "##vso[task.setvariable variable=AZURE_CLIENT_SECRET]$env:servicePrincipalKey"
        Write-Host "##vso[task.setvariable variable=AZURE_CLIENT_SECRET;isOutput=true]$env:servicePrincipalKey"
    ${{ if eq(parameters.exportAsOutput, false) }}:
      inlineScript: |
        Write-Host "##vso[task.setvariable variable=AZURE_TENANT_ID]$env:tenantId"
        Write-Host "##vso[task.setvariable variable=AZURE_CLIENT_ID]$env:servicePrincipalId"
        Write-Host "##vso[task.setvariable variable=AZURE_CLIENT_SECRET]$env:servicePrincipalKey"

DevOps는 비밀에 대해 매우 영리하기 때문에 파이프라인 로그에 나타나지 않습니다.

다른 사용자가 말했듯이 스크립트를 사용하여 서비스 연결에 액세스할 수 있는 좋은 기본 제공 방법은 없습니다.장기간의 환경변수(보안 및 게으름)를 통해 자격정보를 공개하는 회피책이 마음에 들지 않기 때문에 커스텀스크립트를 사용하여 범용 서비스 접속을 이용할 수 있는 확장기능을 작성했습니다.https://marketplace.visualstudio.com/items?itemName=cloudpup.authenticated-scripts

이를 위해 서비스 접속을 단일 스크립트작업의 라이프타임 동안만 지속되는 환경변수로 공개합니다.

서비스 연결 변수 환경 변수
url AS_SC_URL
사용자 이름 AS_SC_USERNAME
패스워드 AS_SC_PASSWORD

환경변수로 노출된 서비스 연결을 보여주는 스크린샷

이 확장에 포함된 작업을 통해 다음과 같은 간결한 파이프라인을 작성할 수 있습니다.

steps:
- task: AuthenticatedPowerShell@1  
  inputs:
    serviceConnection: 'Testing Authenticated Shell'
    targetType: inline
    script: 'Write-Host "url: $env:AS_SC_URL | username: $env:AS_SC_USERNAME | password: $env:AS_SC_PASSWORD"'

네, 저는 항상 이 방법을 사용합니다. 먼저 자격 증명을 환경 변수로 출력하는 작업이 필요합니다. 그런 다음 태스크가 출력하는 환경 변수에서 자체 변수를 만듭니다. 저는 보통 AzureCLI를 사용합니다.

# Set Variables.
- task: AzureCLI@2
  name: setVariables
  displayName: Set Output Variables
  continueOnError: false
  inputs:
    azureSubscription: nameOfAzureServiceConnection
    scriptType: ps
    scriptLocation: inlineScript
    addSpnToEnvironment: true # this must be set to true
    inlineScript: |
      Write-Host "##vso[task.setvariable variable=azureClientId;isOutput=true]$($env:servicePrincipalId)"
      Write-Host "##vso[task.setvariable variable=azureClientSecret;isOutput=true]$($env:servicePrincipalKey)"
      Write-Host "##vso[task.setvariable variable=azureTenantId;isOutput=true]$($env:tenantId)"

그런 다음 아래 단계에서 설정한 이러한 새 변수를 사용할 수 있습니다. 작업 이름을 사용하여 변수를 호출해야 합니다. 따라서 $(taskName.variableName) 다음 예제에서는 새로운 변수를 사용하여 Terraform이 인증에 사용할 새로운 PowerShell 작업에서 환경 변수를 설정합니다.

- PowerShell: |
     terraform plan -input=false -out=tfplan
 displayName: 'Terraform Plan'
 env:
   ARM_CLIENT_ID: $(setVariables.azureClientId)
   ARM_CLIENT_SECRET: $(setVariables.azureClientSecret)
   ARM_TENANT_ID: $(setVariables.azureTenantId)

참조: https://jimferrari.com/2021/11/15/access-azure-service-connection-via-script/

서비스 연결을 사용하여 다른 서비스/리소스에 대한 인증을 받아야 하는 경우 서비스 연결과 함께 필요한 토큰을 가져와 다음과 같이 서비스 연결을 직접 사용할 수 없는 스크립트에 전달할 수도 있습니다.

- task: AzurePowerShell@5
  inputs:
    azureSubscription: 'AzureServiceConnection'
    ScriptType: 'InlineScript'
    Inline: |
      $token = Get-AzAccessToken 
      echo "##vso[task.setvariable variable=accesstoken;]$($token.Token)"
    azurePowerShellVersion: 'LatestVersion'
  
- script: 'echo This is the token: $(accesstoken)'

언급URL : https://stackoverflow.com/questions/57234110/how-can-a-script-access-service-connections-azure-devops-pipelines

반응형