Skip to content

Instantly share code, notes, and snippets.

@abix-
Last active April 4, 2024 14:16
Show Gist options
  • Save abix-/13d3cb842b46d9e4cab44cb80ed18906 to your computer and use it in GitHub Desktop.
Save abix-/13d3cb842b46d9e4cab44cb80ed18906 to your computer and use it in GitHub Desktop.
#!/usr/bin/env pwsh
# permission denied in AWX? do this: git add --chmod=+x path/to/file
# instance properties to add to _meta
$properties = @("*")
# regex to exclude instance tags
$tagExclusions = "bd_gitpath|workload_type"
# read cloud inventory json
$cloudInventory = Get-Content inventory.json | ConvertFrom-Json
# determine which subprojects are auditable
$auditableSubprojects = $cloudInventory.subprojects | Where-Object { $_.auditable -eq $true }
# ansible inventory scripts should support --list and --host
switch($args[0]) {
"--list" {
$ansibleInventory = New-Object -TypeName PSObject
$meta = @{}
$auditable = New-Object -TypeName System.Collections.Generic.List["string"]
$nonAuditable = New-Object -TypeName System.Collections.Generic.List["string"]
$linux = New-Object -TypeName System.Collections.Generic.List["string"]
$windows = New-Object -TypeName System.Collections.Generic.List["string"]
$dev = New-Object -TypeName System.Collections.Generic.List["string"]
$prod = New-Object -TypeName System.Collections.Generic.List["string"]
$uat = New-Object -TypeName System.Collections.Generic.List["string"]
$test = New-Object -TypeName System.Collections.Generic.List["string"]
foreach($instance in $cloudInventory.instances) {
# ansible uses _meta for host variables instead of executing --host for each host. reduced inventory runtime from 47 seconds to 9 seconds
# format metadata for ansible consumption
$meta[$instance.dns] = @{ instance_data = ($instance | Select-Object $properties) }
# group auditable/nonauditable
if ($auditableSubprojects.id -contains $instance.subprojectId ) {
$auditable.Add($instance.dns)
} else {
$nonAuditable.Add($instance.dns)
}
# group linux/window
if ($instance.ostype -eq "Linux") {
$linux.Add($instance.dns)
} elseif ($instance.ostype -eq "Windows") {
$windows.Add($instance.dns)
}
$subproject = $cloudInventory.subprojects | Where-Object { $_.id -eq $instance.subprojectid }
switch($subproject.environment) {
"dev" { $dev.Add($instance.dns) }
"prod" { $prod.Add($instance.dns) }
"uat" { $uat.Add($instance.dns) }
"test" { $test.Add($instance.dns) }
}
}
# add metadata to inventory
Add-Member -InputObject $ansibleInventory -MemberType NoteProperty -Name "_meta" -Value ([pscustomobject]@{"hostvars" = $meta })
# add auditable groups to inventory
Add-Member -InputObject $ansibleInventory -MemberType NoteProperty -Name "auditable_true" -Value $auditable
Add-Member -InputObject $ansibleInventory -MemberType NoteProperty -Name "auditable_false" -Value $nonAuditable
# add linux/windows to inventory
Add-Member -InputObject $ansibleInventory -MemberType NoteProperty -Name "os_linux" -Value $linux
Add-Member -InputObject $ansibleInventory -MemberType NoteProperty -Name "os_windows" -Value $windows
# add subproject environments to inventory
Add-Member -InputObject $ansibleInventory -MemberType NoteProperty -Name "subproject_environment_dev" -Value $dev
Add-Member -InputObject $ansibleInventory -MemberType NoteProperty -Name "subproject_environment_prod" -Value $prod
Add-Member -InputObject $ansibleInventory -MemberType NoteProperty -Name "subproject_environment_uat" -Value $uat
Add-Member -InputObject $ansibleInventory -MemberType NoteProperty -Name "subproject_environment_test" -Value $test
# create groups for unique tag/value combinations
$tags = $cloudInventory.instances.tags.name | Where-Object { $_ -notmatch "$tagExclusions" } | Select-Object -Unique
foreach ($tag in $tags) {
# get unique tag values
$tagValues = $cloudInventory.instances.tags | Where-Object { $_.name -eq $tag } | Select-Object -ExpandProperty value -Unique | Sort-Object
foreach ($tv in $tagValues) {
# get unique hosts per tag/value combination
$tagHosts = [pscustomobject]@{
hosts = @($cloudInventory.instances | Where-Object { $_.tags.name -eq $tag -and $_.tags.value -eq $tv } | Select-Object -ExpandProperty dns)
}
# add tag groups to inventory
Add-Member -InputObject $ansibleInventory -MemberType NoteProperty -Name "$($tag)_$($tv)" -Value $tagHosts
}
}
# create groups per cloud site
$sites = $cloudInventory.instances.site | Select-Object -Unique
foreach ($site in $sites) {
# get unique instances per site
$siteHosts = [pscustomobject]@{
hosts = @($cloudInventory.instances | Where-Object { $_.site -eq $site } | Select-Object -ExpandProperty dns)
}
# add site groups to inventory
Add-Member -InputObject $ansibleInventory -MemberType NoteProperty -Name "site_$site" -Value $siteHosts
}
# create groups per project
$projects = $cloudInventory.instances.projectid | Select-Object -Unique
foreach ($project in $projects) {
# get unique instances per project
$projectHosts = [pscustomobject]@{
hosts = @($cloudInventory.instances | Where-Object { $_.projectid -eq $project } | Select-Object -ExpandProperty dns)
}
# add project groups to inventory
Add-Member -InputObject $ansibleInventory -MemberType NoteProperty -Name "$project" -Value $projectHosts
}
# create groups per subproject
$subprojects = $cloudInventory.instances.subprojectid | Select-Object -Unique
foreach ($subproject in $subprojects) {
# get unique instances per project
$subprojectHosts = [pscustomobject]@{
hosts = @($cloudInventory.instances | Where-Object { $_.subprojectid -eq $subproject } | Select-Object -ExpandProperty dns)
}
# add project groups to inventory
Add-Member -InputObject $ansibleInventory -MemberType NoteProperty -Name "$subproject" -Value $subprojectHosts
}
# output json
$ansibleInventory | ConvertTo-Json -Depth 100
}
"--host" {
# output json for one host
$dns = $args[1]
@{ instance_data = $cloudInventory.instances | Where-Object { $_.dns -eq $dns } | Select-Object $properties } | ConvertTo-Json -Depth 100
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment