こんにちは!コンサル部のinomaso(@inomasosan)です。
前回、AWS Config アグリゲータで、Advanced Queryに対応していない起動テンプレートの情報を取得するためのサンプルコードを作成してみました。
ただ、出力結果の一部にエスケープ処理されたJSON文字列がありました。
そこから必要な情報を取得しようとしたところ、なかなか時間がかかってしまったので備忘として残しておきます。
エスケープ処理されたJSON文字列とは?
以下は起動テンプレートの出力結果となります。
出力結果
{
"ConfigurationItem": {
"version": "1.3",
"accountId": "1234567890",
"configurationItemCaptureTime": "2023-09-14T08:53:54.339000+00:00",
"configurationItemStatus": "OK",
"configurationStateId": "1694681634339",
"configurationItemMD5Hash": "",
"arn": "arn:aws:ec2:ap-northeast-1:1234567890:launch-template/lt-07cae1e5cb08b09f7",
"resourceType": "AWS::EC2::LaunchTemplate",
"resourceId": "lt-07cae1e5cb08b09f7",
"resourceName": "asg-web-template",
"awsRegion": "ap-northeast-1",
"availabilityZone": "Regional",
"tags": {},
"relatedEvents": [],
"relationships": [],
"configuration": "{\"LaunchTemplateName\":\"asg-web-template\",\"Id\":\"lt-07cae1e5cb08b09f7\",\"LaunchTemplateData\":{\"EbsOptimized\":false,\"BlockDeviceMappings\":[{\"DeviceName\":\"/dev/xvda\",\"Ebs\":{\"Encrypted\":false,\"DeleteOnTermination\":true,\"VolumeSize\":8,\"VolumeType\":\"gp2\"}}],\"NetworkInterfaces\":[{\"AssociatePublicIpAddress\":true,\"DeleteOnTermination\":true,\"Description\":\"Primary network interface\",\"DeviceIndex\":0,\"Groups\":[\"sg-07b90410018cd1533\"],\"Ipv6Addresses\":[],\"PrivateIpAddresses\":[],\"Ipv4Prefixes\":[],\"Ipv6Prefixes\":[]}],\"ImageId\":\"ami-09ebacdc178ae23b7\",\"InstanceType\":\"t2.micro\",\"KeyName\":\"aws-ssh-key\",\"Monitoring\":{\"Enabled\":false},\"Placement\":{\"Tenancy\":\"default\"},\"DisableApiTermination\":false,\"UserData\":\"IyEvYmluL2Jhc2gKeXVtIHVwZGF0ZSAteQp5dW0gaW5zdGFsbCAteSBodHRwZApzeXN0ZW1jdGwgc3RhcnQgaHR0cGQuc2VydmljZQpzeXN0ZW1jdGwgZW5hYmxlIGh0dHBkLnNlcnZpY2UKZWNobyDigJxIZWxsbyBXb3JsZCBmcm9tICQoaG9zdG5hbWUgLWYp4oCdID4gL3Zhci93d3cvaHRtbC9pbmRleC5odG1s\",\"TagSpecifications\":[],\"ElasticGpuSpecifications\":[],\"ElasticInferenceAccelerators\":[],\"SecurityGroupIds\":[],\"SecurityGroups\":[],\"CreditSpecification\":{\"CpuCredits\":\"standard\"},\"CapacityReservationSpecification\":{\"CapacityReservationPreference\":\"open\"},\"LicenseSpecifications\":[],\"MetadataOptions\":{\"HttpTokens\":\"optional\",\"HttpPutResponseHopLimit\":1,\"HttpEndpoint\":\"enabled\"}},\"DefaultVersionNumber\":\"1\",\"LatestVersionNumber\":\"2\",\"TagSpecifications\":[]}",
"supplementaryConfiguration": {}
}
}
18行目の"configuration"
を見て頂けると分かる通り、JSONの中にJSONが埋まる形でエスケープ処理されたJSON文字列が出力されています。
ここから特定の値を取得するためには、前処理として整形から実施していく必要があります。
エスケープ処理された文字列を整形
まずは、エスケープ処理されたjson文字列を、fromjson
で見やすく整形していきます。
コマンド
aws configservice list-aggregate-discovered-resources \
--configuration-aggregator-name hoge \
--resource-type AWS::EC2::LaunchTemplate \
--query "ResourceIdentifiers[*].[SourceAccountId, SourceRegion, ResourceId, ResourceType]" \
--output text | while read line
do
SourceAccountId=$(echo $line | awk '{print $1}')
SourceRegion=$(echo $line | awk '{print $2}')
ResourceId=$(echo $line | awk '{print $3}')
ResourceType=$(echo $line | awk '{print $4}')
#EOSの行はスペースを省略しないとエラーになる。ただし一つ目のEOSの行はスペースがあっても良い
json=$(tr -d ' |\n' << EOS
{
"SourceAccountId" : "$SourceAccountId",
"SourceRegion" : "$SourceRegion",
"ResourceId" : "$ResourceId",
"ResourceType" : "$ResourceType"
}
EOS
)
aws configservice get-aggregate-resource-config \
--configuration-aggregator-name hoge \
--resource-identifier $json \
| jq '.ConfigurationItem.configuration | fromjson'
done
エスケープ処理された出力結果と比較して、だいぶ見やすくなったことがわかります。
出力結果
{
"LaunchTemplateName": "asg-web-template",
"Id": "lt-07cae1e5cb08b09f7",
"LaunchTemplateData": {
"EbsOptimized": false,
"BlockDeviceMappings": [
{
"DeviceName": "/dev/xvda",
"Ebs": {
"Encrypted": false,
"DeleteOnTermination": true,
"VolumeSize": 8,
"VolumeType": "gp2"
}
}
],
"NetworkInterfaces": [
{
"AssociatePublicIpAddress": true,
"DeleteOnTermination": true,
"Description": "Primary network interface",
"DeviceIndex": 0,
"Groups": [
"sg-07b90410018cd1533"
],
"Ipv6Addresses": [],
"PrivateIpAddresses": [],
"Ipv4Prefixes": [],
"Ipv6Prefixes": []
}
],
"ImageId": "ami-09ebacdc178ae23b7",
"InstanceType": "t2.micro",
"KeyName": "aws-ssh-key",
"Monitoring": {
"Enabled": false
},
"Placement": {
"Tenancy": "default"
},
"DisableApiTermination": false,
"UserData": "IyEvYmluL2Jhc2gKeXVtIHVwZGF0ZSAteQp5dW0gaW5zdGFsbCAteSBodHRwZApzeXN0ZW1jdGwgc3RhcnQgaHR0cGQuc2VydmljZQpzeXN0ZW1jdGwgZW5hYmxlIGh0dHBkLnNlcnZpY2UKZWNobyDigJxIZWxsbyBXb3JsZCBmcm9tICQoaG9zdG5hbWUgLWYp4oCdID4gL3Zhci93d3cvaHRtbC9pbmRleC5odG1s",
"TagSpecifications": [],
"ElasticGpuSpecifications": [],
"ElasticInferenceAccelerators": [],
"SecurityGroupIds": [],
"SecurityGroups": [],
"CreditSpecification": {
"CpuCredits": "standard"
},
"CapacityReservationSpecification": {
"CapacityReservationPreference": "open"
},
"LicenseSpecifications": [],
"MetadataOptions": {
"HttpTokens": "optional",
"HttpPutResponseHopLimit": 1,
"HttpEndpoint": "enabled"
}
},
"DefaultVersionNumber": "1",
"LatestVersionNumber": "2",
"TagSpecifications": []
}
整形した文字列から必要な情報を抽出
先ほど整形した文字列から、JSON形式でセキュリティグループID関連の情報を取得してみます。
コマンド
aws configservice list-aggregate-discovered-resources \
--configuration-aggregator-name hoge \
--resource-type AWS::EC2::LaunchTemplate \
--query "ResourceIdentifiers[*].[SourceAccountId, SourceRegion, ResourceId, ResourceType]" \
--output text | while read line
do
SourceAccountId=$(echo $line | awk '{print $1}')
SourceRegion=$(echo $line | awk '{print $2}')
ResourceId=$(echo $line | awk '{print $3}')
ResourceType=$(echo $line | awk '{print $4}')
#EOSの行はスペースを省略しないとエラーになる。ただし一つ目のEOSの行はスペースがあっても良い
json=$(tr -d ' |\n' << EOS
{
"SourceAccountId" : "$SourceAccountId",
"SourceRegion" : "$SourceRegion",
"ResourceId" : "$ResourceId",
"ResourceType" : "$ResourceType"
}
EOS
)
aws configservice get-aggregate-resource-config \
--configuration-aggregator-name hoge \
--resource-identifier $json \
| jq '.ConfigurationItem.configuration | fromjson' | jq '{LaunchTemplateName: .LaunchTemplateName, Id: .Id,Groups: .LaunchTemplateData.NetworkInterfaces[].Groups[]}'
done
出力結果
{
"LaunchTemplateName": "asg-web-template",
"Id": "lt-07cae1e5cb08b09f7",
"Groups": "sg-07b90410018cd1533"
}
まとめ
エスケープ処理されたJSON文字列を最初に見たときは面食らいました。
jq
での必要な情報の抽出は、インターネット上での情報収集に苦労したため今回まとめてみました。
この記事が、どなたかのお役に立てば幸いです。それでは!