Merge pull request #49 from Azure/gc-build-github-action

Add GH action and docs for GC build
This commit is contained in:
Nick Price 2022-02-16 00:23:52 +11:00 коммит произвёл GitHub
Родитель 16d5c1d648 f60aca574f
Коммит b214641cc7
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 166 добавлений и 68 удалений

140
.github/workflows/build-gc-policy.yml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,140 @@
name: Build Guest Configuration policies
on:
workflow_dispatch:
inputs:
subscriptionId:
description: 'Subscription Id'
required: true
resourceGroup:
description: 'Resource group'
required: true
storageAccountName:
description: 'Storage account name'
required: true
storageAccountContainer:
description: 'Storage account container'
required: true
default: 'guest-configuration'
jobs:
Compile-Guest-Configuration:
runs-on: windows-2022
steps:
- name: Clone repo
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Login to Azure
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
enable-AzPSSession: true
- name: Set Azure subscription
uses: Azure/powershell@v1
with:
inlineScript: Set-AzContext -SubscriptionId ${{ github.event.inputs.subscriptionId }}
azPSVersion: latest
- name: Build and publish guest configuration policies
shell: pwsh
run: |
#Gather inputs
$GcPolStorageAccountRg = "${{ github.event.inputs.resourceGroup }}"
$GcPolStorageAccountName = "${{ github.event.inputs.storageAccountName }}"
$GcPolStorageAccountContainer = "${{ github.event.inputs.storageAccountContainer }}"
#Prepare runner with prereqs
Install-Module -Name GuestConfiguration -RequiredVersion 3.5.4 -AllowClobber -Force
#Identify DSC configurations
Set-Location .\guest-configuration\
$GcPolFilePathString = (Get-Item ".")
$GcPolFilePath = Get-item $GcPolFilePathString
$PSFiles = $GcPolFilePath.GetFiles("*.ps1")
$PSFiles | ForEach-Object {
$DscShortName = $_.Basename
if (Test-Path ($DscShortName + ".json")) {
#Load the guest configuration metadata (accompanying json file) and install associated DSC modules
$GcPolicyMetadata = Get-Content ($DscShortName + ".json") | ConvertFrom-Json -AsHashtable
#Load any policy-specific DSC modules
if ($GcPolicyMetadata.ContainsKey("DscModules")) {
$GcPolicyMetadata.DscModules | ForEach-Object {Install-Module $_ -Force; Import-Module $_ -Force}
}
#Compile the DSC to MOF
& ($_.FullName)
#Build and publish new guest configuration package to storage account
New-GuestConfigurationPackage -Name $DscShortName -Configuration ($GcPolFilePath.FullName + "\" + $DscShortName + "\localhost.mof") -Path Packages -Force
$ContentUri = Publish-GuestConfigurationPackage -Path ($GcPolFilePath.FullName + "\Packages\" + $DscShortName + "\" + $DscShortName + ".zip") -ResourceGroupName $GcPolStorageAccountRg -StorageAccountName $GcPolStorageAccountName -StorageContainerName $GcPolStorageAccountContainer -Force
#Create guest configuration policy file
New-GuestConfigurationPolicy `
-PolicyID (New-Guid).Guid `
-ContentUri $ContentUri.ContentUri `
-DisplayName $GcPolicyMetadata.DisplayName `
-Description $GcPolicyMetadata.Description `
-Path ($GcPolFilePath.FullName + '\policiestemp') `
-Platform $GcPolicyMetadata.Platform `
-Version $GcPolicyMetadata.Version `
-Parameter $GcPolicyMetadata.PolicyParameters `
#Load guest configuration policy file and apply custom transforms
#This adjusts some of the targeting
$GcPolicy = Get-Content ($GcPolFilePath.FullName + "\policiestemp\AuditIfNotExists.json" )
$GcPolicy = $GcPolicy.Replace("[parameters('IncludeArcMachines')]","[[parameters('IncludeArcMachines')]") #apply nested parameter escape
$GcPolicy = $GcPolicy | ConvertFrom-Json
if ($GcPolicyMetadata.keys -contains "PlatformVersion") { #Apply PlatformVersion-specific transforms
$GcPolicy.properties.policyrule.if.anyof[0].allof += New-Object -TypeName pscustomobject
Add-Member -InputObject $GcPolicy.properties.policyrule.if.anyof[0].allof[2] -MemberType NoteProperty -Name field -Value "Microsoft.Compute/virtualMachines/storageProfile.imageReference.id"
switch ($GcPolicyMetadata.PlatformVersion) {
"Server 2016" { Add-Member -InputObject $GcPolicy.properties.policyrule.if.anyof[0].allof[2] -MemberType NoteProperty -Name contains -Value "images/WindowsServer2016SOE" }
"Server 2019" { Add-Member -InputObject $GcPolicy.properties.policyrule.if.anyof[0].allof[2] -MemberType NoteProperty -Name contains -Value "images/WindowsServer2019SOE" }
"Server 2022" { Add-Member -InputObject $GcPolicy.properties.policyrule.if.anyof[0].allof[2] -MemberType NoteProperty -Name contains -Value "images/WindowsServer2022SOE" }
Default {}
}
}
if ($GcPolicyMetadata.keys -contains "PolicyParameters") { #Apply PolicyParameters-specific transforms
$gcpolicy.properties.policyrule.then.details.existencecondition.allof[1].equals = "[" + $gcpolicy.properties.policyrule.then.details.existencecondition.allof[1].equals
}
#Cleanup
Remove-Item ($GcPolFilePath.FullName + "\" + $DscShortName) -Recurse -Force
Remove-Item ($GcPolFilePath.FullName + "\Packages") -Recurse -Force
Remove-item ($GcPolFilePath.FullName + "\policiestemp") -Recurse -Force
#Construct ARM template from guest configuration policy
if ((Test-Path ($GcPolFilePath.Parent.FullName + "\policies\" + $GcPolicyMetadata.PolicyPath)) -eq $false) {New-Item ($GcPolFilePath.Parent.FullName + "\policies\" + $GcPolicyMetadata.PolicyPath) -ItemType Directory}
$ArmTemplate = [ordered]@{
"`$schema"="https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#";
"contentVersion"="1.0.0.0";
"parameters"=@{"policyName"=@{"type"="string"}};
"resources"=@(
[ordered]@{
"type"="Microsoft.Authorization/policyDefinitions";
"name"="[parameters('policyName')]";
"apiVersion"="2019-09-01"
}
);
"outputs"=@{
"policyDefinitionId"=@{
"type"="string";
"value"= "[resourceId('Microsoft.Authorization/policyDefinitions',parameters('policyName'))]"
}
}
}
$ArmTemplate["resources"][0] += @{"properties"=$GcPolicy.properties}
$ArmTemplate | ConvertTo-Json -depth 100 | Set-Content -Path ($GcPolFilePath.Parent.FullName + "\policies\" + $GcPolicyMetadata.PolicyPath + "\policy.template.json")
}
}
- name: Commit and push policy ARM templates
run: |
git config user.name github-actions
git config user.email github-actions@github.com
git add policies/*/*.json
git commit -m "Compiled GC policies (GH actions)"
git push

Просмотреть файл

@ -192,84 +192,42 @@ Ensure you have prepared the following items:
The CloudSOE ARM templates rely on published Guest Configuration packages. These packages must be build and uploaded to Azure storage. Policy ARM templates also need to be generated by you, as they contain a unique hash based on the packages generated in this step.
These instructions have been updated to use GitHub Actions for this build step to simplify environment setup.
- __Fork the Azure/ausgovcaf-cloudsoe repo__
Due to the use of linked ARM templates, and template that are generated unique to your deployment, the best option to get started is to deploy from your own GitHub repo. Start by forking this repository.
- __Clone the new repo locally__
- __Create an Azure Service Principal and associated GitHub secret__
This is in preparation of the Guest Configuration package build. We recommend you deploy a temporary VM for this step. We have tested with the following software configuration:
GitHub Actions will require access to your Azure storage account in order to publish Guest Configuration policies. In this step, we need to create a service princpal which has access to the storage account, before then storing the related secrets as GitHub secrets.
- Windows Server 2019 OS
- [Powershell 7.1](https://docs.microsoft.com/en-us/powershell/scripting/install/installing-powershell-core-on-windows?view=powershell-7.1)
- [GuestConfiguration PowerShell module](https://www.powershellgallery.com/packages/GuestConfiguration)
- [Git](https://git-scm.com/download/win)
Use the Azure CLI, or cloud shell to create the service princplal as per [these instructions](https://github.com/marketplace/actions/azure-login#configure-a-service-principal-with-a-secret). Grant the service principal the Contributor role to the storage accounts resource group.
Use the following command to clone the repo:
> git clone https://github.com/yourgithubaccount/ausgovcaf-cloudsoe.git
- __Compile and upload the Guest Configuration packages__
Sign in the to the account that has the equivalent of _Storage Blob Data Contributor_ access to the Guest Configuration package storage account:
```powershell
Connect-AzAccount
Select-AzSubscription xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
```
az ad sp create-for-rbac --name "CloudSOEGCPolicyBuild" --role contributor --scopes /subscriptions/{subscription-id}/resourceGroups/{resource-group} --sdk-auth
```
We have provided a sample script which automates the compilation and publication of Guest Configurations, as well as the generation of ARM templates for the associated policyDefinition.
The ```Compile-CloudSOEGcPolicies.ps1``` file is located in the ```<root>\guest-configuration``` folder and when run will:
1. Compile all guest configuration policies in the .\guest-configuration\ folder
1. Build and upload the guest configuration packages to a storage account blob container
1. Create the azure policy guest configuration policy definition template
1. Remove all temporary files
Run the ```Compile-CloudSOEGcPolicies.ps1``` file with parameters
```powershell
.\Compile-CloudSOEGcPolicies.ps1 -GcPolFilePathString . -GcPolStorageAccountRg cloudsoe-rg -GcPolStorageAccountName cloudsoegcpol -GcPolStorageAccountContainer guest-config -Verbose
```
---
Parameter: `GcPolFilePathString`
Describes the ARM management group / subscription location where the prototype policy definitions and assignments will be created.
---
Parameter: `GcPolStorageAcccountRg`
This is the resource group of the storage account where Guest Configuration packages will be published.
---
Parameter: `GcPolStorageAccountName`
This is the name of the storage account where Guest Configuration packages will be published.
---
Parameter: `GcPolStorageAccountContainer`
This is the storage container in the storage account where Guest Configuration packages will be published.
---
- __Add, commit and push the new policy template files to your forked repo__
The previous step will have generated a number of ARM templates in /policies. These templates will be deployed as linked deployments by ```arm-cloudsoe-policy-baseline.json```
Follow [these instructions](https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository) to create your GitHub secret. The secret name must be named _AZURE_CREDENTIALS_. The contents of the secret should be the json object returned by the creation of the service principal.
```
git add .
git commit -m "Created policy templates"
git push
```
Your repo should contain the updated guest configuration policy files ready to be referenced by the linked deployments.
- __Initiate the Guest Configuration policy build__
In your forked repo, select the Actions menu. Locate and select the workflow named _Build Guest Configuration policies_.
Click _Run Workflow_. You will be prompted for four parameters:
- __Subscription ID__: This is the ID of the subscription of the storage account which will hold the guest configuration packages.
- __Resource group__: This is the resource group name of the storage account which will hold the guest configuration packages.
- __Storage account name__: This is the storage account which will hold the guest configuration packages.
- __Storage account container__: This is the blob container which will hold the guest configuration packages.
Once these parameters are populated, click _Run workflow_.
- __Confirm workflow success__
Once the workflow successfully completes, two changes should be apparent:
- The Guest Configuration packages should be present in the storage account container
- The generated guest configuration policies should be present in /policies/ path
## Prepare your inputs for deploying the SOE code