🥦

AWS Config のSchema情報が見つからないのでContributeする

2022/07/09に公開

はじめに

https://zenn.dev/watany/articles/472889670b8f82

前の記事で紹介したAWS Config Resource Schemaだが、ファイルが軒並み3 years agoなどで少々怪しい。ちょっと様子を見てみよう、からPull Requestを出すことになったので、記録としてまとめる。半分は手順メモ代わり。

おさらい - AWS Config Resource Schema

https://github.com/awslabs/aws-config-resource-schema

AWS Config Resource Schemaは読んで字のごとく、AWS Configで記録されるデータのスキーマである。

前記事で紹介したように記録したデータをConfigRuleで評価したり、記録したデータへクエリを投げて解析したりするのが主な使い道。
https://dev.classmethod.jp/articles/aws-config-new-feature-advanced-query/

大きな問題として、このスキーマは公式ドキュメントでなく、awslabリポジトリでの管理という点があげられる。
わからない人向けに説明すると、awslabはAWS公式であるとはいえ、ドキュメントに比べ管理レベルが一段落ちるためメンテナンスの状況がまちまちなのである。念のため中身を確認してみよう。

現状把握

https://docs.aws.amazon.com/config/latest/developerguide/resource-config-reference.html

AWS Config Resource Schemaと公式ドキュメントの対応サービスを比較すると、適当に見るだけでもECR,ECS,EKSなどの主要サービスが含まれていない……これは何とかせねば!
3 years agoで察してはいた。

プルリクのためのステップ

今回はAWS::ECR::Repositoryを対応してみる。ステップは下記。なかなか泥臭い。

  1. データ収集
  2. 加工
  3. 型を埋める

1. データ収集

適当にECRリポジトリを作成して、ConfigRecorderで収集する。
未設定部は空欄となるため、データ型が分からないので、可能な限り設定がすべて有効になるまで頑張る。

{
  "version": "1.3",
  "accountId": "XXXXXXXXXXXX",
  "configurationItemCaptureTime": "2022-07-06T01:02:44.449Z",
  "configurationItemStatus": "OK",
  "configurationStateId": "1657069364449",
  "configurationItemMD5Hash": "",
  "arn": "arn:aws:ecr:ap-northeast-1:XXXXXXXXXXXX:repository/repo-configtest",
  "resourceType": "AWS::ECR::Repository",
  "resourceId": "repo-configtest",
  "resourceName": "repo-configtest",
  "awsRegion": "ap-northeast-1",
  "availabilityZone": "Regional",
  "tags": {
    "test": "test"
  },
  "relatedEvents": [],
  "relationships": [],
  "configuration": {
    "Arn": "arn:aws:ecr:ap-northeast-1:XXXXXXXXXXXX:repository/repo-configtest",
    "ImageScanningConfiguration": {
      "ScanOnPush": true
    },
    "ImageTagMutability": "IMMUTABLE",
    "RepositoryName": "repo-configtest",
    "LifecyclePolicy": {
      "LifecyclePolicyText": "{\"rules\":[{\"rulePriority\":1,\"description\":\"descrioruin\",\"selection\":{\"tagStatus\":\"untagged\",\"countType\":\"sinceImagePushed\",\"countUnit\":\"days\",\"countNumber\":1},\"action\":{\"type\":\"expire\"}}]}",
      "RegistryId": "XXXXXXXXXXXX"
    },
    "RepositoryPolicyText": "{\n  \"Version\" : \"2008-10-17\",\n  \"Statement\" : [ {\n    \"Sid\" : \"new statement\",\n    \"Effect\" : \"Allow\",\n    \"Principal\" : {\n      \"AWS\" : \"arn:aws:iam::XXXXXXXXXXXX:root\"\n    },\n    \"Action\" : \"ecr:UploadLayerPart\"\n  } ]\n}",
    "Tags": [
      {
        "Key": "test",
        "Value": "test"
      }
    ]
  },
  "supplementaryConfiguration": {},
  "resourceTransitionStatus": "None"
}

このJSONを適当な名前のファイルとして、Gitpodで管理する。

  • 今回は/workspace/aws-config-resource-schema/config/properties/resource-types/tmpとする。

2. 加工

GitHubの他ファイルを見るに、このままでは格納できないので、加工する。

  • JSON Keyのフラット化
  • 並び替え

jqで頑張るのも手だが、この要件ならgronが合いそう。
https://github.com/tomnomnom/gron
gronはJSONのKey-Valueにgrepをかけやすいようにフラット化するツールで、curlのレスポンスにパイプしたりして使うらしい。確かに便利~。今回の要件にもfitしているので楽しちゃおう。

Gitpodで以下の操作をしてみよう。

# gron install
go install github.com/tomnomnom/gron@latest
# work directory
cd config/properties/resource-types

# gronの結果を整形
gron tmp |sed 's/ = /": /g'|sed 's/json./  "/g'|sed 's/;$/,/g' |sed '1c {'|sed '$a }' > AWS\:\:ECR\:\:Repository.properties.json

gronの出力結果を加工してJSONに戻すまでに、思ったよりgron後のシェル芸が多いですね。。。汎用性までは確認できてないのであくまでサンプルレベルということで。

余談

周りに相談したところ、こんな別解も教えてもらいました。 シェル芸しんどくなったらこちらに倒したい。。。!

input = `{ "a": 3, "b": "s", "c": { "x": 3, "y": null } }`;
json = JSON.parse(input);
function genType(s, parent) {
  if (s == null) {
    return `"${parent}": null,\n`;
  } else if (typeof s == "string") {
    return `"${parent}": "string",\n`;
  } else if (typeof s == "number") {
    return `"${parent}": "number",\n`;
  } else {
    // s is object
    const keys = Object.getOwnPropertyNames(s);
    let result = "";
    for (key of keys) {
      result += genType(s[key], parent === "" ? key : `${parent}.${key}`);
    }
    return result;
  }
}
function genSchema(s) {
  return "{\n" + genType(s, "") + "}\n";
}
console.log(genSchema(json));

3. 型を埋める

JSONのKeyは完成したので、Valueを埋めてみる。
各パラメータの型を入力する。基本的にCloudFormationを参考にすると良さそう。

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ecr-repository.html

というわけで

無事Pull Requestを出せました。
https://github.com/awslabs/aws-config-resource-schema/pull/29
早く取り込まれるといいな。一緒に手伝ってくれる人はいつでも募集中です。

Discussion