Post

Azure Storage Account létrehozása privát végponttal

Szabad környezetben minden egyszerűbb, de a vállalati környezetben ritkán van ez így, így a biztonságnak ára van. Terraform-os Post-ban létrehoztunk egy Storege Account-ot (SA), hiszen a state file-t valahol tárolni kell. Most olyan SA-t hozok létre, aminél tiltva lesz a publikus végpont.

Az egyik alapvető szabály a publikus elérések tiltása, mellyek “policy”-k létrehozásával garantálhatóak, hogy tényleg nem is lesznek elérhetőek ott. Mivel ezekhez a szabályokhoz alkalmazkodni kell, így az egyes deploy-okat úgy kell megírni, hogy ezeket is figyelembe vesszük. A következő Post-ban egy egyszerű Storage Account-ot fogok deploy-olni, melynél alapvetően tiltva lesz a külső hozzáférés, tehát létre tud jönni abban az esetben is, ha tiltó szabály van érvényben. A következő erőforrások jönnek létre:

  • Storage account
  • Network interface
  • Private endpoint
  • Private DNS zone

A Vnet már létezik, amihez csatlakozni szeretnénk, így annak csak az ID-ja kell, de a Private DNS zona bejegyződik a Vnet-be. Ez annyit tesz, hogy ha van ott például egy virtuális gépünk és a Storage Account-unkat szeretné elérni név alapján, aminek van egy belsős címe, úgy azt fel fogja tudni oldani a hozzá kapcsolt Private DNS zone szolgáltatásnak köszönhetően. A biztonság még nem tökéletes ebben a verzióban, mivel vnet szerkesztő jog kell hozzá, de valahol el kell kezdeni… Később Policy-val azt is megoldjuk :P

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 $
  • Vnet amihez csatlakozunk
  • Vnet-hez még jogosultság is kell, nem csak join, de write (Microsoft.Network/privateDnsZones/virtualNetworkLinks/write, de ezt majd később a Policy megoldja ;) )

Bicep deploy

Azure DevOps-ból már küldtünk ki bicep file-t itt, szóval most csak egyszerűen parancssorból fogom azt indítani, de a webes konzolon keresztül.

img-description

1
2
3
4
5
6
7
8
9
10
11
12
13
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"

#Kell egy mappa
mkdir sape
#Lépjünk bele
cd sape
#Hozzuk létre a fájlt
nano main.bicep
#ctrl+o Mentés # ctrl+x Kilépés

Main.Bicep fájlba ezt másoljuk bele:

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
targetScope = 'subscription'

@description('Name of the resourceGroup to create')
param rgName string = 'rgname'

@description('Location for the resourceGroup')
param rgLocation string = 'westeurope'

@description('Name of the storage account')
param storageName string = 'EGYIDI-SA-NEVKELL'

@description('Name of the storage blob private link endpoint')
param storagePleBlobName string = 'blobname-prov'

@description('Resource ID of the subnet')
param subnetId string = '/subscriptions/ELOFIZETÉSID/resourceGroups/RG-NEVE/providers/Microsoft.Network/virtualNetworks/VNETNEVE/subnets/SUBNETNEVE'

@description('Resource ID of the virtual network')
param virtualNetworkId string = '/subscriptions/ELOFIZETÉSID/resourceGroups/RG-NEVE/providers/Microsoft.Network/virtualNetworks/VNETNEVE'

@description('Storage SKU')
param storageSkuName string = 'Standard_LRS'

@description('Tags to add to the resources')
param tags object = {
  own : 'otto'
}

resource newRg 'Microsoft.Resources/resourceGroups@2019-10-01' = {
  name: rgName
  location: rgLocation
  tags: {
    Note: 'subscription level deployment'
  }
  properties: {}
}

module vm './sa.bicep' = {
  name: 'vm'
  scope: newRg
  params:{
    location:rgLocation
    storageName:storageName
    storagePleBlobName:storagePleBlobName
    storageSkuName:storageSkuName
    subnetId:subnetId
    tags:tags
    virtualNetworkId:virtualNetworkId
  }
}

