1
+ <#
2
+ # © 2024 Broadcom. All Rights Reserved. Broadcom. The term "Broadcom" refers to
3
+ # Broadcom Inc. and/or its subsidiaries.
4
+ #>
5
+
6
+ <#
7
+ . SYNOPSIS
8
+
9
+ This script deploys a VI workload domain
10
+
11
+ . DESCRIPTION
12
+
13
+ This script creates a VI workload domain using the PowerCLI SDK module for VCF SDDC Manager.
14
+
15
+ The script can be broken into two main parts. First, the ESXi hosts are being commissioned.
16
+ Then, the actual VI domain is created using the commissioned ESXi hosts.
17
+
18
+ Both steps - ESXi host commissioning and VI domain creations - are three-stage operations themselves.
19
+ The commissioning/creation specs are constructed. The specs are validated. The actual operation is invoked.
20
+ The validation and operation invocation are long-running tasks. This requires awaiting and status tracking
21
+ until their completion. The waiting for validation and the actual operation is done using helper cmdlets -
22
+ Wait-VcfValidation and Wait-VcfTask, located in utils sub-folder.
23
+
24
+ On completion a new VI workload domain reflecting the given parameters should be created.
25
+
26
+ . NOTES
27
+
28
+ Prerequisites:
29
+ - A VCF Management Domain
30
+ - A minimum of three free hosts marked with the appropriate storage and at least 4 NICs.
31
+ Two of the NICs will be used for Frontend/Management and the other two for workloads.
32
+
33
+ "Global parameters", "Host commissioning parameters", "Workload domain creation parameters" should be updated to
34
+ reflect the environment they are run in. This may require altering the spec creation script.
35
+
36
+ #>
37
+
38
+ $ErrorActionPreference = ' Stop'
39
+ $SCRIPTROOT = ($PWD.ProviderPath , $PSScriptRoot )[!! $PSScriptRoot ]
40
+ . (Join-Path $SCRIPTROOT ' utils/Wait-VcfTask.ps1' )
41
+ . (Join-Path $SCRIPTROOT ' utils/Wait-VcfValidation.ps1' )
42
+
43
+ # --------------------------------------------------------------------------------------------------------------------------
44
+ # Global parameters
45
+ # --------------------------------------------------------------------------------------------------------------------------
46
+
47
+ # Organization name of the workload domain
48
+ $OrgName = ' VMware'
49
+
50
+ # Name of the workload domain - used as a prefix for nested inventory items
51
+ $domainName = ' sfo-w01'
52
+
53
+ $domain = ' vrack.vsphere.local'
54
+ $gateway = ' 10.0.0.250'
55
+ $sddcManager = @ {
56
+ Fqdn = " sddc-manager.$domain "
57
+ User = ' administrator@vsphere.local'
58
+ Password = ' VMware123!'
59
+ }
60
+
61
+ # ###########################################################################################################################
62
+ # Host commissioning
63
+ # ###########################################################################################################################
64
+
65
+ # --------------------------------------------------------------------------------------------------------------------------
66
+ # Host commissioning parameters
67
+
68
+ $esxiHosts = @ (
69
+ @ {
70
+ Fqdn = " esxi-5.$domain "
71
+ Username = ' root'
72
+ Password = " ESXiSddc123!"
73
+ StorageType = " VSAN"
74
+ LicenseKey = ' XXXXX-XXXXX-XXXXX-XXXXX-XXXXX'
75
+ }
76
+ @ {
77
+ Fqdn = " esxi-6.$domain "
78
+ Username = ' root'
79
+ Password = " ESXiSddc123!"
80
+ StorageType = " VSAN"
81
+ LicenseKey = ' XXXXX-XXXXX-XXXXX-XXXXX-XXXXX'
82
+ }
83
+ @ {
84
+ Fqdn = " esxi-7.$domain "
85
+ Username = ' root'
86
+ Password = " ESXiSddc123!"
87
+ StorageType = " VSAN"
88
+ LicenseKey = ' XXXXX-XXXXX-XXXXX-XXXXX-XXXXX'
89
+ }
90
+ @ {
91
+ Fqdn = " esxi-8.$domain "
92
+ Username = ' root'
93
+ Password = " ESXiSddc123!"
94
+ StorageType = " VSAN"
95
+ LicenseKey = ' XXXXX-XXXXX-XXXXX-XXXXX-XXXXX'
96
+ }
97
+ )
98
+
99
+ # The network pool to associate the host with
100
+ $networkPoolName = ' networkpool'
101
+
102
+ # --------------------------------------------------------------------------------------------------------------------------
103
+
104
+ # Connect to SDDC manager
105
+ $sddcConn = Connect-VcfSddcManagerServer `
106
+ - Server $sddcManager.Fqdn `
107
+ - User $sddcManager.User `
108
+ - Password $sddcManager.Password
109
+
110
+ # # Host commissioning spec construction
111
+ $NetworkPool = Invoke-VcfGetNetworkPool | `
112
+ Select-Object - ExpandProperty Elements | `
113
+ Where-Object { $_.Name -eq $NetworkPoolName }
114
+
115
+ $hostCommissionSpecs = $esxiHosts | % {
116
+ Initialize-VcfHostCommissionSpec - Fqdn $_.Fqdn `
117
+ - NetworkPoolId $NetworkPool.Id `
118
+ - Password $_.Password `
119
+ - StorageType $_.StorageType `
120
+ - Username $_.Username
121
+ }
122
+
123
+ # # Host commissioning validation
124
+ $hostValidationResult = Invoke-VcfValidateHostCommissionSpec - HostCommissionSpecs $hostCommissionSpecs
125
+ $hostValidationResult = Wait-VcfValidation `
126
+ - Validation $hostValidationResult `
127
+ - UpdateValidation { param ($id ) Invoke-VcfGetHostCommissionValidationByID - id $id } `
128
+ - UpdateValidationArguments $hostValidationResult.Id `
129
+ - ThrowOnError
130
+
131
+ # # Host commissioning
132
+ $commisionTask = Invoke-VcfCommissionHosts - hostCommissionSpecs $hostCommissionSpecs
133
+ $commisionTask = Wait-VcfTask $commisionTask - ThrowOnError
134
+
135
+
136
+ # ###########################################################################################################################
137
+ # Workload domain creation
138
+ # ###########################################################################################################################
139
+
140
+ # --------------------------------------------------------------------------------------------------------------------------
141
+ # Workload domain creation parameters
142
+
143
+ $domainSpec = @ {
144
+ DomainName = $DomainName
145
+ OrgName = $OrgName
146
+ VCenterSpec = @ {
147
+ Name = " $DomainName -vc01"
148
+ DatacenterName = " $DomainName -dc01"
149
+ RootPassword = " VMware123!"
150
+ NetworkDetailsSpec = @ {
151
+ DnsName = " $DomainName -vc01.$domain "
152
+ IpAddress = " 10.0.0.40"
153
+ SubnetMask = " 255.255.255.0"
154
+ Gateway = $gateway
155
+ }
156
+ }
157
+ ComputeSpec = @ {
158
+ ClusterSpecs = @ (
159
+ @ {
160
+ DatastoreSpec = @ {
161
+ VSanDatastoreSpec = @ {
162
+ DatastoreName = " $DomainName -ds01"
163
+ FailuresToTolerate = 1
164
+ LicenseKey = " XXXXX-XXXXX-XXXXX-XXXXX-XXXXX"
165
+ }
166
+ }
167
+ NetworkSpec = @ {
168
+ VdsSpecs = @ (
169
+ @ {
170
+ Name = " $DomainName -vds01"
171
+ PortGroups = @ (
172
+ @ {
173
+ Name = ' vSAN'
174
+ TransportType = ' VSAN'
175
+ }
176
+ @ {
177
+ Name = ' management'
178
+ TransportType = ' MANAGEMENT'
179
+ }
180
+ @ {
181
+ Name = ' vmotion'
182
+ TransportType = ' VMOTION'
183
+ }
184
+ )
185
+ }
186
+ @ {
187
+ Name = " $DomainName -vds02"
188
+ IsUsedByNsxt = $true
189
+ }
190
+ )
191
+ NsxClusterSpec = @ {
192
+ NsxTClusterSpec = @ {
193
+ GeneveVlanId = 0
194
+ }
195
+ }
196
+ }
197
+ Name = " $DomainName -cl01"
198
+ }
199
+ )
200
+ }
201
+ NsxTSpec = @ {
202
+ NsxManagerSpecs = @ (
203
+ @ {
204
+ Name = " $domainName -nsx01a"
205
+ NetworkDetailsSpec = @ {
206
+ DnsName = " $domainName -nsx01a.$domain "
207
+ IpAddress = " 10.0.0.41"
208
+ SubnetMask = " 255.255.255.0"
209
+ Gateway = $gateway
210
+ }
211
+ }
212
+ @ {
213
+ Name = " $domainName -nsx01b"
214
+ NetworkDetailsSpec = @ {
215
+ DnsName = " $domainName -nsx01b.$domain "
216
+ IpAddress = " 10.0.0.42"
217
+ SubnetMask = " 255.255.255.0"
218
+ Gateway = $gateway
219
+ }
220
+ }
221
+ @ {
222
+ Name = " $domainName -nsx01c"
223
+ NetworkDetailsSpec = @ {
224
+ DnsName = " $domainName -nsx01c.$domain "
225
+ IpAddress = " 10.0.0.43"
226
+ SubnetMask = " 255.255.255.0"
227
+ Gateway = $gateway
228
+ }
229
+ }
230
+ )
231
+ FormFactor = ' large'
232
+ LicenseKey = ' XXXXX-XXXXX-XXXXX-XXXXX-XXXXX'
233
+ NSXManagerAdminPassword = " VMware123!123"
234
+ Vip = ' 10.0.0.44'
235
+ VipFqdn = " $domainName -nsx01.$domain "
236
+ }
237
+ }
238
+ # --------------------------------------------------------------------------------------------------------------------------
239
+
240
+ # # Workload domain spec construction
241
+ $esxiFqdns = $esxiHosts | Select-Object - ExpandProperty Fqdn
242
+ $VcfHost = Invoke-VcfGetHosts - status " UNASSIGNED_USEABLE" | `
243
+ Select-Object - ExpandProperty Elements | `
244
+ Where-Object { $esxiFqdns -contains $_.Fqdn }
245
+
246
+ $ComputeSpec = Initialize-VcfComputeSpec - ClusterSpecs (
247
+ $domainSpec.ComputeSpec.ClusterSpecs | ForEach-Object {
248
+ $_clusterSpec = $_
249
+
250
+ Initialize-VcfClusterSpec `
251
+ - DatastoreSpec (
252
+ Initialize-VcfDatastoreSpec `
253
+ - VsanDatastoreSpec (
254
+ Initialize-VcfVsanDatastoreSpec `
255
+ - DatastoreName $_.DatastoreSpec.VSanDatastoreSpec.DatastoreName `
256
+ - FailuresToTolerate $_.DatastoreSpec.VSanDatastoreSpec.FailuresToTolerate `
257
+ - LicenseKey $_.DatastoreSpec.VSanDatastoreSpec.LicenseKey
258
+ )) `
259
+ - HostSpecs (
260
+ $VcfHost | ForEach-Object {
261
+ $esxiHost = $esxiHosts | Where-Object { $_.Fqdn -eq $_.Fqdn } | Select-Object - First 1
262
+
263
+ Initialize-VcfHostSpec `
264
+ - Id $_.Id `
265
+ - LicenseKey $esxiHost.LicenseKey `
266
+ - HostNetworkSpec (
267
+ Initialize-VcfHostNetworkSpec - VmNics @ (
268
+ Initialize-VcfVmNic - Id ' vmnic0' - VdsName $_clusterSpec.NetworkSpec.VdsSpecs [0 ].Name
269
+ Initialize-VcfVmNic - Id ' vmnic1' - VdsName $_clusterSpec.NetworkSpec.VdsSpecs [0 ].Name
270
+ Initialize-VcfVmNic - Id ' vmnic2' - VdsName $_clusterSpec.NetworkSpec.VdsSpecs [1 ].Name
271
+ Initialize-VcfVmNic - Id ' vmnic3' - VdsName $_clusterSpec.NetworkSpec.VdsSpecs [1 ].Name
272
+ ))
273
+ }
274
+ ) `
275
+ - Name $_.Name `
276
+ - NetworkSpec (
277
+ Initialize-VcfNetworkSpec `
278
+ - NsxClusterSpec (
279
+ Initialize-VcfNsxClusterSpec - NsxTClusterSpec (
280
+ Initialize-VcfNsxTClusterSpec `
281
+ - GeneveVlanId $_.NetworkSpec.NsxClusterSpec.NsxTClusterSpec.GeneveVlanId
282
+ )
283
+ ) `
284
+ - VdsSpecs @ (
285
+ Initialize-VcfVdsSpec - Name $_.NetworkSpec.VdsSpecs [0 ].Name `
286
+ - PortGroupSpecs (
287
+ $_.NetworkSpec.VdsSpecs [0 ].PortGroups | ForEach-Object {
288
+ Initialize-VcfPortgroupSpec `
289
+ - Name $_.Name `
290
+ - TransportType $_.TransportType
291
+ })
292
+ Initialize-VcfVdsSpec - Name $_.NetworkSpec.VdsSpecs [1 ].Name `
293
+ - IsUsedByNsxt $_.NetworkSpec.VdsSpecs [1 ].IsUsedByNsxt
294
+ ))
295
+ })
296
+
297
+
298
+ $DomainCreationSpec = Initialize-VcfDomainCreationSpec `
299
+ - ComputeSpec $ComputeSpec `
300
+ - DomainName $domainSpec.DomainName `
301
+ - NsxTSpec (
302
+ Initialize-VcfNsxTSpec `
303
+ - FormFactor $domainSpec.NsxTSpec.FormFactor `
304
+ - LicenseKey $domainSpec.NsxTSpec.LicenseKey `
305
+ - NsxManagerAdminPassword $domainSpec.NsxTSpec.NSXManagerAdminPassword `
306
+ - NsxManagerSpecs (
307
+ $domainSpec.NsxTSpec.NsxManagerSpecs | ForEach-Object {
308
+ Initialize-VcfNsxManagerSpec `
309
+ - Name $_.Name `
310
+ - NetworkDetailsSpec (
311
+ Initialize-VcfNetworkDetailsSpec `
312
+ - DnsName $_.NetworkDetailsSpec.DnsName `
313
+ - IpAddress $_.NetworkDetailsSpec.IpAddress `
314
+ - SubnetMask $_.NetworkDetailsSpec.SubnetMask `
315
+ - Gateway $_.NetworkDetailsSpec.Gateway )
316
+ }
317
+ ) `
318
+ - Vip $domainSpec.NsxTSpec.Vip `
319
+ - VipFqdn $domainSpec.NsxTSpec.VipFqdn ) `
320
+ - OrgName $domainSpec.OrgName `
321
+ - VcenterSpec (
322
+ Initialize-VcfVcenterSpec `
323
+ - DatacenterName $domainSpec.VCenterSpec.DatacenterName `
324
+ - Name $domainSpec.VCenterSpec.Name `
325
+ - NetworkDetailsSpec (
326
+ Initialize-VcfNetworkDetailsSpec `
327
+ - DnsName $domainSpec.VCenterSpec.NetworkDetailsSpec.DnsName `
328
+ - IpAddress $domainSpec.VCenterSpec.NetworkDetailsSpec.IpAddress `
329
+ - SubnetMask $domainSpec.VCenterSpec.NetworkDetailsSpec.SubnetMask `
330
+ - Gateway $domainSpec.VCenterSpec.NetworkDetailsSpec.Gateway
331
+ ) `
332
+ - RootPassword $domainSpec.VCenterSpec.RootPassword )
333
+
334
+ # Workload domain spec validation
335
+ $domainValidationResult = Invoke-VcfValidateDomainCreationSpec - domainCreationSpec $DomainCreationSpec
336
+ $domainValidationResult = Wait-VcfValidation `
337
+ - Validation $domainValidationResult `
338
+ - ThrowOnError
339
+
340
+ # Workload domain creation
341
+ $creationTask = Invoke-VcfCreateDomain - domainCreationSpec $DomainCreationSpec
342
+ $creationTask = Wait-VcfTask $creationTask - ThrowOnError
343
+
344
+ Disconnect-VcfSddcManagerServer $sddcConn
0 commit comments