Update GitHub pipelines for generic federated credential support (#133)

* added examples for oidc aad integration

* initial commit

* update comments

* update
This commit is contained in:
Johan Dahlbom 2023-02-15 19:27:35 +01:00 коммит произвёл GitHub
Родитель 3186b248db
Коммит 49ccc7667f
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
9 изменённых файлов: 83 добавлений и 501 удалений

20
.github/actions/sharedSteps/action.yml поставляемый
Просмотреть файл

@ -25,7 +25,7 @@ runs:
- name: Cache AzOps module
if: ${{ env.MODULE_VERSION != '' }}
id: cache-AzOps
uses: actions/cache@v2
uses: actions/cache@v3
with:
path: ${{ env.modulesFolder }}
key: '"AzOpsModule" | ${{ env.MODULE_VERSION }}'
@ -59,11 +59,25 @@ runs:
run: |
$Env:PSModulePath = $Env:PSModulePath, '${{ env.modulesFolder }}' -join [IO.Path]::PathSeparator
$azParams = @{
Credential = (New-Object PSCredential -ArgumentList '${{env.ARM_CLIENT_ID}}', (ConvertTo-SecureString -String '${{env.ARM_CLIENT_SECRET}}' -AsPlainText -Force))
SubscriptionId = '${{env.ARM_SUBSCRIPTION_ID}}'
TenantId = '${{env.ARM_TENANT_ID}}'
}
if ('${{env.ARM_ENVIRONMENT}}' -in (Get-AzEnvironment).Name) {
$azParams.Environment = '${{env.ARM_ENVIRONMENT}}'
}
Connect-AzAccount -ServicePrincipal @azParams
# Use Service Principal if ARM_CLIENT_ID is set
if ('${{env.ARM_CLIENT_ID}}') {
# Use federated credentials if token and no secret exists
if ($ENV:ACTIONS_ID_TOKEN_REQUEST_TOKEN -and -not '${{env.ARM_CLIENT_SECRET}}') {
$url = "{0}&audience=api://AzureADTokenExchange" -f $ENV:ACTIONS_ID_TOKEN_REQUEST_URL
$federatedJwt = Invoke-RestMethod -Uri $url -Headers @{Authorization = "Bearer $ENV:ACTIONS_ID_TOKEN_REQUEST_TOKEN"}
$azParams.ApplicationId = '${{env.ARM_CLIENT_ID}}'
$azParams.FederatedToken = [System.Net.WebUtility]::UrlEncode($federatedJwt.Value)
} else {
$azParams.Credential = (New-Object PSCredential -ArgumentList '${{env.ARM_CLIENT_ID}}', (ConvertTo-SecureString -String '${{env.ARM_CLIENT_SECRET}}' -AsPlainText -Force))
}
Connect-AzAccount -ServicePrincipal @azParams
} else {
# Connect with Managed Identity
Connect-AzAccount -Identity @azParams
}

3
.github/samples/oidc-azuread/README.md поставляемый
Просмотреть файл

@ -1,3 +0,0 @@
This folder contains examples on how to leverage Federated workload credentials in Azure AD with AzOps/GitHub Actions.
Instruction on how to configure the service principal in Azure AD can be found at https://github.com/azure/azops/wiki/github-oidc

258
.github/samples/oidc-azuread/pull.yml поставляемый
Просмотреть файл

@ -1,258 +0,0 @@
---
name: "AzOps - Pull"
on:
#
# Workflow Dispatch
# This is to invoke the action from the GitHub UI
#
workflow_dispatch:
#
# Repository Dispatch
# Invoke this action based on event / webhook, this
# could be from an activity logs when a specific condition
# is met and triggered
#
repository_dispatch:
types:
- "Enterprise-Scale Deployment"
- "Enterprise-Scale Event"
#
# Schedule
# This is an optional trigger to pull the latest Azure
# hierarchy into the Git repository in a recurring
# manner.
#
# Default: Every 6 hours
#
schedule:
- cron: "0 */6 * * *"
#
# Workflow Run
# Triggers this workflow upon the completion of
# the Push action.
#
workflow_run:
workflows: ["AzOps - Push"]
branches: [main]
types:
- completed
permissions:
id-token: write
contents: write
pull-requests: write
env:
#
# Credentials
#
ARM_CLIENT_ID: ${{ secrets.ARM_CLIENT_ID }}
ARM_TENANT_ID: ${{ secrets.ARM_TENANT_ID }}
ARM_SUBSCRIPTION_ID: ${{ secrets.ARM_SUBSCRIPTION_ID }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
#
# Folder Name
# By default we generate the hierachy within the
# 'azops' folder within the root of the repository.
# If this property is modified, the config value within
# the settings.json file - Core.State will also need
# to be changed.
#
# Default: root
#
folder: "root"
#
# Branch Name
# As part of the Pull workflow we check a temporary branch
# this branch was previously know as system, this value can
# be changed if this name is already reserved for other systems
# within the repository.
#
# Default: automated
#
branch: "automated"
#
# Commit Message
# During the Pull workflow, the changes are commited to the
# temporary branch, the message which is applied within the
# Git history can be changed as needed.
#
# Default: Automated commit
#
commit_message: "Automated commit"
#
# Pull Request
# The generated Pull Request for the Pull workflow can be
# modified to help indicate when changes we're merged in the
# Git history.
#
# Default: Automated state
#
pull_request: "Automated State"
jobs:
pull:
#
# Pull
#
name: "Pull"
runs-on: ubuntu-20.04
environment: prod
#
# Only run Pull after successful Push or on manually triggered/scheduled events
#
if: ${{ github.event.workflow_run.conclusion == 'success' ||
contains(fromJson('["schedule", "workflow_dispatch", "repository_dispatch"]'), github.event_name) }}
steps:
#
# Checkout
# Checks-out the repository
#
- name: "Checkout"
uses: actions/checkout@v3
with:
fetch-depth: 0
#
# Configure
# Set global options
#
- name: "Configure"
shell: bash
run: |
git config user.name github-actions
git config user.email '41898282+github-actions[bot]@users.noreply.github.com'
#
# Checkout
# Switch branches
#
- name: "Checkout"
shell: bash
run: |
git checkout -b ${{ env.branch }}
#
# Dependencies
# Install required runtime modules
#
- name: "Dependencies"
shell: pwsh
run: |
Install-Module -Name "AzOps" -Force
# Connect
# Authenticate Azure context
#
- name: OIDC Login to Azure Public Cloud with AzPowershell (enableAzPSSession true)
uses: azure/login@v1
with:
client-id: ${{ env.ARM_CLIENT_ID}}
tenant-id: ${{ env.ARM_TENANT_ID }}
subscription-id: ${{ env.ARM_SUBSCRIPTION_ID }}
enable-AzPSSession: true
#
# Initialize
# Generate new state data
#
- name: "Initialize"
shell: pwsh
run: |
Import-PSFConfig -Path settings.json -Schema MetaJson -EnableException
if ($env:ACTION -eq "Enterprise-Scale Deployment") {
Set-PSFConfig -FullName AzOps.Core.SkipResource -Value $false
}
Invoke-AzOpsPull -Rebuild
Get-Job | Remove-Job -Force
env:
ACTION: ${{ github.event.action }}
#
# Status
# Check for data changes
#
- name: "Status"
id: status
shell: bash
run: |
STATUS=$(git status --short)
echo $STATUS
if [ -z "$STATUS" ]
then
echo "state=stop" >> $GITHUB_OUTPUT
else
echo "state=continue" >> $GITHUB_OUTPUT
fi
#
# Add
# Add file content to index
#
- name: "Add"
if: steps.status.outputs.state == 'continue'
run: |
git add "./${{ env.folder }}"
shell: bash
#
# Commit
# Record changes to the repository
#
- name: "Commit"
if: steps.status.outputs.state == 'continue'
shell: bash
run: |
git commit -m "${{ env.commit_message }}"
#
# Push
# Update remote refs along with associated objects
#
- name: "Push"
if: steps.status.outputs.state == 'continue'
shell: bash
run: |
git push origin ${{ env.branch }} -f
#
# Merge
# Automatically merge the head branch into base
#
- name: "Merge"
if: steps.status.outputs.state == 'continue'
shell: bash
run: |
gh pr create --title "${{ env.pull_request }}" --body "-" --base 'main' --head ${{ env.branch }}
gh pr merge "${{ env.branch }}" --squash --delete-branch

113
.github/samples/oidc-azuread/push.yml поставляемый
Просмотреть файл

@ -1,113 +0,0 @@
---
name: "AzOps - Push"
on:
#
# Push
# Automated workflow trigger when a merge
# commit enters the main branch.
#
push:
branches:
- main
paths:
- "root/**"
permissions:
id-token: write
contents: write
pull-requests: write
env:
#
# Credentials
#
ARM_CLIENT_ID: ${{ secrets.ARM_CLIENT_ID }}
ARM_TENANT_ID: ${{ secrets.ARM_TENANT_ID }}
ARM_SUBSCRIPTION_ID: ${{ secrets.ARM_SUBSCRIPTION_ID }}
jobs:
push:
#
# Push
#
name: "Push"
runs-on: ubuntu-20.04
environment: prod
steps:
#
# Checkout
# Checks-out the repository
#
- name: "Checkout"
uses: actions/checkout@v3
with:
fetch-depth: 0
#
# Dependencies
# Install required runtime modules
#
- name: "Dependencies"
shell: pwsh
run: |
Install-Module -Name "AzOps" -Force
#
# Connect
# Authenticate Azure context
#
- name: OIDC Login to Azure Public Cloud with AzPowershell (enableAzPSSession true)
uses: azure/login@v1
with:
client-id: ${{ env.ARM_CLIENT_ID}}
tenant-id: ${{ env.ARM_TENANT_ID }}
subscription-id: ${{ env.ARM_SUBSCRIPTION_ID }}
enable-AzPSSession: true
#
# Diff
# List index changes
#
- name: "Diff"
shell: bash
run: |
if [ ! -z "$(git diff --name-status HEAD^ HEAD)" ]; then
echo $(git diff --name-status HEAD^ HEAD)
git diff --name-status HEAD^ HEAD > /tmp/diff.txt
if [ ! -z "$(git diff --diff-filter=D HEAD^ HEAD)" ]; then
echo $(git diff --diff-filter=D HEAD^ HEAD --no-prefix | grep ^- | sed -r "s/^([^-+ ]*)[-+ ]/\\1/" | less -r)
git diff --diff-filter=D HEAD^ HEAD --no-prefix | grep ^- | sed -r "s/^([^-+ ]*)[-+ ]/\\1/" | less -r > /tmp/diffdeletedfiles.txt
fi
else
echo "The validation pipeline failed because there is currently no change to be processed"
exit 1
fi
#
# Deploy
# Initial deployment of any index changes
#
- name: "Deploy"
shell: pwsh
run: |
Initialize-AzOpsEnvironment
Import-PSFConfig -Path settings.json -Schema MetaJson -EnableException
$diff = Get-Content -Path /tmp/diff.txt
$module = Get-Module -Name AzOps
if(Test-Path -Path "/tmp/diffdeletedfiles.txt") {
$diffdeletedfiles = Get-Content -Path /tmp/diffdeletedfiles.txt
$module.Invoke({ Invoke-AzOpsPush -ChangeSet $diff -DeleteSetContents $diffdeletedfiles })
}
else {
$module.Invoke({ Invoke-AzOpsPush -ChangeSet $diff })
}
Get-Job | Remove-Job -Force

123
.github/samples/oidc-azuread/validate.yml поставляемый
Просмотреть файл

@ -1,123 +0,0 @@
---
name: "AzOps - Validate"
on:
#
# Pull Request
# Upon the creation of a new Pull Request in the root folder
# this workflow will execute.
#
pull_request:
paths:
- "root/**"
env:
#
# Credentials
#
ARM_CLIENT_ID: ${{ secrets.ARM_CLIENT_ID }}
ARM_TENANT_ID: ${{ secrets.ARM_TENANT_ID }}
ARM_SUBSCRIPTION_ID: ${{ secrets.ARM_SUBSCRIPTION_ID }}
permissions:
id-token: write
contents: write
pull-requests: write
jobs:
validate:
#
# Validate
#
name: "Validate"
runs-on: ubuntu-20.04
environment: prod
steps:
#
# Checkout
# Checks-out the repository
#
- name: "Checkout"
uses: actions/checkout@v3
with:
fetch-depth: 0
#
# Dependencies
# Install required runtime modules
#
- name: "Dependencies"
shell: pwsh
run: |
Install-Module -Name "AzOps" -Force
#
# Connect
# Authenticate Azure context
#
- name: OIDC Login to Azure Public Cloud with AzPowershell (enableAzPSSession true)
uses: azure/login@v1
with:
client-id: ${{ env.ARM_CLIENT_ID}}
tenant-id: ${{ env.ARM_TENANT_ID }}
subscription-id: ${{ env.ARM_SUBSCRIPTION_ID }}
enable-AzPSSession: true
#
# Diff
# List index changes
#
- name: "Diff"
id: diff
shell: bash
run: |
if [ ! -z "$(git diff --name-status HEAD^ HEAD)" ]; then
echo $(git diff --name-status HEAD^ HEAD)
git diff --name-status HEAD^ HEAD > /tmp/diff.txt
if [ ! -z "$(git diff --diff-filter=D HEAD^ HEAD)" ]; then
echo $(git diff --diff-filter=D HEAD^ HEAD --no-prefix | grep ^- | sed -r "s/^([^-+ ]*)[-+ ]/\\1/" | less -r)
git diff --diff-filter=D HEAD^ HEAD --no-prefix | grep ^- | sed -r "s/^([^-+ ]*)[-+ ]/\\1/" | less -r > /tmp/diffdeletedfiles.txt
fi
else
echo "The validation pipeline failed because there is currently no change to be processed"
exit 1
fi
#
# Validate
#
- name: "Validate"
shell: pwsh
run: |
Initialize-AzOpsEnvironment
Import-PSFConfig -Path settings.json -Schema MetaJson -EnableException
$diff = Get-Content -Path /tmp/diff.txt
$module = Get-Module -Name AzOps
if(Test-Path -Path "/tmp/diffdeletedfiles.txt")
{
$diffdeletedfiles = Get-Content -Path /tmp/diffdeletedfiles.txt
$module.Invoke({ Invoke-AzOpsPush -ChangeSet $diff -DeleteSetContents $diffdeletedfiles -WhatIf })
}
else{
$module.Invoke({ Invoke-AzOpsPush -ChangeSet $diff -WhatIf })
}
Get-Job | Remove-Job -Force
#
# Results
#
- name: "Results"
shell: bash
run: |
gh pr comment ${{ github.event.pull_request.number }} --body-file /tmp/OUTPUT.md
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

18
.github/workflows/pull.yml поставляемый
Просмотреть файл

@ -44,7 +44,16 @@ on:
workflows: ["AzOps - Push"]
branches: [main]
types:
- completed
- completed
#
# Permissions required for the pipeline to interact with repo and federated credentials
#
permissions:
id-token: write
contents: write
pull-requests: write
env:
#
@ -123,6 +132,13 @@ jobs:
name: "Pull"
runs-on: ubuntu-20.04
#
# Environment if using Federated Credentials
# https://github.com/azure/azops/wiki/github-oidc
#
# environment: prod
#
# Only run Pull after successful Push or on manually triggered/scheduled events

16
.github/workflows/push.yml поставляемый
Просмотреть файл

@ -14,7 +14,16 @@ on:
- main
paths:
- 'root/**'
#
# Permissions required for the pipeline to interact with repo and federated credentials
#
permissions:
id-token: write
contents: write
pull-requests: write
env:
#
@ -48,6 +57,13 @@ jobs:
name: "Push"
runs-on: ubuntu-20.04
#
# Environment if using Federated Credentials
# https://github.com/azure/azops/wiki/github-oidc
#
# environment: prod
steps:
#

16
.github/workflows/redeploy.yml поставляемый
Просмотреть файл

@ -15,6 +15,15 @@ on:
description: 'Path with templates that will be deployed'
required: true
#
# Permissions required for the pipeline to interact with repo and federated credentials
#
permissions:
id-token: write
contents: write
pull-requests: write
env:
#
@ -66,6 +75,13 @@ jobs:
name: "Redeploy"
runs-on: ubuntu-20.04
#
# Environment if using Federated Credentials
# https://github.com/azure/azops/wiki/github-oidc
#
# environment: prod
steps:
#

17
.github/workflows/validate.yml поставляемый
Просмотреть файл

@ -11,6 +11,15 @@ on:
pull_request:
paths:
- "root/**"
#
# Permissions required for the pipeline to interact with repo and federated credentials
#
permissions:
id-token: write
contents: write
pull-requests: write
env:
#
@ -41,6 +50,14 @@ jobs:
name: "Validate"
runs-on: ubuntu-20.04
#
# Environment if using Federated Credentials
# https://github.com/azure/azops/wiki/github-oidc
#
# environment: prod
steps:
#