Full Autonomy for the Developers when using VCF Private Cloud (compute / storage / network / security)
Table of contents
Summary
- VCF 5.2.1 enhances Virtual Private Clouds (VPCs): This allows developers to self-provision their applications, including compute, storage, network, and security, without submitting IT tickets.
- VPCs simplify network setup: They provide an abstraction layer for creating self-contained virtual networks with their security policies, making it easier for developers to manage their applications.
- Improved developer autonomy: Developers can now define their networks, subnets, and security rules (North/South and East/West traffic) within their VPCs.
- Centralized control for admins: Network administrators still manage IP addressing, and security administrators define overall security policies, ensuring compliance and control.
- Automation through scripting: The blog post provides example scripts for automating tasks like creating Active Directory groups, VPCs, and assigning vCenter permissions, showcasing VCF’s orchestration capabilities.
Presentation
Developers require the capability to deploy their applications.
For years, vCenter Administrators have been able to grant developers permission to self-provision the compute (VMs) and storage for their applications.
However, developers have not had the autonomy to manage their applications’ network and security aspects.
So the developers’ workflow has always been:
- Developer opens IT ticket to get subnets (and optionally open firewall)
- Developer creates workload (VMs)
VCF 5.2.1 release closes the gap, granting developers full autonomy over the deployment of their applications, including compute, storage, network, and security thanks to its latest enhancements in Virtual Private Clouds (VPCs).
VPCs are an abstraction layer that simplifies setting up self-contained virtual private cloud networks and security in a self-service consumption model.
VPCs were introduced as part of its NSX network and security component.
And VCF 5.2.1 integrates those VPCs into its vCenter compute component.
Key points to note about this self-service VPC consumption model for developers include:
- Network Administrators maintain complete ownership of the IP addressing for the self-service VPC networks.
- Security Administrators retain full control over security, determining which traffic is permitted North/South (between the physical network and VPCs) and East/West (within VPCs).
Developers have the capability to create:
- Specific networks and subnets for their applications.
- Tailored North/South and East/West security rules for their applications
Demo
In the demo below, you can see how the developers of a Finance application and those of a Marketing application have independently deployed their applications (including compute, storage, network, and security) without having to open a single IT ticket:
Annex
The whole demo could have been done using VCF UI.
However to speed up things and to show the orchestration capabilities of VCF, different scripts have been used in the demo:
- Creation of Microsoft Active Directory Groups
Actually, this script has nothing to do with VCF and is a Microsoft Active Directory script to create Microsoft AD Groups and add specific developer users in them.
Those AD Groups are later used by VCF to allow those AD Groups to use its VCF Compute component (vCenter) and its VCF Network and Security component (NSX).
- Creation of Virtual Private Clouds (VPCs)
Specific VPCs are created for the application of Finance and of Marketing.
VPC Admin rights are granted to specific AD Group (Finance / Marketing).
- Creation of vCenter Permissions for each application
Specific permissions are created in vCenter to allow each Microsoft AD Group (Finance / Marketing) to be fully autonomous in the creation of its application.
Here is the explanation of each script:
Creation of Microsoft Active Directory Groups
Root (.bat) script “create-Microsoft-AD-Group_Marketing.bat”
1 |
"C:\Program Files\PowerShell\7\pwsh.exe" code\Microsoft-AD-Group-Creation.ps1 -user_name developer2 -ad_group Group_Dev_Marketing |
C:\Program Files\PowerShell\7\pwsh.exe
Location of PowerShell executable.
code\Microsoft-AD-Group-Creation.ps1
Location of the PowerShell script
-user_name developer2 -ad_group Group_Dev_Marketing
Script parameters:- user_name = developer AD User who will develop the Marketing application
- ad_group = AD Group name
PowerShell script “Microsoft-AD-Group-Creation.ps1”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# ./Microsoft-AD-Group-Creation.ps1 -user_name developer2 -$ad_group Group_Dev_Marketing param ($user_name, $ad_group) Write-Output "==============================================" Write-Output "Create AD Group $ad_group with user $user_name" Write-Output "==============================================" ### #Create Create AD Group $ad_group with user $user_name ### Write-Output " . Create AD Group $ad_group with user $user_name" New-ADGroup -Name $ad_group -Path "CN=Users,DC=corp,DC=vmbeans,DC=com" -Description "VMware VCF VPC Administrators" -GroupCategory Security -GroupScope Global Write-Output " . Add AD User $user_name in AD Group $ad_group" Add-ADGroupMember -Identity (Get-ADGroup $ad_group) -Members (Get-ADUser $user_name) cmd /c 'pause' |
Creation of Virtual Private Clouds (VPCs)
Root (.bat) script “create-Project_Marketing-VPC_Mar.bat”
1 2 3 |
python code\create_project.py -nsx_manager lm-vi1-paris.corp.vmbeans.com -nsx_user admin -nsx_password VMware1!VMware1! -project_name Marketing python code\create_vpc.py -nsx_manager lm-vi1-paris.corp.vmbeans.com -nsx_user admin -nsx_password VMware1!VMware1! -project_name Marketing -vpc_name VPC_Mar -ad_group Group_Dev_Marketing |
code\create_project.py and code\create_vpc.py
Location of the python scripts
-nsx_manager lm-vi1-paris.corp.vmbeans.com -nsx_user admin -nsx_password VMware1!VMware1! -project_name Marketing -vpc_name VPC_Mar -ad_group Group_Dev_Marketing
Script parameters:- nsx_manager = VCF NSX Component (IP or FQDN)
- nsx_user = NSX Admin account
- nsx_password = NSX Admin password
- project_name = Project name to create
- vpc_name = VPC name to create
- ad_group = AD Group name to add as VPC Admin
Python script “create_project.py””
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 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
#!/usr/bin/env python # Requires Python 3.x # NSX Project # Author: Dimitri Desmidt # version 1.0 # September 2024 # This script is neither supported nor endorsed by VMware/Broadcom but meant as an example ''' Script to create NSX Project Validated with: NSX-T 4.2.1 ''' import requests import json import datetime import ssl import time import os.path import argparse # Input information # python create_project.py -nsx_manager lm-vi1-paris.corp.vmbeans.com -nsx_user admin -nsx_password VMware1!VMware1! -project_name Project1 parser = argparse.ArgumentParser() parser.add_argument("-nsx_manager", help="REQUIRED - NSX Manager IP/FQDN (e.g. 192.168.110.201)", type=str, required=True) parser.add_argument("-nsx_user", default="admin", help="OPTIONAL - NSX Manager user (default = admin)", type=str) parser.add_argument("-nsx_password", help="REQUIRED - NSX Manager password", type=str, required=True) parser.add_argument("-project_name", help="REQUIRED - Project Name", type=str, required=True) args = parser.parse_args() nsx_manager = args.nsx_manager nsx_user = args.nsx_user nsx_password = args.nsx_password project_name = args.project_name ###################################################################################################### # Don't change things below ###################################################################################################### start_time= datetime.datetime.now() #remove the self certificate warnings requests.packages.urllib3.disable_warnings() # headers for NSX-T Restful API calls headers = {'Content-type': 'application/json', 'Accept': 'application/json'} def nsx_get_call (mgr, uri): try: response = requests.get('https://'+mgr+uri, verify=False, auth=(nsx_user, nsx_password), headers=headers, stream=True) except requests.exceptions.Timeout: print ("GET uri " + uri + " Timeout") return 'error' except requests.exceptions.ConnectionError: print ("GET uri " + uri + " ConnectionError") return 'error' if "20" not in str(response.status_code): print ("GET uri " + uri + " response status code: "+str(response.status_code)) print (response.text) return 'error' #As the answer is in JSON format, create the proper object json_response=json.loads(response.text) return json_response def nsx_check_call (mgr, uri): try: response = requests.get('https://'+mgr+uri, verify=False, auth=(nsx_user, nsx_password), headers=headers, stream=True) except requests.exceptions.Timeout: print ("GET uri " + uri + " Timeout") return 'error' except requests.exceptions.ConnectionError: print ("GET uri " + uri + " ConnectionError") return 'error' if "20" not in str(response.status_code): return 'error' #As the answer is in JSON format, create the proper object json_response=json.loads(response.text) return json_response def nsx_put_call (mgr, uri, payload): try: response = requests.put('https://'+mgr+uri, verify=False, auth=(nsx_user, nsx_password), headers=headers, stream=True, data=json.dumps(payload)) except requests.exceptions.Timeout: print ("PUT uri " + uri + " Timeout") return 'error' except requests.exceptions.ConnectionError: print ("PUT uri " + uri + " ConnectionError") return 'error' if "20" not in str(response.status_code): print ("PUT uri " + uri + " response status code: "+str(response.status_code)) print (response.text) return 'error' #As the answer is in JSON format, create the proper object json_response=json.loads(response.text) return json_response def nsx_patch_call (mgr, uri, payload): try: response = requests.patch('https://'+mgr+uri, verify=False, auth=(nsx_user, nsx_password), headers=headers, stream=True, data=json.dumps(payload)) except requests.exceptions.Timeout: print ("PATCH uri " + uri + " Timeout") return 'error' except requests.exceptions.ConnectionError: print ("PATCH uri " + uri + " ConnectionError") return 'error' if "20" not in str(response.status_code): print ("PATCH uri " + uri + " response status code: "+str(response.status_code)) print (response.text) return 'error' return 'OK' ######################### #Script to create project ######################### print ('') #Validate inputs print ('========================') print ('Script to create Project') print ('========================') print (' nsx_manager = '+ nsx_manager) print (' nsx_user = '+ nsx_user) print (' nsx_password = '+ nsx_password) print (' project_name = '+ project_name) print ('') print ('') print ('') #Create External Subnet if needed if nsx_check_call(nsx_manager, '/policy/api/v1/infra/ip-blocks/Project_Ext') == 'error': payload = {"visibility":"EXTERNAL","cidr":"30.30.30.0/23"} result = nsx_put_call(nsx_manager, '/policy/api/v1/infra/ip-blocks/Project_Ext', payload) #Create Project print ('. Create Project: '+ project_name) payload = { \ "resource_type": "Project", \ "tier_0s": [ \ "/infra/tier-0s/ef4c052c-dbcc-4750-a706-d71a21e5bcf9" \ ], \ "site_infos": [ \ { \ "edge_cluster_paths": [ \ "/infra/sites/default/enforcement-points/default/edge-clusters/7a7c5b8a-e8f2-47b9-9017-bc5d66e8cb24" \ ], \ "site_path": "/infra/sites/default" \ } \ ], \ "external_ipv4_blocks": [ \ "/infra/ip-blocks/Project_Ext" \ ], \ "vc_folder": "true", \ "activate_default_dfw_rules": "true" \ } result = nsx_put_call(nsx_manager, '/policy/api/v1/orgs/default/projects/'+project_name, payload) end_time= datetime.datetime.now() print ('') print ('') print ('script started at ' + start_time.strftime("%Y-%m-%d %H:%M:%S")) print ('script ended at ' + end_time.strftime("%Y-%m-%d %H:%M:%S")) total_time = end_time - start_time print ('total time '+str(total_time).split(".")[0]) |
Python script “create_vpc.py”
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 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 |
#!/usr/bin/env python # Requires Python 3.x # NSX VPC # Author: Dimitri Desmidt # version 1.0 # September 2024 # This script is neither supported nor endorsed by VMware/Broadcom but meant as an example ''' Script to create NSX VPC Validated with: NSX-T 4.2.1 ''' import requests import json import datetime import ssl import time import os.path import argparse # Input information # python create_vpc.py -nsx_manager lm-vi1-paris.corp.vmbeans.com -nsx_user admin -nsx_password VMware1!VMware1! -project_name Project1 -vpc_name VPC1 -ad_group 'Group_Dev_Marketing' parser = argparse.ArgumentParser() parser.add_argument("-nsx_manager", help="REQUIRED - NSX Manager IP/FQDN (e.g. 192.168.110.201)", type=str, required=True) parser.add_argument("-nsx_user", default="admin", help="OPTIONAL - NSX Manager user (default = admin)", type=str) parser.add_argument("-nsx_password", help="REQUIRED - NSX Manager password", type=str, required=True) parser.add_argument("-project_name", help="REQUIRED - Project Name", type=str, required=True) parser.add_argument("-vpc_name", help="REQUIRED - VPC Name", type=str, required=True) parser.add_argument("-ad_group", help="REQUIRED - AD Group", type=str, required=True) args = parser.parse_args() nsx_manager = args.nsx_manager nsx_user = args.nsx_user nsx_password = args.nsx_password project_name = args.project_name vpc_name = args.vpc_name ad_group = args.ad_group ###################################################################################################### # Don't change things below ###################################################################################################### start_time= datetime.datetime.now() #remove the self certificate warnings requests.packages.urllib3.disable_warnings() # headers for NSX-T Restful API calls headers = {'Content-type': 'application/json', 'Accept': 'application/json'} def nsx_get_call (mgr, uri): try: response = requests.get('https://'+mgr+uri, verify=False, auth=(nsx_user, nsx_password), headers=headers, stream=True) except requests.exceptions.Timeout: print ("GET uri " + uri + " Timeout") return 'error' except requests.exceptions.ConnectionError: print ("GET uri " + uri + " ConnectionError") return 'error' if "20" not in str(response.status_code): print ("GET uri " + uri + " response status code: "+str(response.status_code)) print (response.text) return 'error' #As the answer is in JSON format, create the proper object json_response=json.loads(response.text) return json_response def nsx_check_call (mgr, uri): try: response = requests.get('https://'+mgr+uri, verify=False, auth=(nsx_user, nsx_password), headers=headers, stream=True) except requests.exceptions.Timeout: print ("GET uri " + uri + " Timeout") return 'error' except requests.exceptions.ConnectionError: print ("GET uri " + uri + " ConnectionError") return 'error' if "20" not in str(response.status_code): return 'error' #As the answer is in JSON format, create the proper object json_response=json.loads(response.text) return json_response def nsx_put_call (mgr, uri, payload): try: response = requests.put('https://'+mgr+uri, verify=False, auth=(nsx_user, nsx_password), headers=headers, stream=True, data=json.dumps(payload)) except requests.exceptions.Timeout: print ("PUT uri " + uri + " Timeout") return 'error' except requests.exceptions.ConnectionError: print ("PUT uri " + uri + " ConnectionError") return 'error' if "20" not in str(response.status_code): print ("PUT uri " + uri + " response status code: "+str(response.status_code)) print (response.text) return 'error' #As the answer is in JSON format, create the proper object json_response=json.loads(response.text) return json_response def nsx_post_call (mgr, uri, payload): try: response = requests.post('https://'+mgr+uri, verify=False, auth=(nsx_user, nsx_password), headers=headers, stream=True, data=json.dumps(payload)) except requests.exceptions.Timeout: print ("POST uri " + uri + " Timeout") return 'error' except requests.exceptions.ConnectionError: print ("POST uri " + uri + " ConnectionError") return 'error' if "20" not in str(response.status_code): print ("POST uri " + uri + " response status code: "+str(response.status_code)) print (response.text) return 'error' #As the answer is in JSON format, create the proper object json_response=json.loads(response.text) return json_response def nsx_patch_call (mgr, uri, payload): try: response = requests.patch('https://'+mgr+uri, verify=False, auth=(nsx_user, nsx_password), headers=headers, stream=True, data=json.dumps(payload)) except requests.exceptions.Timeout: print ("PATCH uri " + uri + " Timeout") return 'error' except requests.exceptions.ConnectionError: print ("PATCH uri " + uri + " ConnectionError") return 'error' if "20" not in str(response.status_code): print ("PATCH uri " + uri + " response status code: "+str(response.status_code)) print (response.text) return 'error' return 'OK' def nsx_find_user_id (mgr, uri, user_name): json_response = nsx_get_call (mgr, uri) rerun = 'true' object_list = [] userid = 'error' while (rerun == 'true' and len(json_response['results']) > 0): for result in (json_response['results']): if user_name in result['username']: userid = result['userid'] if ('cursor' in json_response): json_response = nsxt_get_call (mgr, uri,cursor=json_response['cursor']) else: rerun = 'false' return userid def nsx_find_user_status (mgr, uri, user_name): json_response = nsx_get_call (mgr, uri) rerun = 'true' object_list = [] name_id = 'error' while (rerun == 'true' and len(json_response['results']) > 0): for result in (json_response['results']): if user_name in result['username']: status = result['status'] if ('cursor' in json_response): json_response = nsxt_get_call (mgr, uri,cursor=json_response['cursor']) else: rerun = 'false' return status def nsx_find_role_id (mgr, uri, user_name): json_response = nsx_get_call (mgr, uri) rerun = 'true' # Create list of elements to find while (rerun == 'true' and len(json_response['results']) > 0): for result in (json_response['results']): if user_name == result['name']: role_id = result['id'] rerun = 'false' if ('cursor' in json_response): json_response = nsxt_get_call (mgr, uri,cursor=json_response['cursor']) return role_id def nsx_user_vpc_admin (mgr, uri, user_name, project, vpc): role_id = nsx_find_role_id(mgr, uri, user_name) role_json = nsx_get_call (mgr, uri+'/'+role_id) role_json['roles'] = [] role_json['read_roles_for_paths'] = "true" role_json['roles_for_paths'] = [ \ { \ "path":"/orgs/default/projects/"+project+"/vpcs/"+vpc, \ "roles":[ \ { \ "role":"vpc_admin", \ "role_display_name":"VPC Admin" \ } \ ] \ }, \ { \ "path":"/", \ "roles":[ \ { \ "role":"auditor", \ "role_display_name":"Auditor" \ } \ ], \ "delete_path":"true" \ } \ ] result = nsx_put_call (mgr, uri+'/'+role_id, role_json) return result def nsx_ldap_user_vpc_admin (mgr, uri, user_name, project, vpc): payload = { \ "name": user_name+"@corp.vmbeans.com", \ "type": "remote_user", \ "identity_source_type": "LDAP", \ "identity_source_id": "485bbac8-f79d-41ee-a2d3-8a81e987ac57", \ "roles_for_paths": [ \ { \ "path": "/orgs/default/projects/"+project+"/vpcs/"+vpc, \ "roles": [ \ { \ "role": "vpc_admin", \ "role_display_name": "VPC Admin" \ } \ ] \ }], \ "read_roles_for_paths": "true" \ } result = nsx_post_call (mgr, uri, payload) return result ##################### #Script to create VPC ##################### print ('') #Validate inputs print ('========================') print ('Script to create VPC') print ('========================') print (' nsx_manager = '+ nsx_manager) print (' nsx_user = '+ nsx_user) print (' nsx_password = '+ nsx_password) print (' project_name = '+ project_name) print (' vpc_name = '+ vpc_name) print ('') print ('') print ('') #Create Private Subnet if needed if nsx_check_call(nsx_manager, '/policy/api/v1/orgs/default/projects/'+project_name+'/infra/ip-blocks/'+project_name+'_Priv') == 'error': payload = {"cidr":"10.99.0.0/16","visibility":"PRIVATE"} result = nsx_put_call(nsx_manager, '/policy/api/v1/orgs/default/projects/'+project_name+'/infra/ip-blocks/'+project_name+'_Priv', payload) #Create VPC print ('. Create VPC: '+ vpc_name) payload = { "default_gateway_path": "/infra/tier-0s/ef4c052c-dbcc-4750-a706-d71a21e5bcf9", \ "site_infos": [ \ { \ "edge_cluster_paths": [ \ "/infra/sites/default/enforcement-points/default/edge-clusters/7a7c5b8a-e8f2-47b9-9017-bc5d66e8cb24" \ ], \ "site_path": "/infra/sites/default" \ } \ ], \ "ip_address_type": "IPV4", \ "external_ipv4_blocks": [ \ "/infra/ip-blocks/Project_Ext" \ ], \ "private_ipv4_blocks": [ \ "/orgs/default/projects/"+project_name+"/infra/ip-blocks/"+project_name+"_Priv" \ ], \ "service_gateway": { \ "disable": "false", \ "auto_snat": "true" \ }, \ "activate_default_dfw_rules": "false", \ "dhcp_config": { \ "enable_dhcp": "true" \ }, \ "load_balancer_vpc_endpoint": { \ "enabled": "false" \ } \ } result = nsx_put_call(nsx_manager, '/policy/api/v1/orgs/default/projects/'+project_name+'/vpcs/'+vpc_name, payload) ''' #Add local user vpc_user to VPC #Check if user vpc_user is created if nsx_find_user_id(nsx_manager, '/api/v1/node/users', vpc_user) == 'error': payload = {"username": vpc_user} result = nsx_post_call(nsx_manager, '/api/v1/node/users?action=create_user', payload) print ('. Add user '+vpc_user) #Check if user vpc_user is enabled if nsx_find_user_status(nsx_manager, '/api/v1/node/users', vpc_user) == 'NOT_ACTIVATED': user_id = nsx_find_user_id(nsx_manager, '/api/v1/node/users', vpc_user) payload = {"password":"VMware1!VMware1!"} result = nsx_post_call(nsx_manager, '/api/v1/node/users/'+str(user_id)+'?action=activate', payload) print ('. User '+vpc_user+' enabled') #Add user vpc_user as VPC-Admin of VPC result = nsx_user_vpc_admin(nsx_manager, '/api/v1/aaa/role-bindings', vpc_user, project_name, vpc_name) print ('. User '+vpc_user+' is VPC Admin of '+vpc_name) ''' #Add AD Group ad_group to VPC print ('. AD Group "'+ad_group+'" is VPC Admin of '+vpc_name) result = nsx_ldap_user_vpc_admin(nsx_manager, '/api/v1/aaa/role-bindings', ad_group, project_name, vpc_name) end_time= datetime.datetime.now() print ('') print ('') print ('script started at ' + start_time.strftime("%Y-%m-%d %H:%M:%S")) print ('script ended at ' + end_time.strftime("%Y-%m-%d %H:%M:%S")) total_time = end_time - start_time print ('total time '+str(total_time).split(".")[0]) input("Press Enter to continue...") |
The following settings in the scripts above will have to be updated to match your environment:
- In both files:
- Update Tier-0 information with yours
"/infra/tier-0s/ef4c052c-dbcc-4750-a706-d71a21e5bcf9"
You can find your Tier-0 ID from NSX Mgr UI
- Update Edge Cluster information with yours
"/infra/sites/default/enforcement-points/default/edge-clusters/7a7c5b8a-e8f2-47b9-9017-bc5d66e8cb24"
You can find your Edge Cluster ID from NSX Mgr UI
- Update Tier-0 information with yours
Creation of vCenter Permissions for each application
Root (.bat) script “create-Microsoft-AD-Group_Marketing.bat”
1 |
"C:\Program Files\PowerShell\7\pwsh.exe" code\vcenter-permissions.ps1 -ad_group VMware_VCF_VPC_Mar_Admins -folder_name VM_Marketing -vpc_name VPC_Mar |
C:\Program Files\PowerShell\7\pwsh.exe
Location of PowerShell executable.
code\vcenter-permissions.ps1
Location of the PowerShell script
-ad_group VMware_VCF_VPC_Mar_Admins -folder_name VM_Marketing -vpc_name VPC_Mar
Script parameters:- ad_group = AD Group name
- folder_name = vCenter VM folder name to create
- vpc_name = VPC name
PowerShell script “vcenter-permissions.ps1”
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 |
# ./vcenter-permissions.ps1 -ad_group VMware_VCF_VPC_Mar_Admins -folder_name VM_Marketing -vpc_name VPC_Mar param ($ad_group , $folder_name, $vpc_name) Write-Output "======================================================================================================" Write-Output "Create vCenter permissions for AD Group $ad_group" Write-Output " + Create a vCenter VM folder $folder_name" Write-Output " + Add permissions AD Group $ad_group in vCenter VM folder $folder_name " Write-Output " + Add permissions AD Group $ad_group in vCenter Network folder $vpc_name" Write-Output "======================================================================================================" Connect-VIServer -Server vcenter-vi1-paris.corp.vmbeans.com -Protocol https -User administrator@corp.vmbeans.com -Password VMware1!VMware1! ### #Create VM folder ### Write-Output " . Create in vCenter VM folder $folder_name" New-Folder -Name $folder_name -Location (Get-Folder vm) | Out-Null ### #Add permissions for AD Group in vCenter folder ### Write-Output " . Add permissions for Microsoft AD Group $ad_group for the vCenter VM folder $folder_name" $folder = Get-Folder $folder_name $roleName = "developer-role" $authMgr = Get-View AuthorizationManager $roleId = ($authMgr.RoleList | where {$_.Name -eq $roleName}).RoleId[0] $spec = New-Object VMware.Vim.Permission $spec.Group = $true $spec.principal = "corp.vmbeans.com\$ad_group" $spec.propagate = $true $spec.roleid = $roleId $authMgr.SetEntityPermissions($folder.Extensiondata.MoRef,@($spec)) ### #Add permissions for AD Group in vCenter Network VPC ### Write-Output " . Add permissions for Microsoft AD Group $ad_group for the vCenter Network folder $vpc_name" $folder = Get-Folder $vpc_name $roleName = "developer-role" $authMgr = Get-View AuthorizationManager $roleId = ($authMgr.RoleList | where {$_.Name -eq $roleName}).RoleId[0] $spec = New-Object VMware.Vim.Permission $spec.Group = $true $spec.principal = "corp.vmbeans.com\$ad_group" $spec.propagate = $true $spec.roleid = $roleId $authMgr.SetEntityPermissions($folder.Extensiondata.MoRef,@($spec)) cmd /c 'pause' |