Отчет об объектах AWS в PowerShell

15.05.2018

Для тех кто пользуется Amazon Web Services было бы полезным иметь инструмент для выгрузки списка используемых ресурсов в виде таблицы. Для решения этой задачи я написал скрипт на Powershell.

Для того, чтобы воспользоваться скриптом, нужно:
- Установить библиотеки AWS SDK for .NET, которые будут вызываться из скрипта PowerShell.
- Создать служебного пользователя в сервисе IAM консоли AWS.
- Назначить служебному пользователю права на чтение объектов EC2 и RDS (права описаны ниже).
- В скрипте PowerShell обозначить входные данные: номер аккаунта AWS, регион, учетные данные служебного пользователя.

Листинг скрипта для получения отчета по объектам EC2 и RDS из консоли AWS:

# AWS variables
$AWSAccountID = [your AWS account number]
$AWSRegion = [AWS region to report]
$AWSProfileAccessKey = "service user access key"
$AWSProfileSecretKey = "service user secret key"

# Registering AWS libraries
Add-Type -Path "C:\Program Files (x86)\AWS SDK for .NET\bin\Net45\AWSSDK.Core.dll"

Function Write-ScriptLog {
 Param(
   [CmdletBinding()]
   [Parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
   [String]$Message,
   [Parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
   [String]$LogFile
 )
 Process {
   $LogMessage = Get-Date -uformat "%d.%m.%Y %H:%M:%S"
   $LogMessage += "`t"
   $LogMessage += $Message
   $LogMessage | Out-File -FilePath $LogFile -Append
 }
}#End Function

# --- Start ---

# Calculating variables
$CurrentDate = Get-Date
$ScriptFolder = $MyInvocation.MyCommand.Path.SubString(0,($MyInvocation.MyCommand.Path.Length - $MyInvocation.MyCommand.Name.Length))

# Reset report
$EC2Report = @()
$RDSReport = @()

# Get list of VPCs
$VPCs = Get-EC2Vpc -Region $AWSRegion -AccessKey $AWSProfileAccessKey -SecretKey $AWSProfileSecretKey

# Get list of instances
$EC2Instances = (Get-EC2Instance -Region $AWSRegion -AccessKey $AWSProfileAccessKey -SecretKey $AWSProfileSecretKey).Instances

# Create the report per VPC
ForEach ($VPC in $VPCs) {
 $EC2Instances | Where-Object {$_.VpcId -eq $VPC.VpcId} | ForEach {
   $EC2InstanceProperties = New-Object -TypeName PSObject -Property @{
     'VPC-Id' = $_.VpcId
     'VPC-Name' = ($VPC.Tags | Where-Object {$_.Key -eq 'Name'}).Value
     'Instance-Id' = $_.InstanceId
     'Instance-Name' = ($_.Tags | Where-Object {$_.Key -eq 'Name'}).Value
     'Instance-LaunchTime' = $_.LaunchTime
     'Instance-Type' = $_.InstanceType
     'Instance-PrivateIpAddress' = $_.PrivateIpAddress
     'Instance-State' = $_.State.Name
     'Instance-Key' = $_.KeyName
     'Instance-Description' = ($_.Tags | Where-Object {$_.Key -eq 'Description'}).Value
     'Instance-Project' = ($_.Tags | Where-Object {$_.Key -eq 'Project code'}).Value
     'Instance-ProjectName' = ($_.Tags | Where-Object {$_.Key -eq 'Project name'}).Value
     'Instance-Responsible' = ($_.Tags | Where-Object {$_.Key -eq 'Responsible'}).Value
     'Instance-Platform' = $_.Platform
   }
   $EC2Report += $EC2InstanceProperties
 }
}

$EC2Report | Select 'Instance-Name', 'Instance-Description', 'Instance-Project', 'Instance-Id', 'Instance-Platform', 'Instance-Type', `
 'VPC-Name', 'VPC-Id', 'Instance-PrivateIpAddress', 'Instance-LaunchTime', 'Instance-State', 'Instance-ProjectName', 'Instance-Key', `
 'Instance-Responsible' | Sort -Property ('VPC-Name', 'Instance-Name') | Export-Csv -Path ($ScriptFolder + 'AWS-EC2Instances.csv') `
 -Encoding UTF8 -NoTypeInformation


$RDSInstances = Get-RDSDBInstance -Region $AWSRegion -AccessKey $AWSProfileAccessKey -SecretKey $AWSProfileSecretKey

ForEach ($VPC in $VPCs) {
 $RDSInstances | Where-Object {$_.DBSubnetGroup.VpcId -eq $VPC.VpcId} | ForEach {
   $RDSInstanceTags = Get-RDSTagForResource -ResourceName $_.DBInstanceArn -Region $AWSRegion -AccessKey $AWSProfileAccessKey `
     -SecretKey $AWSProfileSecretKey
   $RDSInstanceProperties = New-Object -TypeName PSObject -Property @{
     'VPC-Id' = $_.DBSubnetGroup.VpcId
     'VPC-Name' = ($VPC.Tags | Where-Object {$_.Key -eq 'Name'}).Value
     'Instance-Name' = $_.DBInstanceIdentifier
     'Instance-EndPoint' = $_.Endpoint.Address
     'Instance-CreateTime' = $_.InstanceCreateTime
     'Instance-Type' = $_.DBInstanceClass
     'Instance-StorageSize' = $_.AllocatedStorage
     'Instance-AvailabilityZone' = $_.AvailabilityZone
     'Instance-State' = $_.DBInstanceStatus
     'Instance-Platform' = $_.Engine
     'Instance-IOps' = $_.Iops
     'Instance-Description' = ($RDSInstanceTags | Where-Object {$_.Key -eq 'Description'}).Value
     'Instance-Project' = ($RDSInstanceTags | Where-Object {$_.Key -eq 'Project code'}).Value
     'Instance-ProjectName' = ($RDSInstanceTags | Where-Object {$_.Key -eq 'Project name'}).Value
     'Instance-Responsible' = ($RDSInstanceTagss | Where-Object {$_.Key -eq 'Responsible'}).Value
   }
   $RDSReport += $RDSInstanceProperties
 }
}

