AWSStatic-verified

A GraphQL API that Does Not Publish Its Own Schema

introspection_config defaults to ENABLED, handing any caller a complete map of every type, field and argument, and query_depth_limit defaults to 0, which means no limit - so one nested query multiplies into thousands of resolver calls. Both closed here, with request bodies kept out of CloudWatch and a WAF association for the rate nothing else bounds.

terraformAWSaws
aws-appsyncvizier v1.2.0

Verification

Static-verified

Passed: validated and lint-clean (provider-schema-validated for AWS/Azure/GCP; Terraform-language lint elsewhere).

Conformance

  • Static validation (fmt · validate · tflint)
  • Security scan clean (Checkov)
  • Plan tests (mocked: validation rules · outputs)

Provenance

  • SHA-256 checksum
  • Signature (pending)

Functional

  • Live test pending (no cloud run yet)

Last verified 2026-09-13 · how we verify

Use it from the registry

terraform · opentofu
module "appsync" {
  source  = "www.iac-bazaar.com/iac-bazaar/aws-appsync/aws"
  version = "1.0.0"
}

Needs a registry token from /account/tokens. The module itself is free; the account is what identifies you. Full setup: registry docs.

Inputs & outputs

Create a free account to read this module's contract

The declared contract - every input name, type, default and description, plus every output - is shown to signed-in accounts, not to anonymous visitors.

A free account sees the contract of every module in the catalogue. There is no subscription and nothing to buy - the modules are free to download, and they run under Vizier.

Documentation

aws-appsync

An AppSync GraphQL API that does not publish its own schema, cannot be asked an arbitrarily deep question, and does not write its callers' data into CloudWatch. Works with Terraform and OpenTofu (>= 1.6), AWS provider >= 6.0, < 7.0.

introspection_config defaults to ENABLED. GraphQL introspection returns the whole schema - every type, every field, every argument, including the internal ones and the ones you never documented. Anyone who can reach the API with any credential can download a complete map of it. DISABLED here.

query_depth_limit defaults to 0, which means no limit. GraphQL schemas are usually cyclic - an author has books, a book has an author - so a caller can nest a query as deep as they like, and every level multiplies the resolver calls beneath it. One request becomes thousands, against your resolvers and whatever they talk to. 16 here, with resolver_count_limit bounded too.

Turning logging on without exclude_verbose_content writes request and response bodies to CloudWatch. That is your callers' data, copied into a log group with its own retention and its own access policy, as a side effect of enabling observability. Excluded here; field_log_level still records what happened. A precondition refuses the verbose combination unless accept_verbose_logs says it was meant.

API_KEY is a bare bearer token - no identity, no attribution, and no revocation short of deleting the key for everyone holding it. The module accepts it and requires accept_api_key_auth to say so out loud. A second precondition refuses an auth type whose configuration block is missing, which otherwise creates an API nobody can authenticate against.

Enum-valued settings are exposed as the API's own strings rather than as booleans a conditional converts. That is deliberate: a rendered ternary reads as unresolved to configuration scanners, which then report a control as absent on a module that has it - verified by bisect twice while building this batch.

A depth limit bounds one query; nothing bounds the rate. query_depth_limit makes a single request cheap, and an internet-facing GraphQL API with no rate limit simply receives more of them. Rate-based rules live in WAF, so pass web_acl_arn and the module associates a REGIONAL WAFv2 web ACL with the API.

Smaller things: log_config is a static block and the module creates the CloudWatch role when you do not pass one - needing to build an IAM role first is how field-level logging ends up switched off in practice, and a dynamic block here would also be unreadable to configuration scanners; the created role's trust policy is scoped with aws:SourceAccount, so the shared appsync.amazonaws.com principal cannot be used to assume it on behalf of someone else's API; and app_id_client_regex is surfaced, since leaving it null admits every app client in the pool including ones created later by somebody else.

Verification

Static validation runs tofu fmt, init, validate, tflint and checkov. This module has not yet had a live test, so it is published as statically validated with its live test pending and does not carry the live-tested mark.

Usage code & full reference need an account

The complete copy-paste usage, the full input/output reference, and operational notes are free with an account - shown here and bundled in the download. Sign in and this section fills in.

  • Usage

Related modules