/terraform-aws-appsync

Terraform module to create AWS AppSync resources

Primary LanguageHCLApache License 2.0Apache-2.0

AWS AppSync Terraform module

Terraform module which creates AWS AppSync resources and connects them together.

This Terraform module is part of serverless.tf framework, which aims to simplify all operations when working with the serverless in Terraform.

Usage

Complete AppSync with datasources and resolvers

module "appsync" {
  source = "terraform-aws-modules/appsync/aws"

  name = "dev-appsync"

  schema = file("schema.graphql")

  api_keys = {
    default = null # such key will expire in 7 days
  }

  additional_authentication_provider = {
    iam = {
      authentication_type = "AWS_IAM"
    }

    openid_connect_1 = {
      authentication_type = "OPENID_CONNECT"

      openid_connect_config = {
        issuer    = "https://www.issuer1.com/"
        client_id = "client_id1"
      }
    }
  }

  datasources = {
    registry_terraform_io = {
      type     = "HTTP"
      endpoint = "https://registry.terraform.io"
    }

    lambda_create_zip = {
      type         = "AWS_LAMBDA"
      function_arn = "arn:aws:lambda:eu-west-1:135367859850:function:index_1"
    }

    dynamodb1 = {
      type       = "AMAZON_DYNAMODB"
      table_name = "my-table"
      region     = "eu-west-1"
    }

    elasticsearch1 = {
      type     = "AMAZON_ELASTICSEARCH"
      endpoint = "https://search-my-domain.eu-west-1.es.amazonaws.com"
      region   = "eu-west-1"
    }
  }

  resolvers = {
    "Query.getZip" = {
      data_source   = "lambda_create_zip"
      direct_lambda = true
    }

    "Query.getModuleFromRegistry" = {
      data_source       = "registry_terraform_io"
      request_template  = file("vtl-templates/request.Query.getModuleFromRegistry.vtl")
      response_template = file("vtl-templates/response.Query.getModuleFromRegistry.vtl")
    }
  }
}

Conditional creation

Sometimes you need to have a way to create resources conditionally but Terraform 0.12 does not allow usage of count inside module block, so the solution is to specify create_graphql_api argument.

module "appsync" {
  source = "terraform-aws-modules/appsync/aws"

  create_graphql_api = false # to disable all resources

  # ... omitted
}

Relationship between Data-Source and Resolver resources

datasources define keys which can be referenced in resolvers. For initial configuration and parameters updates Terraform is able to understand the order of resources correctly.

In order to change name of keys in both places (eg from lambda-old to lambda-new), you will need to change key in both variables, and then run Terraform with partial configuration (using -target) to handle the migration in the aws_appsync_resolver resource (eg, Post.id):

# Create new resources and update resolver
$ terraform apply -target="module.appsync.aws_appsync_resolver.this[\"Post.id\"]" -target="module.appsync.aws_appsync_datasource.this[\"lambda-new\"]" -target="module.appsync.aws_iam_role.service_role[\"lambda-new\"]" -target="module.appsync.aws_iam_role_policy.this[\"lambda-new\"]"

# Delete orphan resources ("lambda-old")
$ terraform apply

Examples

  • Complete - Create AppSync with datasources, resolvers, and authorization providers in various combinations.

Requirements

Name Version
terraform >= 0.13.1
aws >= 2.46
random >= 2.0

Providers

Name Version
aws >= 2.46

Modules

No modules.

Resources

Name Type
aws_appsync_api_key.this resource
aws_appsync_datasource.this resource
aws_appsync_function.this resource
aws_appsync_graphql_api.this resource
aws_appsync_resolver.this resource
aws_iam_role.logs resource
aws_iam_role.service_role resource
aws_iam_role_policy.this resource
aws_iam_role_policy_attachment.logs resource
aws_caller_identity.this data source
aws_iam_policy_document.assume_role data source
aws_iam_policy_document.service_policy data source

Inputs

Name Description Type Default Required
additional_authentication_provider One or more additional authentication providers for the GraphqlApi. any {} no
api_keys Map of API keys to create map(string) {} no
authentication_type The authentication type to use by GraphQL API string "API_KEY" no
create_graphql_api Whether to create GraphQL API bool true no
create_logs_role Whether to create service role for Cloudwatch logs bool true no
datasources Map of datasources to create any {} no
direct_lambda_request_template VTL request template for the direct lambda integrations string "{\n \"version\" : \"2017-02-28\",\n \"operation\": \"Invoke\",\n \"payload\": {\n \"arguments\": $util.toJson($ctx.arguments),\n \"identity\": $util.toJson($ctx.identity),\n \"source\": $util.toJson($ctx.source),\n \"request\": $util.toJson($ctx.request),\n \"prev\": $util.toJson($ctx.prev),\n \"info\": {\n \"selectionSetList\": $util.toJson($ctx.info.selectionSetList),\n \"selectionSetGraphQL\": $util.toJson($ctx.info.selectionSetGraphQL),\n \"parentTypeName\": $util.toJson($ctx.info.parentTypeName),\n \"fieldName\": $util.toJson($ctx.info.fieldName),\n \"variables\": $util.toJson($ctx.info.variables)\n },\n \"stash\": $util.toJson($ctx.stash)\n }\n}\n" no
direct_lambda_response_template VTL response template for the direct lambda integrations string "$util.toJson($ctx.result)\n" no
dynamodb_allowed_actions List of allowed IAM actions for datasources type AMAZON_DYNAMODB list(string)
[
"dynamodb:GetItem",
"dynamodb:PutItem",
"dynamodb:DeleteItem",
"dynamodb:UpdateItem",
"dynamodb:Query",
"dynamodb:Scan",
"dynamodb:BatchGetItem",
"dynamodb:BatchWriteItem"
]
no
elasticsearch_allowed_actions List of allowed IAM actions for datasources type AMAZON_ELASTICSEARCH list(string)
[
"es:ESHttpDelete",
"es:ESHttpHead",
"es:ESHttpGet",
"es:ESHttpPost",
"es:ESHttpPut"
]
no
functions Map of functions to create any {} no
graphql_api_tags Map of tags to add to GraphQL API map(string) {} no
iam_permissions_boundary ARN for iam permissions boundary string null no
lambda_allowed_actions List of allowed IAM actions for datasources type AWS_LAMBDA list(string)
[
"lambda:invokeFunction"
]
no
log_cloudwatch_logs_role_arn Amazon Resource Name of the service role that AWS AppSync will assume to publish to Amazon CloudWatch logs in your account. string null no
log_exclude_verbose_content Set to TRUE to exclude sections that contain information such as headers, context, and evaluated mapping templates, regardless of logging level. bool false no
log_field_log_level Field logging level. Valid values: ALL, ERROR, NONE. string null no
logging_enabled Whether to enable Cloudwatch logging on GraphQL API bool false no
logs_role_name Name of IAM role to create for Cloudwatch logs string null no
logs_role_tags Map of tags to add to Cloudwatch logs IAM role map(string) {} no
name Name of GraphQL API string "" no
openid_connect_config Nested argument containing OpenID Connect configuration. map(string) {} no
resolver_caching_ttl Default caching TTL for resolvers when caching is enabled number 60 no
resolvers Map of resolvers to create any {} no
schema The schema definition, in GraphQL schema language format. Terraform cannot perform drift detection of this configuration. string "" no
tags Map of tags to add to all GraphQL resources created by this module map(string) {} no
user_pool_config The Amazon Cognito User Pool configuration. map(string) {} no
xray_enabled Whether tracing with X-ray is enabled. bool false no

Outputs

Name Description
appsync_api_key_id Map of API Key ID (Formatted as ApiId:Key)
appsync_api_key_key Map of API Keys
appsync_datasource_arn Map of ARNs of datasources
appsync_function_arn Map of ARNs of functions
appsync_function_function_id Map of function IDs of functions
appsync_function_id Map of IDs of functions
appsync_graphql_api_arn ARN of GraphQL API
appsync_graphql_api_fqdns Map of FQDNs associated with the API (no protocol and path)
appsync_graphql_api_id ID of GraphQL API
appsync_graphql_api_uris Map of URIs associated with the API
appsync_resolver_arn Map of ARNs of resolvers

Authors

Module managed by Anton Babenko. Check out serverless.tf to learn more about doing serverless with Terraform.

Please reach out to Betajob if you are looking for commercial support for your Terraform, AWS, or serverless project.

License

Apache 2 Licensed. See LICENSE for full details.