GraphQL によるデータ取得
Shisho Cloud では、リソースの検査や、評価結果(decision)の登録は、ワークフローにて定義されています。また、その検査に必要な検査/監査対象のデータに関しては、ワークフロー内に GraphQL クエリ形式で定義されています。本ページでは、Shisho Cloud における GraphQL の仕様について説明します。なお、ワークフローの詳細については、こちらのページ で詳しく説明しているので、参照してください。
GraphQL は API 向けに作られたクエリ言語で、クライアントが必要とするデータのみを取得できるなど、柔軟なアプローチが特徴です。詳しくは GraphQL (英語)をご参照ください。
ワークフローと GraphQL クエリ
ワークフローは複数の ジョブ(Job)を持ち、各ジョブの decide/notify
ブロック に、input
ブロックがあります。その input
ブロックに記述されているのが GraphQL クエリで、検査/監査対象のデータを定義しています。 Shisho Cloud は、このようなクエリの定義に従って各ジョブごとにデータを取得し、その取得したデータをポリシーコードに入力します。
jobs:
- id: example
name: Example Job
decide:
input:
schema: |
query {
...
}
- id: notify
name: Notify Job Status
decide:
input:
schema: |
query {
...
}
例えば以下の GraphQL クエリは、AWS アカウント内の VPC がデフォルトかどうかを示す isDefault
を取得しています。
jobs:
- id: example
name: Example Job
decide:
input:
schema: |
query {
aws {
accounts {
network {
vpcs {
metadata {
id
}
isDefault
}
}
}
}
}
GraphQL クエリの検索条件
通常、リソースは全件取得されますが、 いくつかのフィールドでは特定のリソースのみを取得するための検索条件(condition
)を指定できるinput
フィールドを持ち、これにより特定のリソースのみ取得できます。
下記のケースでは、AWSNetworkCondition
を利用し、特定のリージョン(regions
)、ap-northeast-1
, us-west-2
の 「AWS VPC リソース」("aws-vpc"
)のみを取得できます。
type AWSNetwork {
"""
VPC networks
"""
vpcs(condition: AWSNetworkCondition): [AWSVPC!]!
@resource(kind: "aws-vpc")
...
}
input AWSNetworkCondition {
"""
Regions of networks
If no list is specified (i.e. null), this field returns networks in *any* zone.
"""
regions: [AWSRegion!] @testdata(constraint: { array: { length: 2 } })
}
jobs:
- id: example
name: Example Job
decide:
input:
schema: |
query {
aws {
accounts {
network {
vpcs (condition: { regions: ["ap-northeast-1", "us-west-2"] }){
metadata {
id
}
isDefault
}
}
}
}
}
shishoctl
CLI による GraphQL クエリの実行
shishoctl
CLI は Shisho Cloud を操作するための CLI です。 様々なコマンドを用意していますが、その中には GraphQL クエリを実行するためのコマンドもあります。
shishoctl query run --org <ORGANIZATION_ID> <GRAPHQL_QUERY_FILE_NAME>.graphql
例えば、以下のようなコマンドを実行することで、shisho-cloud-demo
という組織に対して、 example.graphql
というファイルに記述された GraphQL クエリを実行できます。
shishoctl query run --org shisho-cloud-demo example.graphql
query {
aws {
accounts {
network {
vpcs {
metadata {
id
}
isDefault
}
}
}
}
}
shishoctl
CLI についての詳細は、こちら をご参照ください。
発展: GraphQL ディレクティブ(directives)
Shisho Cloud は GraphQL をスキーマ/クエリ言語として採用し、ユーザーが検査/監査したいデータを簡単に定義・取得できるようにしています。いま、スキーマにはいくつかの GraphQL ディレクティブ(directive)が定義されており、これによりスキーマからデータ取得ロジックの仕様が読み解きやすいようになっています。また、クエリ時にも Shisho Cloud 独特の GraphQL ディレクティブを用いて、検査/監査データ取得の挙動をカスタマイズできるようになっています。
本セクションでは、Shisho Cloud が対応している GraphQL ディレクティブについて説明します。
なお、下記の説明文において、リソースというキーワードが出てきます。Shisho Cloud では 監査対象データのエンティティをリソースと定義しています。リソースの詳細については、こちら をご参照ください。
GraphQL スキーマ内に付与されたディレクティブ
GraphQL ディレクティブは、GraphQL スキーマ内の GraphQL オブジェクトやフィールドに対して付与されることがあります。Shisho Cloud においても同様で、スキーマ内におけるディレクティブは、主にオブジェクトやフィールドの仕様を表現するために用いられています。以下では Shisho Cloud で定義されている GraphQL ディレクティブのうち、主としてスキーマで用いられる想定のものを列挙します。
@resource
@resource
ディレクティブはリソースの種別(resource kind)を明示するために利用されます。以下の例では、vpcs
フィールドが、Shisho Cloud 内で「AWS VPC リソース」("aws-vpc"
)として扱われるリソースを返却することがスキーマ内で明示されています。
type AWSNetwork {
"""
VPC networks
"""
vpcs(condition: AWSNetworkCondition): [AWSVPC!]!
@resource(kind: "aws-vpc")
...
}
@canBePartial
@canBePartial
ディレクティブは、リソースの一部のみを取得できるかどうかを示すために利用されます。このディレクティブがスキーマ上で付与されたフィールドに対しては、ある方法でクエリ発行時に リソース ID を指定することで、当該リソースに関するデータのみが取得できるようになります。この方法は「 GraphQL クエリの検索条件」セクションで説明した検索条件(condition
)とはまた別の形で、取得するリソースを絞り込む仕組みで、Shisho Cloud が再診断を高速に提供するために暗黙のうちに利用されています。
再診断や対象リソースの指定方法など、詳細を確認したい場合は こちらのページ をご参照ください。
以下の例では、VPC リソース一覧の一部のみを取得できることを示しています。
type AWSNetwork {
"""
VPC networks
"""
vpcs(condition: AWSNetworkCondition): [AWSVPC!]! @canBePartial
...
}
@locatable
@locatable
ディレクティブは、付与されたフィールドのロケーションを指定することで、リソースを絞り込めるかどうかを明示します。このディレクティブは parentKind
フィールドを持ち、親リソースの種別(resource kind)が併せて明示されています。
以下は例となりますが、Shisho Cloud 内でシナリオ(scenarios
)フィールドは、「 Web アプリケーションリソース」("user-web-application"
)の子リソースとして定義されています。また、シナリオ(scenarios
)フィールドに対して、@locatable
ディレクティブが付与されており、シナリオを絞り込むためのロケーション情報を指定することで、特定の Web アプリケーションリソースに紐づくシナリオのみを取得できます。
type Query {
"""
All data from web application integration
"""
webApps: [WebApp!]! @resource(kind: "user-web-application")
}
type WebApp {
"""
Scenarios that the finding relates to
"""
scenarios: [WebAppScenario!]! @locatable(parentKind: "user-web-application")
...
}
@testdata
@testdata
ディレクティブは、GraphQL クエリのテスト用 Playground で利用されているテストデータの生成に関わる情報が定義されています。そのため、実際のワークフロー には影響せず、あくまでテスト用 Playground に関する仕様です。なお、以下の例では、minimumTtl
フィールドに対して、10 から 60 の範囲でテストデータを生成することを示しています。
type AWSCloudFrontCachePolicyConfiguration {
"""
The minimum amount of time, in seconds, that you want objects to stay in the CloudFront cache before CloudFront sends another request to the origin to see if the object has been updated
"""
minimumTtl: Int64! @testdata(constraint: { int: { min: 10, max: 60 } })
...
}
GraphQL クエリ内で利用できるディレクティブ
GraphQL クエリ内でもいくつかのディレクティブが利用でき、これにより GraphQL クエリの評価時に特別な挙動を引き起こせます。以下では、GraphQL クエリ内で利用できるディレクティブを列挙します。
@mustBeTotal
@mustBeTotal
ディレクティブは、クエリの実行時に必ず全てのデータが取得される必要があることを宣言するためのものです。
通常、GraphQL クエリの実行時はリソースは全件取得されますが、Shisho Cloud の再診断機能を始めとした一部の機能は不必要なデータ取得を避けるような最適化を暗黙的に実施することがあります。したがって、GraphQL クエリの結果を処理する Rego 等のポリシーコードは、必ずしも全てのデータが取得されない前提で記述せねばなりません。
一方、ポリシーの判定ロジックの都合上、常にデータ全件が必要な場合もあります。クエリ発行時に、そのような制約の表明に利用できるのがこのディレクティブです。
以下の例では、全てのVPC 傘下のルートテーブル (aws.accounts.network.vpcs.routeTables
)取得に関して、全て取得するよう要求しています。対して、 EC2 インスタンスに紐づく VPC のルートテーブル(aws.accounts.ec2.instances.vpc.routeTables
)に関しては、その限りではありません。
{
aws {
accounts {
network {
vpcs {
routeTables @mustBeTotal { # 全てのルートテーブルを必ず取得する
id
...
}
}
}
ec2 {
instances {
vpc {
routeTables { # 一部のルートテーブル取得が可能
metadata {
id
}
...
}
}
}
}
}
}
}