I'd like to propose some resources to cover the new AppSync service from AWS. I asked Clint about it at re:Invent and he suggest I start by submitting an issue. There are couple of different ways I see to model this in Terraform. I'll enumerate the ones I thought of, explain my preference for one and then share a concrete example.
https://aws.amazon.com/documentation/appsync/
There are a few concepts for AppSync. At the top level we have "GraphQL APIs".
Each GraphQL API can have several "Data Sources", each of which is bound to a Lambda, Elasticsearch instance, or DynamoDB table.
Each GraphQL API can have several "Types". The AWS console and APIs provide multiple mechanisms for specifying these Types: they can be created from a GraphQL file en masse or one at a time. Types have a name and a classification (e.g. int, boolean, object) where object types of "Fields".
Each GraphQL API can have several "Resolvers". A Resolver is a GraphQL concept (generically beyond AWS) that defines how a specific field within a specific type should be fetched from a given data source.
For example, if there's a type type Foo { foo: String! }
we could define a resolve that described how to invoke a Lambda to fetch the foo
field of the type Foo
. That Lambda would receive various contextual information.
Modeling options
I think Data Source are pretty straight forward. The question comes as to how to best model Types, Fields, and Resolvers.
One approach would be to do exactly what the AWS APIs do and have a resource for Types and Resolvers with Types being implicitly created by Field definitions and referenced by Resolvers. I would describe this as "partially linked" -- a description I hope will become clearer in a moment.
A more explicit representation in Terraform might be to have Types as "container resources" and add an explicit Field resource. The collection of Type resources would implicitly construct the Type; Resolver resources would explicitly reference Field resources in Terraform.
On reflection though this seems baroque and cumbersome. I expect that users will typically specify their GraphQL schema in one file rather than spread between a bunch of Type resources or Type and Field resources. To accommodate this, the user would specify their schema as a property of the GraphQL API resource. The would be no need for a Type resource in Terraform. Resolver resources would reference Types and Field by name.
I'd suggest therefore the last of these options. While it departs slightly from the concepts expressed in the (preview) AWS API, I believe users will want to specify their GraphQL schema in one-shot rather than piecemeal in HCL.
resource "aws_appsync_graphql_api" "my-api" {
# required
name = "foo"
authentication_type = "API_KEY | AWS_IAM | AMAZON_COGNITO_USER_POOLS"
schema = <<EOF
schema {
query:Query
}
type Query {
getTodos: [Todo]
}
type Todo {
id: ID!
name: String
description: String
priority: Int
}
EOF
# optional
user_pool_config {
# required
user_pool_id = "string"
aws_region = "string"
default_action = "ALLOW | DENY"
# optional
app_id_client_regex = "*"
}
# properties
# id - string
# arn - string
# uris - [string]
# api_keys - [{id, expires} ... ]
}
resource "aws_appsync_data_source" "use-the-source" {
api_id = "${aws_appsync_graphql_api.my-api.id}"
name = "string"
description = "string"
# role when accessing lambda / elastic / dynamo
service_role = "aws_iam_role.foo.arn"
# one of...
lambda {
arn = "arn"
}
elasticsearch {
aws_region = "string"
endpoint = "string"
}
dynamodb {
aws_region = "string"
table_name = "string"
user_caller_credentials = true
}
# properties
# arn - string
}
resource "aws_appsync_resolver" "velvet-resolver" {
api_id = "${aws_appsync_graphql_api.my-api.id}"
type = "Query"
field = "getTodos"
data_source = "${aws_appsync_data_source.use-the-source.name}"
request_template = "string"
# optional
response_template = "string"
}
I'd be interested in working on this. Let me know if I'm headed in the right direction or if I'm off course.
Hi @ahl
I'd be inclined to following the AWS API as much as we can. We tried creating abstractions in the past for some resources and it usually turns out to be a bad idea as Amazon introduced some changes in their API which then showed some flaws in our abstractions forcing us to rework the resource.
On reflection though this seems baroque and cumbersome. I expect that users will typically specify their GraphQL schema in one file rather than spread between a bunch of Type resources or Type and Field resources.
It is possible that AWS will introduce support for full schema definition on the API level and then I'd be happy for Terraform to support that too. Until that happens I'm not too inclined to model it like this - or to rephrase - I don't see the value in doing so at this point, especially after considering the potential maintenance burden.
@atsushi-ishibashi Correct me if I'm wrong here - you seem to have more experience with AppSync by looking at your PRs.
A great example here would be API Gateway - we closely follow the API (of API Gateway service), hence we have many resources:
aws_api_gateway_base_path_mapping
aws_api_gateway_gateway_response
aws_api_gateway_integration
aws_api_gateway_integration_response
aws_api_gateway_method
aws_api_gateway_method_response
aws_api_gateway_method_settings
aws_api_gateway_model
aws_api_gateway_resource
but Amazon also later started supporting OpenAPI (Swagger) spec which can be passed to the API and creates all the things user would normally create via resources mentioned above. See https://www.terraform.io/docs/providers/aws/r/api_gateway_rest_api.html#body
The spec processing is _not_ Terraform's job - it's just a string being passed to the respective API, see https://github.com/terraform-providers/terraform-provider-aws/blob/b9b64ba46f9c3dcf90617d0d5e922764c94e2915/aws/resource_aws_api_gateway_rest_api.go#L89
So maintenance burden is very low.
FYI: We have PRs opened for first two resources here:
https://github.com/terraform-providers/terraform-provider-aws/pull/2494
https://github.com/terraform-providers/terraform-provider-aws/pull/2758
which we're going to review 🔜
Actually the API might support it already 🤔
https://docs.aws.amazon.com/appsync/latest/APIReference/API_StartSchemaCreation.html
so we might be able to support both.
We can add definition
(which is name closer to the API, but same as schema
in your example) to aws_appsync_graphql_api
later on for folks who wish to manage their APIs that way.
It should not be the only way though, I think.
@radeksimko I appreciate the review, but I'm confused by your comments:
It is possible that AWS will introduce support for full schema definition on the API level and then I'd be happy for Terraform to support that too.
Indeed; AWS does support this (as you discovered) and this is what I've proposed.
I'd be inclined to following the AWS API as much as we can. We tried creating abstractions in the past for some resources and it usually turns out to be a bad idea as Amazon introduced some changes in their API which then showed some flaws in our abstractions forcing us to rework the resource.
I've attempted to follow the AWS API; I've excluded pieces that are mutually conflicting (and that have unspecified and surprising semantics when used together). What I described as "baroque and cumbersome" was adding resources that don't map directly to the AWS entities.
I think I might have an easier time understanding if you put forth a concrete proposal. On that subject, is it more typical to have resources dribble in piecemeal per the PRs from @atsushi-ishibashi? @catsby had suggested I post an RFC to look at service as a whole, but I'm not sure if that's a typical workflow.
@radeksimko @catsby if there isn't interest in this proposal, feel free to close it.
We are definitely interested in AppSync support and will use it heavily. Even though I think some people will want to specify the entire API in one shot we used to do this with API Gateway and then switched to the piecemeal approach because at scale, the "big bang" approach is far more difficult to manage. I would propose a high level template type resource like the JSON template resource that then has dependencies on all of the more granular types such as type
, mutation
, subscription
, input
, interface
, fragment
, etc.
If there is interest, I can work on an entire proposal.
I'm interested, any idea on how long it could take to spike something around this proposal? :)
Looks like it's supported now! https://www.terraform.io/docs/providers/aws/r/appsync_graphql_api.html
Yes, it's supported but in a limited fashion. No way to define the schema nor resolvers. =(
Our team is also very interesting in using terraform to deploy appsync. But is there an effort to build support to deploy schemas and resolvers?
Our team would benefit from full AppSync support too.
I'm not really sure why this died on the vine -- certainly we've moved on from our interest in pursuing it.
@radeksimko would it unblock things to close this issue?
@atsushi-ishibashi is your plan to continue piecemeal?
Is somebody actively developing the missing pieces? Is there any help needed to get it done?
I'm very interested in full support for AppSync and offer my support in developing the missing pieces -- deploy schemas and resolvers.
+1 for supporting schemas and resolvers
Here here! We are building in the process of building a AppSync API. We use Terraform for everything else – we can assist if needed. +1 for supporting schemas and resolvers from here as well!
I've had the following PR out for 2 months now with no progress on getting it merged. I have a resolver one that I was working on and was almost done with. However with the lack of progress on my first PR, I gave up.
Would love some help getting this pushed through
https://github.com/terraform-providers/terraform-provider-aws/pull/4840
Is there ever going to be progress on this? AppSync has been out for nearly a year now....
I have submitted two PRs to clear out the enhancement backlog for the existing resources:
resource/aws_appsync_graphql_api: #6138
resource/aws_appsync_datasource: #6139
I'm looking at #4840 now but looks like it will need some review cycles before it can be merged.
Hello all. Two weeks ago i created a pull request adding the schema as a property of graphql_api and the resolvers. Please check out #6451. I'm curious about your feedback. Also if possible give a thumbs up to help prioritizing.
+1 for this please. Otherwise I'll have to switch to using Serverless. I've been using Terraform all the way along and don't want to move.
@ngocketit just FYI there is a 3rd option which I end up with - https://github.com/awslabs/aws-cdk
@vladgolubev Do you have the sample code? I created most of the infrastructure (including the aws_appsync_datasource
and aws_appsync_graphql_api
) with Terraform and the only missing part is the resolvers. Is there a way that I can use the already-created appsync (datasources, apis) resources with aws-cdk to define the resolvers?
Hi everyone 👋 We just merged the new aws_appsync_resolver
resource, which will release with version 2.4.0 of the Terraform AWS Provider, likely later today. Thanks to the community members who made this possible!
If you have further feature requests or bug reports for AppSync functionality, please submit new GitHub issues. Thanks!
Many thanks to you guys! Can't wait to give it a try.
The aws_appsync_graphql_api
resource schema
argument and the aws_appsync_resolver
resource has been released in version 2.4.0 of the Terraform AWS provider. Please see the Terraform documentation on provider versioning or reach out if you need any assistance upgrading.
Awesome!
I'm going to lock this issue because it has been closed for _30 days_ ⏳. This helps our maintainers find and focus on the active issues.
If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thanks!
Most helpful comment
+1 for supporting schemas and resolvers