Skip to content

Commit

Permalink
Merge pull request #35631 from acwwat/f-aws_appsync_graphql_api-add_c…
Browse files Browse the repository at this point in the history
…onfig_limit_attrs

feat: Add introspection and limit args to aws_appsync_graphql_api
  • Loading branch information
ewbankkit authored Feb 14, 2024
2 parents 34add68 + 83de6ea commit bb8ccd4
Show file tree
Hide file tree
Showing 5 changed files with 185 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .changelog/35631.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
resource/aws_appsync_graphql_api: Add `introspection_config`, `query_depth_limit`, and `resolver_count_limit` arguments
```
3 changes: 3 additions & 0 deletions internal/service/appsync/appsync_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ func TestAccAppSync_serial(t *testing.T) {
"AdditionalAuthentication_multiple": testAccGraphQLAPI_AdditionalAuthentication_multiple,
"xrayEnabled": testAccGraphQLAPI_xrayEnabled,
"visibility": testAccGraphQLAPI_visibility,
"introspectionConfig": testAccGraphQLAPI_introspectionConfig,
"queryDepthLimit": testAccGraphQLAPI_queryDepthLimit,
"resolverCountLimit": testAccGraphQLAPI_resolverCountLimit,
},
"Function": {
"basic": testAccFunction_basic,
Expand Down
45 changes: 45 additions & 0 deletions internal/service/appsync/graphql_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,12 @@ func ResourceGraphQLAPI() *schema.Resource {
Required: true,
ValidateFunc: validation.StringInSlice(appsync.AuthenticationType_Values(), false),
},
"introspection_config": {
Type: schema.TypeString,
Optional: true,
Default: appsync.GraphQLApiIntrospectionConfigEnabled,
ValidateFunc: validation.StringInSlice(appsync.GraphQLApiIntrospectionConfig_Values(), false),
},
"lambda_authorizer_config": {
Type: schema.TypeList,
Optional: true,
Expand Down Expand Up @@ -219,6 +225,18 @@ func ResourceGraphQLAPI() *schema.Resource {
},
},
},
"query_depth_limit": {
Type: schema.TypeInt,
Optional: true,
Default: 0,
ValidateFunc: validation.IntBetween(0, 75),
},
"resolver_count_limit": {
Type: schema.TypeInt,
Optional: true,
Default: 0,
ValidateFunc: validation.IntBetween(0, 10000),
},
"schema": {
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -305,6 +323,18 @@ func resourceGraphQLAPICreate(ctx context.Context, d *schema.ResourceData, meta
input.UserPoolConfig = expandGraphQLAPIUserPoolConfig(v.([]interface{}), meta.(*conns.AWSClient).Region)
}

if v, ok := d.GetOk("introspection_config"); ok {
input.IntrospectionConfig = aws.String(v.(string))
}

if v, ok := d.GetOk("query_depth_limit"); ok {
input.QueryDepthLimit = aws.Int64(int64(v.(int)))
}

if v, ok := d.GetOk("resolver_count_limit"); ok {
input.ResolverCountLimit = aws.Int64(int64(v.(int)))
}

if v, ok := d.GetOk("xray_enabled"); ok {
input.XrayEnabled = aws.Bool(v.(bool))
}
Expand Down Expand Up @@ -360,7 +390,10 @@ func resourceGraphQLAPIRead(ctx context.Context, d *schema.ResourceData, meta in
if err := d.Set("openid_connect_config", flattenGraphQLAPIOpenIDConnectConfig(api.OpenIDConnectConfig)); err != nil {
return sdkdiag.AppendErrorf(diags, "setting openid_connect_config: %s", err)
}
d.Set("introspection_config", api.IntrospectionConfig)
d.Set("name", api.Name)
d.Set("query_depth_limit", api.QueryDepthLimit)
d.Set("resolver_count_limit", api.ResolverCountLimit)
d.Set("uris", aws.StringValueMap(api.Uris))
if err := d.Set("user_pool_config", flattenGraphQLAPIUserPoolConfig(api.UserPoolConfig)); err != nil {
return sdkdiag.AppendErrorf(diags, "setting user_pool_config: %s", err)
Expand Down Expand Up @@ -406,6 +439,18 @@ func resourceGraphQLAPIUpdate(ctx context.Context, d *schema.ResourceData, meta
input.UserPoolConfig = expandGraphQLAPIUserPoolConfig(v.([]interface{}), meta.(*conns.AWSClient).Region)
}

if v, ok := d.GetOk("introspection_config"); ok {
input.IntrospectionConfig = aws.String(v.(string))
}

if v, ok := d.GetOk("query_depth_limit"); ok {
input.QueryDepthLimit = aws.Int64(int64(v.(int)))
}

if v, ok := d.GetOk("resolver_count_limit"); ok {
input.ResolverCountLimit = aws.Int64(int64(v.(int)))
}

if v, ok := d.GetOk("xray_enabled"); ok {
input.XrayEnabled = aws.Bool(v.(bool))
}
Expand Down
117 changes: 117 additions & 0 deletions internal/service/appsync/graphql_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ func testAccGraphQLAPI_basic(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "additional_authentication_provider.#", "0"),
resource.TestCheckResourceAttr(resourceName, "xray_enabled", "false"),
resource.TestCheckResourceAttr(resourceName, "visibility", "GLOBAL"),
resource.TestCheckResourceAttr(resourceName, "introspection_config", "ENABLED"),
resource.TestCheckResourceAttr(resourceName, "query_depth_limit", "0"),
resource.TestCheckResourceAttr(resourceName, "resolver_count_limit", "0"),
),
},
{
Expand Down Expand Up @@ -1208,6 +1211,90 @@ func testAccGraphQLAPI_visibility(t *testing.T) {
})
}

func testAccGraphQLAPI_introspectionConfig(t *testing.T) {
ctx := acctest.Context(t)
var api1 appsync.GraphqlApi
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resourceName := "aws_appsync_graphql_api.test"

resource.Test(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t); acctest.PreCheckPartitionHasService(t, appsync.EndpointsID) },
ErrorCheck: acctest.ErrorCheck(t, appsync.EndpointsID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckGraphQLAPIDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccGraphQLAPIConfig_introspectionConfig(rName, "DISABLED"),
Check: resource.ComposeTestCheckFunc(
testAccCheckGraphQLAPIExists(ctx, resourceName, &api1),
resource.TestCheckResourceAttr(resourceName, "introspection_config", "DISABLED"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func testAccGraphQLAPI_queryDepthLimit(t *testing.T) {
ctx := acctest.Context(t)
var api1 appsync.GraphqlApi
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resourceName := "aws_appsync_graphql_api.test"

resource.Test(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t); acctest.PreCheckPartitionHasService(t, appsync.EndpointsID) },
ErrorCheck: acctest.ErrorCheck(t, appsync.EndpointsID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckGraphQLAPIDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccGraphQLAPIConfig_queryDepthLimit(rName, 2),
Check: resource.ComposeTestCheckFunc(
testAccCheckGraphQLAPIExists(ctx, resourceName, &api1),
resource.TestCheckResourceAttr(resourceName, "query_depth_limit", "2"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func testAccGraphQLAPI_resolverCountLimit(t *testing.T) {
ctx := acctest.Context(t)
var api1 appsync.GraphqlApi
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resourceName := "aws_appsync_graphql_api.test"

resource.Test(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t); acctest.PreCheckPartitionHasService(t, appsync.EndpointsID) },
ErrorCheck: acctest.ErrorCheck(t, appsync.EndpointsID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckGraphQLAPIDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccGraphQLAPIConfig_resolverCountLimit(rName, 2),
Check: resource.ComposeTestCheckFunc(
testAccCheckGraphQLAPIExists(ctx, resourceName, &api1),
resource.TestCheckResourceAttr(resourceName, "resolver_count_limit", "2"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func testAccCheckGraphQLAPIDestroy(ctx context.Context) resource.TestCheckFunc {
return func(s *terraform.State) error {
conn := acctest.Provider.Meta().(*conns.AWSClient).AppSyncConn(ctx)
Expand Down Expand Up @@ -1707,3 +1794,33 @@ resource "aws_appsync_graphql_api" "test" {
}
`, rName, xrayEnabled)
}