sa.bicep fájlba pedig ezt:

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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// Creates a storage account, private endpoints and DNS zones
@description('Azure region of the deployment')
param location string

@description('Tags to add to the resources')
param tags object

@description('Name of the storage account')
param storageName string

@description('Name of the storage blob private link endpoint')
param storagePleBlobName string

@description('Resource ID of the subnet')
param subnetId string

@description('Resource ID of the virtual network')
param virtualNetworkId string

@description('Storage SKU')
param storageSkuName string

var storageNameCleaned = replace(storageName, '-', '')

var blobPrivateDnsZoneName = 'privatelink.blob.${environment().suffixes.storage}'

resource storage 'Microsoft.Storage/storageAccounts@2021-04-01' = {
  name: storageNameCleaned
  location: location
  tags: tags
  sku: {
    name: storageSkuName
  }
  kind: 'StorageV2'
  properties: {
    accessTier: 'Hot'
    allowBlobPublicAccess: false
    allowCrossTenantReplication: false
    allowSharedKeyAccess: true
    encryption: {
      keySource: 'Microsoft.Storage'
      requireInfrastructureEncryption: false
      services: {
        blob: {
          enabled: true
          keyType: 'Account'
        }
        file: {
          enabled: true
          keyType: 'Account'
        }
        queue: {
          enabled: true
          keyType: 'Service'
        }
        table: {
          enabled: true
          keyType: 'Service'
        }
      }
    }
    isHnsEnabled: false
    isNfsV3Enabled: false
    keyPolicy: {
      keyExpirationPeriodInDays: 7
    }
    largeFileSharesState: 'Disabled'
    minimumTlsVersion: 'TLS1_2'
    networkAcls: {
      bypass: 'AzureServices'
      defaultAction: 'Deny'
    }
    supportsHttpsTrafficOnly: true
  }
}

resource storagePrivateEndpointBlob 'Microsoft.Network/privateEndpoints@2020-11-01' = {
  name: storagePleBlobName
  location: location
  tags: tags
  properties: {
    privateLinkServiceConnections: [
      {
        name: storagePleBlobName
        properties: {
          groupIds: [
            'blob'
          ]
          privateLinkServiceId: storage.id
          privateLinkServiceConnectionState: {
            status: 'Approved'
            description: 'Auto-Approved'
            actionsRequired: 'None'
          }
        }
      }
    ]
    subnet: {
      id: subnetId
    }
  }
}

resource blobPrivateDnsZone 'Microsoft.Network/privateDnsZones@2020-01-01' = {
  name: blobPrivateDnsZoneName
  location: 'global'
}

resource privateEndpointDns 'Microsoft.Network/privateEndpoints/privateDnsZoneGroups@2020-06-01' = {
  name: '${storagePrivateEndpointBlob.name}/blob-PrivateDnsZoneGroup'
  properties:{
    privateDnsZoneConfigs: [
      {
        name: blobPrivateDnsZoneName
        properties:{
          privateDnsZoneId: blobPrivateDnsZone.id
        }
      }
    ]
  }
}

resource blobPrivateDnsZoneVnetLink 'Microsoft.Network/privateDnsZones/virtualNetworkLinks@2020-01-01' = {
  name: '${blobPrivateDnsZone.name}/${uniqueString(storage.id)}'
  location: 'global'
  properties: {
    registrationEnabled: false
    virtualNetwork: {
      id: virtualNetworkId
    }
  }
}

output storageId string = storage.id

img-descriptionVégül valami hasonlót kellene látnunk

Ha a két fájlt sikerült létrehozni ugyanabban a mappában, már csak futtatni kell azokat.

1
az deployment sub create --template-file main.bicep --location=westeurope

Ha minden jól ment, végül valami hasonlót kellene látnunk:
img-description

Szuper, már van is egy private végponttal rendelkező SA, aminek az eléréséhez nem kell kimenni a netre.

This post is licensed under CC BY 4.0 by the author.