ここまでの PowerNSX でのテナント追加と削除を、
簡易的なスクリプトにして省力化してみようと思います。
これまでの流れについて。
PowerNSX でテナント追加の自動化をしてみる。Part.1
PowerNSX でテナント追加の自動化をしてみる。Part.2
PowerNSX でテナント追加の自動化をしてみる。Part.3
ここまで実施してきたことを参考に、スクリプト化してみます。
今回の環境は、複雑になりすぎないようにあえてシンプルな構成にしています。
たとえば、下記のような感じです。
- テナントごとに、論理スイッチ(VXLAN)は 1つだけ。
- ファイアウォール ルールの通信元 / 通信先 やサービスなどは 1つしか指定しない。
- VM の vNIC は 1つだけ。
実際の環境で使用する場合は、オブジェクトの確認やエラー制御などが必要に
なりますが、今回はできるだけ省略しています。
作成する環境の構成について。
設定値については、スクリプトとは別のファイルに分割してみました。
テナント ネットワークにかかわる設定値と、
テナント内の VM にかかわる設定値を、それぞれファイルを分けてみました。
NSX Edge(Edge Service Gateway と DLR Control VM)については、
はじめから Object ID を確認しておいて決め打ちしています。
下記のような構成にしています。
テナント ネットワークの構成ファイル。
テナントの名前として、tenant-04 という文字列を使っています。
ファイル名: nw_tenant-04.ps1
# テナント固有 変数
$tenant_name = "tenant-04"
$gw_addr = "10.1.40.1"
$nw_addr = "10.1.40.0"
$nw_msak_length = 24
# 共通 変数
$tz_name = "tz01"
$dlr_id = "edge-5"
$esg_id = "edge-1"
$esg_ext_addr = "192.168.1.144"
$jbox_ip = "192.168.1.223"
$dlr_if_name = "if-" + $tenant_name
$dfw_section_name = "dfw-section-" + $tenant_name
$ls_name = "ls-" + $tenant_name
VM 1台目(vm41)の構成ファイル。
ファイル名: vm_vm41.ps1
# VM 固有 変数
$vm_name = "vm41"
$ip_addr = "10.1.40.101"
$vnic_name = "Network adapter 1"
$template_name = "photon-1.0-rev2"
# テナント内共通 変数
$nw_msak = "255.255.255.0"
$tenant_dns = "10.1.1.1"
$domain_name = "go-lab.jp"
$cluster_name = "nsx-cluster-01"
$datastore_name = "ds_nfs_lab02"
VM 2台目(vm42)の構成ファイル。
1台目との差分は VM 名と IP アドレスだけにしています。
ファイル名: vm_vm42.ps1
# VM 固有 変数
$vm_name = "vm42"
$ip_addr = "10.1.40.102"
$vnic_name = "Network adapter 1"
$template_name = "photon-1.0-rev2"
# テナント内共通 変数
$nw_msak = "255.255.255.0"
$tenant_dns = "10.1.1.1"
$domain_name = "go-lab.jp"
$cluster_name = "nsx-cluster-01"
$datastore_name = "ds_nfs_lab02"
テナント作成と VM の追加のスクリプト例。
PowerNSX でテナント追加の自動化をしてみる。Part.1のように、
ネットワーク環境と VM を作成して、VM をネットワーク(論理スイッチ)に接続します。
テナントの作成 スクリプトの内容。
1つ目の引数で、テナントネットワークの構成ファイルを指定しています。
ファイル名: add_tenant_nw.ps1
$tenant_nw_config = $args[0]
. $tenant_nw_config
# テナント 論理スイッチ作成
$tz = Get-NsxTransportZone -name $tz_name
$ls = New-NsxLogicalSwitch -TransportZone $tz -Name $ls_name
$ls | % {"Logical Switch: " + $_.name + " => objectId: " + $_.objectId}
# DLR 接続
$dlr = Get-NsxLogicalRouter -objectId $dlr_id
$dlr_if = $dlr | New-NsxLogicalRouterInterface `
-Type internal -PrimaryAddress $gw_addr -SubnetPrefixLength $nw_msak_length `
-ConnectedTo $ls -Name $dlr_if_name
$dlr_if | select -ExpandProperty interface |
% {"DLR Interface: " + $_.name + " => index: " + $_.index}
# SNAT ルール追加
$nat_original_addr = $nw_addr + "/" + $nw_msak_length
$esg = Get-NsxEdge -objectId $esg_id
$snat_rule = $esg | Get-NsxEdgeNat | New-NsxEdgeNatRule `
-Vnic 0 -action snat `
-OriginalAddress $nat_original_addr -TranslatedAddress $esg_ext_addr
$snat_rule | % {"SNAT Source Address: " + $_.originalAddress + " => ruleId " + $_.ruleId}
# DFW ルール追加
$dfw_section = New-NsxFirewallSection -Name $dfw_section_name
$dfw_section | % {"DFW Section: " + $_.name + " => id " + $_.id}
$dfw_rule_name = "allow jBox to tenant-ls SSH"
$dfw_section = Get-NsxFirewallSection -objectId $dfw_section.id
$svc = Get-NsxService -Name SSH | where {$_.isUniversal -eq $false}
$dfw_rule = $dfw_section | New-NsxFirewallRule -Name $dfw_rule_name `
-Action allow -Source $jbox_ip -Destination $ls -Service $svc -AppliedTo $ls
$dfw_rule | % {"DFW Rule: " + $_.name + " => id " + $_.id}
$dfw_rule_name = "allow Any to tenant-ls HTTP"
$dfw_section = Get-NsxFirewallSection -objectId $dfw_section.id
$svc = Get-NsxService -Name HTTP | where {$_.isUniversal -eq $false}
$dfw_rule = $dfw_section | New-NsxFirewallRule -Name $dfw_rule_name `
-Action allow -Destination $ls -Service $svc -AppliedTo $ls
$dfw_rule | % {"DFW Rule: " + $_.name + " => id " + $_.id}
$vm_folder = Get-Folder -Type VM vm | New-Folder -Name $tenant_name
$vm_folder | % {"VM Folder: " + $_.Name + " => id " + $_.ExtensionData.MoRef.Value}
少し長いスクリプトですが、実行すると下記のような出力結果となります。
VM の追加 スクリプトの内容。
1つ目の引数で、テナントネットワークの構成ファイルを指定して、
2つ目の引数で、VM の構成ファイルを指定しています。
ファイル名: add_tenant_vm.ps1
$tenant_nw_config = $args[0]
. $tenant_nw_config
$tenant_vm_config = $args[1]
. $tenant_vm_config
$ls = Get-NsxTransportZone -name $tz_name | Get-NsxLogicalSwitch -Name $ls_name
"Create Guest OS Customization Spec: " + $os_spec_name
$os_spec_name = "osspec-" + $vm_name
$spec = New-OSCustomizationSpec -Name $os_spec_name `
-OSType Linux -DnsServer $tenant_dns -Domain $domain_name
"Edit Guest OS Customization Spec: " + $_.Name
$spec | Get-OSCustomizationNicMapping |
Set-OSCustomizationNicMapping -IpMode UseStaticIP `
-IpAddress $ip_addr -SubnetMask $nw_msak -DefaultGateway $gw_addr | Out-Null
$vm = Get-Template -Name $template_name |
New-VM -Name $vm_name -Location (Get-Folder -Type VM $tenant_name) `
-ResourcePool $cluster_name -Datastore $datastore_name -OSCustomizationSpec $spec
$vm | % {"New VM: " + $_.Name + " => id " + $_.ExtensionData.MoRef.Value}
"Delete Guest OS Customization Spec: " + $spec.Name
$spec | Remove-OSCustomizationSpec -Confirm:$false
"Connect vNIC: " + ($vm.Name + "/" + $vnic_name + " to " + $ls.Name)
$vm | Get-NetworkAdapter -Name $vnic_name | Connect-NsxLogicalSwitch $ls
$vm | Start-VM | % {"Start VM: " + $_.Name}
テナント情報取得スクリプトの例。
PowerNSX でテナント追加の自動化をしてみる。Part.2で確認したような情報を取得してみます。
しかし、あまり詳細な情報までとらず、特徴的なサマリを表示するようにしてみました。
https://gist.github.com/gowatana/0dfab57feb0598452bccf2448c45f4d9
テナント情報取得スクリプトの内容。
1つ目の引数で、テナントネットワークの構成ファイルを指定しています。
ファイル名: get_tenant_summary.ps1
$tenant_nw_config = $args[0]
. $tenant_nw_config
function format_output ($title, $object) {
"=" * 60
$title
""
($object | Out-String).Trim()
""
}
"#" * 60
"テナント: " + $tenant_name
"実行時刻: " + (Get-Date).DateTime
""
$ls = Get-NsxTransportZone $tz_name | Get-NsxLogicalSwitch -Name $ls_name
$ls_id = $ls.objectId
$dvpg = $ls | Get-NsxBackingPortGroup
$dlr = Get-NsxLogicalRouter -objectId $dlr_id
$dlr_if = $dlr | Get-NsxLogicalRouterInterface | where {$_.connectedToId -eq $ls_id}
$dlr_if_addr = $dlr_if.addressGroups.addressGroup | %{$_.primaryAddress + "/" + $_.subnetPrefixLength}
$ls_info = $ls | fl `
name,
objectId,
@{N="VDSwitch";E={$dvpg.VDSwitch.Name}},
@{N="dvPortgroup";E={$dvpg.Name}},
@{N="DlrIfIPAddress";E={$dlr_if_addr}}
format_output "Tenant Network" $ls_info
$esg = Get-NsxEdge -objectId $esg_id
$nat_original_addr = $nw_addr + "/" + $nw_msak_length
$snat_rule = $esg | Get-NsxEdgeNat | Get-NsxEdgeNatRule |
where {$_.originalAddress -eq $nat_original_addr}
$snat_rule_info = $snat_rule | fl translatedAddress,originalAddress
format_output "ESG SNAT ルール情報" $snat_rule_info
$dfw_section = Get-NsxFirewallSection -Name $dfw_section_name
$dfw_rules = $dfw_section.rule
$dfw_rules_info = $dfw_rules | select `
id,
name,
@{N="Src";E={
$member = $_ | Get-NsxFirewallRuleMember |
where {$_.MemberType -eq "Source"} |
% {if($_.Name -eq $null){$_.Value}else{$_.Name}
}
if(($member).Count -eq 0){$member = "Any"}
$member
}
},
@{N="Dst";E={
$member = $_ | Get-NsxFirewallRuleMember |
where {$_.MemberType -eq "Destination"} |
% {if($_.Name -eq $null){$_.Value}else{$_.Name}
}
if(($member).Count -eq 0){$member = "Any"}
$member
}
},
@{N="Service";E={$_.services.service.name}},
action,
@{N="appliedTo";E={$_.appliedToList.appliedTo.name}},
logged | ft -AutoSize
format_output ("DFWセクション" + $dfw_section.name + "ルール情報") $dfw_rules_info
# 論理スイッチに接続されているVMの情報
$vms = $ls | Get-NsxBackingPortGroup | Get-VM | sort Name
$vm_info = $vms | % {
$vm = $_
$guest = $_ | Get-VmGuest
$vm | select `
@{N="VM";E={$_.Name}},
@{N="HostName";E={$_.Guest.ExtensionData.HostName}},
@{N="State";E={$_.Guest.State}},
@{N="IPAddress";E={
$_.Guest.ExtensionData.Net.IpConfig.IpAddress |
where {$_.PrefixLength -le 32} |
% {$_.IpAddress + "/" + $_.PrefixLength}
}
},
@{N="Gateway";E={
$guest_dgw = $_.Guest.ExtensionData.IpStack.IpRouteConfig.IpRoute |
where {$_.Network -eq "0.0.0.0"}
$guest_dgw.Gateway.IpAddress
}
},
@{N="GuestFullName";E={$_.Guest.ExtensionData.GuestFullName}}
} | ft -AutoSize
format_output "VM / ゲスト ネットワーク情報" $vm_info
テナント削除スクリプトの例。
PowerNSX でテナント追加の自動化をしてみる。Part.3のように、
VM を削除して、論理スイッチも削除します。
特に対話的な確認メッセージもなく、一気に削除するようにしています。
テナント削除 スクリプトの内容。
1つ目の引数で、テナントネットワークの構成ファイルを指定しています。
ファイル名: delete_tenant.ps1
$tenant_nw_config = $args[0]
. $tenant_nw_config
$ls = Get-NsxTransportZone $tz_name | Get-NsxLogicalSwitch -Name $ls_name
"Remove VM"
$ls | Get-NsxBackingPortGroup | Get-VM | Stop-VM -Confirm:$false | Out-Null
$ls | Get-NsxBackingPortGroup | Get-VM | Remove-VM -DeletePermanently -Confirm:$false
"Remove DFW Rule"
Get-NsxFirewallSection -Name $dfw_section_name |
Remove-NsxFirewallSection -force -Confirm:$false
"Remove SNAT Rule"
$nat_original_addr = $nw_addr + "/" + $nw_msak_length
Get-NsxEdge -objectId $esg_id | Get-NsxEdgeNat | Get-NsxEdgeNatRule |
where {$_.originalAddress -eq $nat_original_addr} |
Remove-NsxEdgeNatRule -Confirm:$false
"Remove NsxLogical Switch"
Get-NsxLogicalRouter -objectId $dlr_id | Get-NsxLogicalRouterInterface |
where {$_.connectedToId -eq $ls.objectId} |
Remove-NsxLogicalRouterInterface -Confirm:$false
$ls | Remove-NsxLogicalSwitch -Confirm:$false
"Remove VM Folder"
Get-Folder -Type VM $tenant_name | Remove-Folder -Confirm:$false
まだつづく。