Tűzfallal védett Key Vault használata Azure DevOps-ban, Microsoft-hosted agent-el
Előző Post-hoz érkezett egy érdekes ötlet, amit este össze is dobtam, mint érdekesség. (Köszönet Gábor K. az ötletért)
Alapértelmezetten egy Key Vault úgy jön létre, hogy az elérhető az internet irányából is. Ezt a lehetőséget természetesen le lehet zárni a saját tűzfalával, és az “Enterprise” megoldásban létrehozhatunk egy Self-hosted Agent-et. Private Endpoint kell a Key Vault-hoz és egy Private DNS Zone a Vnet-hez és már működni is fog. Nem annyira bonyolult, mint elsőre hallatszik, de tény, hogy létre kell hozni pár dolgot, karbantartani, valamint fizetni hozzá a számlát. Ha viszont valami egyszerűbb környezetben vagyunk és nem köti a kezünket túl sok szabály, akkor van egy alternatív megoldás is, hogy növeljük a biztonságunkat.
Amikor DevOps-ból futtatunk egy pipeline-t, akkor azt végül egy virtuális gép fogja végrehajtani valahol a nagyvilágban. Ennek a gépnek természetesen van publikus IP-je is, szóval felvehetjük kivételként a vault saját tűzfalán ezt az IP-t és ezzel hozzáférést biztosíthatunk a pipeline futtatása alatt interneten keresztül, majd amikor végzett, természetesen el is távolítjuk. Csupán pár extra “task” ez a megoldás, de érdemi javulást érhetünk el vele, tulajdonképpen ingyen.
Előfeltételek
A környezet létrehozásához a következőkre van szükség:
- Service Principal (SP)
- Azure DevOps regisztráció
- Azure előfizetés amibe van pár $
Azure DevOps projekt létrehozása
Hozzunk létre egy üres projektet, amelyben tudjuk majd futtatni a pipeline-t. http://dev.azure.com
Ezzel el is készült az üres projekt, most pedig hozzunk létre egy service connection-t, amely segítségével az erőforrásokat kezelhetjük az előfizetésünkben.
Service connection létrehozása
Ezt már egy előző postban leírtam, hogy hogyan is kell létrehozni, mely itt található.
Key Vault létrehozása
A felületen is gyorsan összekattintható, de a Cli-ban gyorsabban megvagyunk, bár a jogosztás a felületen már gyorsabb :)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
az login
#Ha több előfizetéshez van jogosultsága a felhasználónknak
az account list
az account set --subscription "Előfizetés_neve"
#----------------------------------------------------------
$RESOURCE_GROUP_NAME="keyvault_rg"
#Egyedi névre van szükség régió szinten
$KEYVAULT_NAME="gudszentvault2345"
# Resource Group létrehozása
az group create -l westeurope -n $RESOURCE_GROUP_NAME
# Key Vault létrehozása Publikus elérés nélkül
az keyvault create --name $KEYVAULT_NAME --resource-group $RESOURCE_GROUP_NAME --location "westeurope" --default-action Deny
# Secret létrehozása, hogy legyen mit kiolvasni
az keyvault secret set --vault-name $KEYVAULT_NAME --name "secretneve" --value "jelszo123"
Utána a felületen nyissuk meg a létrehozott Vault-ot és adjunk a service principal-nak hozzáférést.
Pipeline létrehozása
Mindössze ennyi beállítással már el is érhető a pipeline számára a tartalom, most pedig hozzuk is létre azt a bizonyos pipeline-t:
Töröljünk ki mindent az automatikusan feltöltött file-ból, majd illesszük be a következőt:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
pool:
vmImage: ubuntu-latest
trigger: none
variables:
ServiceConnectionName: 'Land3'
rg: keyvault_rg
vaultname: gudszentvault2345
ipv4:
stages :
- stage: UseKeyvaultwithfirewall
jobs:
- job: GetSecretFromVaultoverFW
steps:
- task: Bash@3
# Local IP lekérése
displayName: GetAgentPublicIP
inputs:
targetType: 'inline'
script: |
IP=$(curl https://ipecho.net/plain)
IP+="/32"
echo "##vso[task.setvariable variable=ipv4;issecret=false]$IP"
- task: AzureCLI@2
# Vault FW kivételhez hozzáadása
name: Vault_IP_set
displayName: AddPublicIPVaultFW
inputs:
azureSubscription: $(ServiceConnectionName)
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
echo $(ipv4)
az keyvault network-rule add --name $(vaultname) --resource-group $(rg) --ip-address $(ipv4)
az keyvault network-rule wait --name $(vaultname) --resource-group $(rg) --updated
- task: AzureKeyVault@2
# Key Vault megnyitása
displayName: OpenKeyvault
inputs:
azureSubscription: 'Land3_SPN'
KeyVaultName: 'keyvaultgudsz'
SecretsFilter: '*'
RunAsPreJob: false
- task: CmdLine@2
# KeyVaulton belüli adatok kiírása
displayName: GetSecret
inputs:
script: 'echo $(secretneve) > secret.txt'
- task: CopyFiles@2
displayName: CopyFileForAtrifact
inputs:
Contents: secret.txt
targetFolder: '$(Build.ArtifactStagingDirectory)'
- task: PublishBuildArtifacts@1
displayName: PublishArtifact
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
ArtifactName: 'drop'
publishLocation: 'Container'
- task: AzureCLI@2
condition: always()
# IP eltávolítása a FW kivételekből
name: Vault_IP_remove
displayName: Vault remove networkIP
inputs:
azureSubscription: $(ServiceConnectionName)
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
echo $(ipv4)
az keyvault network-rule remove --name $(vaultname) --resource-group $(rg) --ip-address $(ipv4)
Cseréljük ki a változókat azokra az értékekre, amiket használtunk végül
Secret ellenőrzése
Artifact-ban, ha minden jól ment, meg is jelent egy txt exportunk, ezt így tudjuk leellenőrizni:
!Fontos, ha már nem kell, amit korábban létrehoztunk, akkor töröljük is azt ;)