$RDSReport | Select 'Instance-Name', 'Instance-Description', 'Instance-Project', 'Instance-IOps', 'Instance-Platform', 'Instance-Type', `
 'VPC-Name', 'VPC-Id', 'Instance-EndPoint', 'Instance-CreateTime', 'Instance-State', 'Instance-ProjectName', 'Instance-StorageSize', `
 'Instance-AvailabilityZone', 'Instance-Responsible' | Sort -Property ('VPC-Name', 'Instance-Name') | `
 Export-Csv -Path ($ScriptFolder + 'AWS-RDSInstances.csv') -Encoding UTF8 -NoTypeInformation

(Get-RDSTagForResource -ResourceName $RDSInstances[1].DBInstanceArn -Region $AWSRegion -AccessKey $AWSProfileAccessKey `
 -SecretKey $AWSProfileSecretKey).Key['Projectcode']

# --- Stop---

 Листинг прав IAM для служебного пользователя, который используется для выгрузки данных из консоли AWS:

 {
   "Version": "2012-10-17",
   "Statement": [
       {
           "Sid": "VisualEditor0",
           "Effect": "Allow",
           "Action": [
               "ec2:DescribeInstances",
               "ec2:DescribeTags",
               "ec2:DescribeRegions",
               "ec2:DescribeSnapshots",
               "ec2:StopInstances",
               "ec2:DescribeSecurityGroups",
               "ec2:DescribeVolumeAttribute",
               "ec2:DescribeImages",
               "ec2:StartInstances",
               "ec2:DescribeAvailabilityZones",
               "ec2:DescribeVpcs",
               "ec2:DescribeVolumes",
               "ec2:DescribeSubnets",
               "ec2:DescribeKeyPairs",
               "ec2:DescribeInstanceStatus",
               "rds:ListTagsForResource",
               "rds:DescribeDBInstances"
           ],
           "Resource": "*"
       }
   ]
}
Примечание. Здесь для служебного пользователя выданы дополнительные полномочия, чтобы этот пользователь имел возможность перезагружать серверы EC2. Эта опция используется в другом скрипте, предназначенном для быстрого управления серверами без входа в консоль AWS.

Пример отчета по серверам EC2 - файл AWS-EC2Instances.csv

"Instance-Name","Instance-Description","Instance-Project","Instance-Id","Instance-Platform","Instance-Type","VPC-Name","VPC-Id",
 "Instance-PrivateIpAddress","Instance-LaunchTime","Instance-State","Instance-ProjectName","Instance-Key","Instance-Responsible"
"SERVER1","AWS TEST server","INF","i-08993683117971400",,"t2.xlarge","vpc-i-TST","vpc-43a84000",
 "192.168.1.12","09.05.2018 13:29:59","running",,,"Ivanov Vladimir"

Пример отчета по базам данным RDS - файл AWS-RDSInstances.csv

"Instance-Name","Instance-Description","Instance-Project","Instance-IOps","Instance-Platform","Instance-Type","VPC-Name","VPC-Id",
 "Instance-EndPoint","Instance-CreateTime","Instance-State","Instance-ProjectName","Instance-StorageSize","Instance-AvailabilityZone",
 "Instance-Responsible"
"dbs-i-tst",,,"0","postgres","db.t2.large","vpc-i-TST","vpc-43a84000",
 "dbs-i-tst.ctpuy7pji400.eu-west-1.rds.amazonaws.com","27.04.2018 16:44:14","available",,"250","eu-west-1a",
 
Server - AWS instances report
Пример отчета об объектах AWS, сконвертированный в Excel