Merge pull request #49 from Azure/gc-build-github-action
Add GH action and docs for GC build
This commit is contained in:
Коммит
b214641cc7
|
@ -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
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче