Skip to content

Commit 4020d9c

Browse files
Merge pull request #5 from devopsabcs-engineering/main
Additional changes for workshop
2 parents 2de1d04 + 4391ffe commit 4020d9c

16 files changed

Lines changed: 1489 additions & 6 deletions

.github/workflows/deploy-aks-construction.yml

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,32 @@ on:
44
workflow_dispatch:
55

66
permissions:
7-
id-token: write
8-
contents: read
7+
id-token: write #This is required for requesting the JWT
8+
contents: write # This is required to create/push the new git tag
99

1010
jobs:
11+
create_resource_group_job:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v4
15+
with:
16+
fetch-depth: 0
17+
- name: Login to Azure
18+
uses: azure/login@v2
19+
with:
20+
client-id: ${{ secrets.AZURE_CLIENT_ID }}
21+
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
22+
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
23+
- name: Create Resource Group
24+
id: create_rg
25+
run: |
26+
az group create --name ${{ env.RESOURCE_GROUP_NAME }} --location ${{ env.LOCATION }}
27+
env:
28+
RESOURCE_GROUP_NAME: rg-k8s-pygoat-dev-001
29+
LOCATION: canadacentral
1130
reusable_workflow_job:
1231
uses: Azure/AKS-Construction/.github/workflows/AKSC_Deploy.yml@0.10.5
32+
needs: create_resource_group_job
1333
with:
1434
templateVersion: 0.10.5
1535
rg: rg-k8s-pygoat-dev-001

.github/workflows/oss_pygoat-devsecops-basic.yml

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,19 @@ on:
44
# branches:
55
# - main
66
workflow_dispatch:
7+
inputs:
8+
DEFECTDOJO_URL:
9+
description: 'DefectDojo URL'
10+
required: true
11+
default: 'https://defectdojo.cad4devops.com:8443/api/v2'
12+
DEFECTDOJO_COMMONUSER:
13+
description: 'DefectDojo Common User'
14+
required: true
15+
default: 'Student000'
16+
DEFECTDOJO_COMMONPRODUCTNAME:
17+
description: 'DefectDojo Common Product Name'
18+
required: true
19+
default: 'GitHub-OSS-pygoat-devsecops-workshop-002-product-000'
720

821
permissions:
922
# The permissions for azure federation
@@ -26,10 +39,10 @@ env:
2639
doImageScanWithDockerHubScout: false
2740
adjustDNS: false
2841
listArtifacts: true
29-
DEFECTDOJO_URL: https://defectdojo-002.cad4devops.com:8443/api/v2
30-
DEFECTDOJO_COMMONUSER: Student000
31-
DEFECTDOJO_COMMONPRODUCTNAME: GitHub-OSS-pygoat-devsecops-workshop-001-product-000
32-
DEFECTDOJO_TOKEN: ${{ secrets.DEFECTDOJO_TOKEN }}
42+
DEFECTDOJO_URL: ${{ inputs.DEFECTDOJO_URL }} #https://defectdojo-002.cad4devops.com:8443/api/v2
43+
DEFECTDOJO_COMMONUSER: ${{ inputs.DEFECTDOJO_COMMONUSER }} #Student000
44+
DEFECTDOJO_COMMONPRODUCTNAME: ${{ inputs.DEFECTDOJO_COMMONPRODUCTNAME }} #GitHub-OSS-pygoat-devsecops-workshop-001-product-000
45+
DEFECTDOJO_TOKEN: ${{ secrets.DEFECTDOJO_TOKEN }} # 8116113b49d62b5affe822be7cf260778c5f62b1
3346
appUrl: http://gh-pygoat-test.cad4devops.com
3447
containerName: owaspzapproxy
3548
doActiveScan: false

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ bin
1010
pygoatvenv/
1111
/.vs
1212
wrkshp-001-student-*
13+
__azurite_db_table__.json

New-Deployment.ps1

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
param (
2+
[Parameter()]
3+
[string]$nameSuffix = "ek005",
4+
[Parameter()]
5+
[string]$deploymentName = "deploy-rg-fnapp-$nameSuffix",
6+
[Parameter()]
7+
[string]$location = "canadacentral",
8+
[Parameter()]
9+
[string]$templateFile = "infra/main.bicep",
10+
[Parameter()]
11+
[string]$resourceGroupName = "rg-fnapp-$nameSuffix"
12+
)
13+
14+
# echo parameters
15+
Write-Host "deploymentName: $deploymentName"
16+
Write-Host "location: $location"
17+
Write-Host "templateFile: $templateFile"
18+
Write-Host "nameSuffix: $nameSuffix"
19+
Write-Host "resourceGroupName: $resourceGroupName"
20+
21+
# create resource group
22+
az group create --name $resourceGroupName `
23+
--location $location
24+
25+
az deployment group create --name $deploymentName `
26+
--resource-group $resourceGroupName `
27+
--template-file $templateFile `
28+
--parameters nameSuffix="$nameSuffix"

New-GitHubFederatedIdentity.ps1

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
param (
2+
[Parameter()]
3+
[string]
4+
$githubRepo = "devopsabcs-engineering/devsecops-workshop", #"<your-github-username>/<your-repo-name>"
5+
[Parameter()]
6+
[string]
7+
$subscriptionName = "IT Test", #"<your-subscription-id>"
8+
[Parameter()]
9+
[string]
10+
$tenantName = "devopsabcs.com" #"<your-tenant-id>"
11+
)
12+
13+
# get the display name from the repo name replacing the forward slash with a double underscore
14+
$displayName = "GH__" + $githubRepo -replace "/", "__"
15+
16+
Write-Output "Creating federated identity for $displayName in $githubRepo"
17+
18+
$subscriptionsWithTenants = az account list --query "[].{SubscriptionName:name, TenantId:tenantId}" -o json | ConvertFrom-Json
19+
$subscription = $subscriptionsWithTenants | Where-Object { $_.SubscriptionName -eq $subscriptionName }
20+
$tenantId = $subscription.TenantId
21+
22+
# get tenant id from tenant name
23+
Write-Output "Tenant ID: $tenantId"
24+
25+
# Login to Azure
26+
#az login --service-principal -u "<your-service-principal-id>" -p "<your-service-principal-secret>" --tenant $tenantId
27+
az login --tenant $tenantId
28+
29+
# set the default subscription
30+
az account set --subscription $subscriptionName
31+
32+
# get subscription id from subscription name
33+
$subscriptionId = az account show --query id -o tsv
34+
Write-Output "Subscription ID: $subscriptionId"
35+
36+
# echo parameters
37+
Write-Output "displayName: $displayName"
38+
Write-Output "githubRepo: $githubRepo"
39+
Write-Output "subscriptionName: $subscriptionName"
40+
Write-Output "subscriptionId: $subscriptionId"
41+
Write-Output "tenantName: $tenantName"
42+
Write-Output "tenantId: $tenantId"
43+
Write-Output "clientId: $clientId"
44+
45+
46+
# create azure credentials for the pipeline in github actions
47+
48+
# Create the federated service principal
49+
$sp = az ad sp create-for-rbac --name $displayName --role Contributor `
50+
--scopes /subscriptions/$subscriptionId `
51+
--query "{clientId: appId, clientSecret: password}" -o json | ConvertFrom-Json
52+
$clientId = $sp.clientId
53+
54+
# get object id from app registration
55+
$objectId = az ad app show --id $clientId --query id -o tsv
56+
Write-Output "Service principal object ID: $objectId"
57+
58+
59+
Write-Output "Service principal created."
60+
Write-Output "Client ID: $clientId"
61+
62+
# read credentials.json from file
63+
#$credentialRaw = Get-Content -Path "credential.json" -Raw
64+
$credentialRaw =
65+
@'
66+
{
67+
"name": "__CREDENTIAL_NAME__",
68+
"issuer": "https://token.actions.githubusercontent.com",
69+
"subject": "__SUBJECT__",
70+
"audiences": [
71+
"api://AzureADTokenExchange"
72+
]
73+
}
74+
'@
75+
76+
# find and replace the placeholders with the actual values
77+
$credential = $credentialRaw -replace "__CREDENTIAL_NAME__", $displayName -replace "__SUBJECT__", "repo:${githubRepo}:ref:refs/heads/main"
78+
79+
$appRegistrationJson = az ad app list --display-name "$displayName" -o json
80+
Write-Output "App Registration: $appRegistrationJson"
81+
$appRegistration = $appRegistrationJson | ConvertFrom-Json
82+
Write-Output "App Registration: $appRegistration"
83+
84+
85+
86+
#$appId = "<Your-App-Id>"
87+
$credential = $credential | ConvertFrom-Json
88+
Write-Output "Credential: $credential"
89+
az ad app show --id $objectId
90+
$command = "New-AzADAppFederatedCredential -ApplicationObjectId $objectId -Name $($credential.name) -Issuer $($credential.issuer) -Subject $($credential.subject) -Audience $($credential.audiences)"
91+
92+
Write-Output "Command: $command"
93+
94+
gh auth login
95+
96+
# Push secrets to GitHub
97+
$secrets = @{
98+
AZURE_CLIENT_ID = $clientId
99+
AZURE_TENANT_ID = $tenantId
100+
AZURE_SUBSCRIPTION_ID = $subscriptionId
101+
}
102+
103+
# use gh cli to push secrets to github
104+
foreach ($secret in $secrets.GetEnumerator()) {
105+
$value = $secret.Value
106+
$name = $secret.Key
107+
Write-Output "Setting secret $name"
108+
Write-Output "gh secret set $name -b $value -R $githubRepo"
109+
gh secret set $name -b $value -R $githubRepo
110+
}
111+
112+
Write-Output "Federated service principal created and secrets pushed to GitHub."

Validate-Deployment.ps1

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
param (
2+
[Parameter()]
3+
[string]$nameSuffix = "ek002",
4+
[Parameter()]
5+
[string]$deploymentName = "deploy-rg-fnapp-$nameSuffix",
6+
[Parameter()]
7+
[string]$resourceGroupName = "rg-fnapp-$nameSuffix"
8+
)
9+
10+
# echo parameters
11+
Write-Host "deploymentName: $deploymentName"
12+
Write-Host "nameSuffix: $nameSuffix"
13+
Write-Host "resourceGroupName: $resourceGroupName"
14+
15+
#az account show
16+
# get functionAppName
17+
$functionAppName = az deployment group show --resource-group $resourceGroupName `
18+
--name $deploymentName `
19+
--query properties.outputs.azureFunctionName.value `
20+
-o tsv
21+
Write-Host "functionAppName: $functionAppName"
22+
23+
# get testUrl with function key
24+
$functionKey = az functionapp keys list --name $functionAppName `
25+
--resource-group $resourceGroupName `
26+
--query functionKeys.default `
27+
-o tsv
28+
29+
Write-Host "functionKey: $functionKey"
30+
31+
$addNameParameter = $true
32+
33+
if ($addNameParameter) {
34+
Write-Host "Adding name parameter to testUrl"
35+
$testUrl = "https://$functionAppName.azurewebsites.net/api/HttpExample?name=AzureDevOpsSmokeTest&code=$functionKey"
36+
}
37+
else {
38+
$testUrl = "https://$functionAppName.azurewebsites.net/api/HttpExample?code=$functionKey"
39+
}
40+
41+
Write-Host "testUrl: $testUrl"
42+
43+
# test function
44+
$testResult = Invoke-RestMethod -Uri $testUrl
45+
Write-Host "testResult: $testResult"
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
param (
2+
[Parameter()]
3+
[string]$nameSuffix = "ek005",
4+
[Parameter()]
5+
[string]$deploymentName = "deploy-rg-defectdojo-$nameSuffix",
6+
[Parameter()]
7+
[string]$location = "canadacentral",
8+
[Parameter()]
9+
[string]$templateFile = "main.bicep",
10+
[Parameter()]
11+
[string]$resourceGroupName = "rg-defectdojo-$nameSuffix",
12+
[Parameter()]
13+
[string]$subscriptionId = "IT Test",
14+
[Parameter()]
15+
[string]$sshKeyPath = "$HOME\.ssh\vm-defectdojo-${nameSuffix}-id_rsa",
16+
[Parameter()]
17+
[string] $username = "ddadmin",
18+
[Parameter()]
19+
[string] $password = "booWgDmaYdgNxO5eNWql",
20+
[Parameter()]
21+
[string] $adminUsername = "azureuser"
22+
)
23+
24+
# function to generate random password
25+
function New-Password {
26+
param (
27+
[int]$length = 32
28+
)
29+
30+
$chars = [char[]]('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_+-=[]{}|;:,.<>?')
31+
$password = -join ($chars | Get-Random -Count $length)
32+
return $password
33+
}
34+
35+
# install az cli if not already installed
36+
if (-not (Get-Command az -ErrorAction SilentlyContinue)) {
37+
Write-Output "Installing az cli"
38+
Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://aka.ms/installazurecliwindows')
39+
}
40+
else {
41+
Write-Output "az cli already installed"
42+
}
43+
44+
# login
45+
Write-Output "Logging in to Azure"
46+
az login
47+
48+
# set subscription
49+
Write-Output "Setting subscription to $subscriptionId"
50+
az account set --subscription "$subscriptionId"
51+
52+
# echo parameters
53+
Write-Output "nameSuffix: $nameSuffix"
54+
Write-Output "deploymentName: $deploymentName"
55+
Write-Output "location: $location"
56+
Write-Output "templateFile: $templateFile"
57+
Write-Output "resourceGroupName: $resourceGroupName"
58+
59+
# deploy
60+
# create resource group
61+
Write-Output "Creating resource group $resourceGroupName in location $location"
62+
az group create --name $resourceGroupName `
63+
--location $location
64+
65+
# generate ssh key pair
66+
Write-Output "Generating ssh key pair at $sshKeyPath"
67+
if (-not (Test-Path $sshKeyPath)) {
68+
ssh-keygen -t rsa -b 2048 -f $sshKeyPath -q -N ""
69+
}
70+
else {
71+
Write-Output "ssh key pair already exists"
72+
}
73+
74+
# echo ssh public key
75+
Write-Output "Public key:"
76+
$sshPublicKey = Get-Content "$sshKeyPath.pub"
77+
Write-Output $sshPublicKey
78+
79+
# # generate random password for postgresql
80+
# $password = New-Password -length 32
81+
# Write-Output "Generated password for PostgreSQL: $password"
82+
83+
# deploy bicep
84+
Write-Output "Deploying bicep template $templateFile to resource group $resourceGroupName"
85+
az deployment group create `
86+
--name $deploymentName `
87+
--resource-group $resourceGroupName `
88+
--template-file main.bicep `
89+
--parameters sshPublicKey="`"$sshPublicKey`"" `
90+
--parameters administratorLoginPassword="`"$password`"" `
91+
--parameters nameSuffix="`"$nameSuffix`"" `
92+
--parameters adminUsername="`"$adminUsername`"" `
93+
--parameters administratorLogin="`"$username`"" `
94+
95+
# output vm public ip address from deployment output
96+
$fqdn = (az deployment group show `
97+
--name $deploymentName `
98+
--resource-group $resourceGroupName `
99+
--query "properties.outputs.fqdn.value" `
100+
--output tsv)
101+
102+
Write-Output "DefectDojo is deployed at $fqdn"
103+
104+
# output postgresql fqdn from deployment output
105+
$fullyQualifiedDomainName = (az deployment group show `
106+
--name $deploymentName `
107+
--resource-group $resourceGroupName `
108+
--query "properties.outputs.fullyQualifiedDomainName.value" `
109+
--output tsv)
110+
111+
Write-Output "PostgreSQL is deployed at $fullyQualifiedDomainName"
112+
113+
# output admin username from deployment output
114+
$adminUsername = (az deployment group show `
115+
--name $deploymentName `
116+
--resource-group $resourceGroupName `
117+
--query "properties.outputs.adminUsername.value" `
118+
--output tsv)
119+
120+
Write-Output "Admin username is $adminUsername"
121+
122+
# get psql password from deployment output
123+
$administratorLogin = (az deployment group show `
124+
--name $deploymentName `
125+
--resource-group $resourceGroupName `
126+
--query "properties.outputs.administratorLogin.value" `
127+
--output tsv)
128+
129+
# give ssh instructions
130+
Write-Output "To ssh into the VM, run the following command:"
131+
Write-Output "ssh -i $sshKeyPath $adminUsername@$fqdn"
132+
133+
# give psql instructions
134+
Write-Output "To connect to PostgreSQL, run the following command:"
135+
Write-Output "psql -h $fullyQualifiedDomainName -U $administratorLogin -P $password"

0 commit comments

Comments
 (0)