func testAccGraphQLAPIConfig_introspectionConfig(rName, introspectionConfig string) string {
return fmt.Sprintf(`
resource "aws_appsync_graphql_api" "test" {
authentication_type = "API_KEY"
name = %[1]q
introspection_config = %[2]q
}
`, rName, introspectionConfig)
}

func testAccGraphQLAPIConfig_queryDepthLimit(rName string, queryDepthLimit int) string {
return fmt.Sprintf(`
resource "aws_appsync_graphql_api" "test" {
authentication_type = "API_KEY"
name = %[1]q
query_depth_limit = %[2]d
}
`, rName, queryDepthLimit)
}

func testAccGraphQLAPIConfig_resolverCountLimit(rName string, resolverCountLimit int) string {
return fmt.Sprintf(`
resource "aws_appsync_graphql_api" "test" {
authentication_type = "API_KEY"
name = %[1]q
resolver_count_limit = %[2]d
}
`, rName, resolverCountLimit)
}
17 changes: 17 additions & 0 deletions website/docs/r/appsync_graphql_api.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,18 @@ resource "aws_wafv2_web_acl" "example" {
}
```

### GraphQL run complexity, query depth, and introspection

```terraform
resource "aws_appsync_graphql_api" "example" {
authentication_type = "AWS_IAM"
name = "example"
introspection_config = "ENABLED"
query_depth_limit = 2
resolver_count_limit = 2
}
```

## Argument Reference

This resource supports the following arguments:
Expand All @@ -210,6 +222,11 @@ This resource supports the following arguments:
* `lambda_authorizer_config` - (Optional) Nested argument containing Lambda authorizer configuration. Defined below.
* `schema` - (Optional) Schema definition, in GraphQL schema language format. Terraform cannot perform drift detection of this configuration.
* `additional_authentication_provider` - (Optional) One or more additional authentication providers for the GraphqlApi. Defined below.
* `introspection_config` - (Optional) Sets the value of the GraphQL API to enable (`ENABLED`) or disable (`DISABLED`) introspection. If no value is provided, the introspection configuration will be set to ENABLED by default. This field will produce an error if the operation attempts to use the introspection feature while this field is disabled. For more information about introspection, see [GraphQL introspection](https://graphql.org/learn/introspection/).
* `query_depth_limit` - (Optional) The maximum depth a query can have in a single request. Depth refers to the amount of nested levels allowed in the body of query. The default value is `0` (or unspecified), which indicates there's no depth limit. If you set a limit, it can be between `1` and `75` nested levels. This field will produce a limit error if the operation falls out of bounds.

Note that fields can still be set to nullable or non-nullable. If a non-nullable field produces an error, the error will be thrown upwards to the first nullable field available.
* `resolver_count_limit` - (Optional) The maximum number of resolvers that can be invoked in a single request. The default value is `0` (or unspecified), which will set the limit to `10000`. When specified, the limit value can be between `1` and `10000`. This field will produce a limit error if the operation falls out of bounds.
* `tags` - (Optional) Map of tags to assign to the resource. If configured with a provider [`default_tags` configuration block](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level.
* `xray_enabled` - (Optional) Whether tracing with X-ray is enabled. Defaults to false.
* `visibility` - (Optional) Sets the value of the GraphQL API to public (`GLOBAL`) or private (`PRIVATE`). If no value is provided, the visibility will be set to `GLOBAL` by default. This value cannot be changed once the API has been created.
Expand Down

0 comments on commit bb8ccd4

Please sign in to comment.