Skip to content

Commit

Permalink
Merge pull request #37773 from Oltier/f-add-appsync-target-to-aws_clo…
Browse files Browse the repository at this point in the history
…udwatch_event_target

F add appsync target to aws cloudwatch event target
  • Loading branch information
ewbankkit authored Oct 15, 2024
2 parents 843cf6b + 1ed520d commit 7c94eab
Show file tree
Hide file tree
Showing 5 changed files with 283 additions and 1 deletion.
3 changes: 3 additions & 0 deletions .changelog/37773.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
resource/aws_cloudwatch_event_target: Add `appsync_target` configuration block
```
2 changes: 1 addition & 1 deletion .changelog/37799.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
```release-note:enhancement
resource/aws_dynamodb_table: Add `on_demand_throughput` and `global_secondary_index.on_demand_throughput` arguments
resource/aws_dynamodb_table: Add `on_demand_throughput` and `global_secondary_index.on_demand_throughput` arguments
```
44 changes: 44 additions & 0 deletions internal/service/events/target.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,20 @@ func resourceTarget() *schema.Resource {
},

Schema: map[string]*schema.Schema{
"appsync_target": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"graphql_operation": {
Type: schema.TypeString,
Optional: true,
ValidateDiagFunc: validation.ToDiagFunc(validation.StringLenBetween(1, 1048576)),
},
},
},
},
names.AttrARN: {
Type: schema.TypeString,
Required: true,
Expand Down Expand Up @@ -621,6 +635,12 @@ func resourceTargetRead(ctx context.Context, d *schema.ResourceData, meta interf
}
}

if target.AppSyncParameters != nil {
if err := d.Set("appsync_target", flattenAppSyncParameters(target.AppSyncParameters)); err != nil {
return sdkdiag.AppendErrorf(diags, "setting appsync_target: %s", err)
}
}

return diags
}

Expand Down Expand Up @@ -871,6 +891,10 @@ func expandPutTargetsInput(ctx context.Context, d *schema.ResourceData) *eventbr
target.DeadLetterConfig = expandDeadLetterParametersConfig(v.([]interface{}))
}

if v, ok := d.GetOk("appsync_target"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil {
target.AppSyncParameters = expandAppSyncParameters(v.([]interface{}))
}

input := &eventbridge.PutTargetsInput{
Rule: aws.String(d.Get(names.AttrRule).(string)),
Targets: []types.Target{target},
Expand Down Expand Up @@ -1484,3 +1508,23 @@ func flattenTargetCapacityProviderStrategy(cps []types.CapacityProviderStrategyI
}
return results
}

func flattenAppSyncParameters(apiObject *types.AppSyncParameters) []map[string]interface{} {
tfMap := make(map[string]interface{})
tfMap["graphql_operation"] = aws.ToString(apiObject.GraphQLOperation)

return []map[string]interface{}{tfMap}
}

func expandAppSyncParameters(tfList []interface{}) *types.AppSyncParameters {
apiObject := &types.AppSyncParameters{}

for _, tfMapRaw := range tfList {
tfMap := tfMapRaw.(map[string]interface{})
if v, ok := tfMap["graphql_operation"].(string); ok && v != "" {
apiObject.GraphQLOperation = aws.String(v)
}
}

return apiObject
}
135 changes: 135 additions & 0 deletions internal/service/events/target_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ func TestAccEventsTarget_basic(t *testing.T) {
Config: testAccTargetConfig_basic(rName),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckTargetExists(ctx, resourceName, &v),
resource.TestCheckResourceAttr(resourceName, "appsync_target.#", acctest.Ct0),
resource.TestCheckResourceAttrPair(resourceName, names.AttrARN, snsTopicResourceName, names.AttrARN),
resource.TestCheckResourceAttr(resourceName, "batch_target.#", acctest.Ct0),
resource.TestCheckResourceAttr(resourceName, "dead_letter_config.#", acctest.Ct0),
Expand All @@ -224,6 +225,7 @@ func TestAccEventsTarget_basic(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "sagemaker_pipeline_target.#", acctest.Ct0),
resource.TestCheckResourceAttr(resourceName, "sqs_target.#", acctest.Ct0),
resource.TestCheckResourceAttr(resourceName, "target_id", rName),
resource.TestCheckResourceAttr(resourceName, "appsync_target.#", acctest.Ct0),
),
},
{
Expand Down Expand Up @@ -1199,6 +1201,39 @@ func TestAccEventsTarget_ecsNoPropagateTags(t *testing.T) {
})
}

func TestAccEventsTarget_appsync(t *testing.T) {
ctx := acctest.Context(t)
var v types.Target
rName := sdkacctest.RandomWithPrefix("tf_appsync_target")
resourceName := "aws_cloudwatch_event_target.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
acctest.PreCheck(ctx, t)
},
ErrorCheck: acctest.ErrorCheck(t, names.EventsServiceID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckTargetDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccTargetConfig_appsync(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckTargetExists(ctx, resourceName, &v),
resource.TestCheckResourceAttr(resourceName, "appsync_target.#", acctest.Ct1),
resource.TestCheckResourceAttr(resourceName, "appsync_target.0.graphql_operation", "mutation TestMutation($input:MutationInput!){testMutation(input: $input) {test}}"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateIdFunc: testAccTargetImportStateIdFunc(resourceName),
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{names.AttrForceDestroy},
},
},
})
}

func testAccCheckTargetExists(ctx context.Context, n string, v *types.Target) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
Expand Down Expand Up @@ -2645,3 +2680,103 @@ resource "aws_cloudwatch_event_target" "test" {
}
`)
}

func testAccTargetConfig_appsync(rName string) string {
return fmt.Sprintf(`
data "aws_partition" "current" {}
resource "aws_cloudwatch_event_rule" "test" {
name = %[1]q
description = "schedule_batch_test"
schedule_expression = "rate(5 minutes)"
}
resource "aws_cloudwatch_event_target" "test" {
arn = replace(aws_appsync_graphql_api.test.arn, "apis", "endpoints/graphql-api")
rule = aws_cloudwatch_event_rule.test.id
role_arn = aws_iam_role.test.arn
input_transformer {
input_paths = {
input = "$.detail.input"
}
input_template = <<EOF
{
"input": <input>
}
EOF
}
appsync_target {
graphql_operation = "mutation TestMutation($input:MutationInput!){testMutation(input: $input) {test}}"
}
}
resource "aws_iam_role" "test" {
name = %[1]q
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "events.${data.aws_partition.current.dns_suffix}"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
resource "aws_iam_role_policy" "test" {
name = %[1]q
role = aws_iam_role.test.id
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "appsync:GraphQL",
"Effect": "Allow",
"Resource": [
"*"
]
}
]
}
EOF
}
resource "aws_appsync_graphql_api" "test" {
name = %[1]q
authentication_type = "AWS_IAM"
schema = <<EOF
schema {
mutation: Mutation
query: Query
}
type Query {
testQuery: String
}
type Mutation {
testMutation(input: MutationInput!): TestMutationResult
}
type TestMutationResult {
test: String
}
input MutationInput {
testInput: String
}
EOF
}
`, rName)
}
100 changes: 100 additions & 0 deletions website/docs/r/cloudwatch_event_target.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,101 @@ resource "aws_cloudwatch_event_target" "example" {
}
```

### AppSync Usage

```terraform
resource "aws_cloudwatch_event_rule" "invoke_appsync_mutation" {
name = "invoke-appsync-mutation"
description = "schedule_batch_test"
schedule_expression = "rate(5 minutes)"
}
resource "aws_cloudwatch_event_target" "invoke_appsync_mutation" {
arn = replace(aws_appsync_graphql_api.graphql-api.arn, "apis", "endpoints/graphql-api")
rule = aws_cloudwatch_event_rule.invoke_appsync_mutation.id
role_arn = aws_iam_role.appsync_mutation_role.arn
input_transformer {
input_paths = {
input = "$.detail.input"
}
input_template = <<EOF
{
"input": <input>
}
EOF
}
appsync_target {
graphql_operation = "mutation TestMutation($input:MutationInput!){testMutation(input: $input) {test}}"
}
}
resource "aws_iam_role" "appsync_mutation_role" {
name = "appsync-mutation-role"
assume_role_policy = data.aws_iam_policy_document.appsync_mutation_role_trust.json
}
data "aws_iam_policy_document" "appsync_mutation_role_trust" {
statement {
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["events.amazonaws.com"]
}
}
}
data "aws_iam_policy_document" "appsync_mutation_role_policy_document" {
statement {
actions = ["appsync:GraphQL"]
effect = "Allow"
resources = [
aws_appsync_graphql_api.graphql-api.arn
]
}
}
resource "aws_iam_policy" "appsync_mutation_role_policy" {
name = "appsync-mutation-role-policy"
policy = data.aws_iam_policy_document.appsync_mutation_role_policy_document.json
}
resource "aws_iam_role_policy_attachment" "appsync_mutation_role_attachment" {
policy_arn = aws_iam_policy.appsync_mutation_role_policy.arn
role = aws_iam_role.appsync_mutation_role.name
}
resource "aws_appsync_graphql_api" "graphql-api" {
name = "api"
authentication_type = "AWS_IAM"
schema = <<EOF
schema {
mutation: Mutation
query: Query
}
type Query {
testQuery: String
}
type Mutation {
testMutation(input: MutationInput!): TestMutationResult
}
type TestMutationResult {
test: String
}
input MutationInput {
testInput: String
}
EOF
}
```

## Argument Reference

-> **Note:** In order to be able to have your AWS Lambda function or
Expand All @@ -463,6 +558,7 @@ The following arguments are required:

The following arguments are optional:

* `appsync_target` - (Optional) Parameters used when you are using the rule to invoke an AppSync GraphQL API mutation. Documented below. A maximum of 1 are allowed.
* `batch_target` - (Optional) Parameters used when you are using the rule to invoke an Amazon Batch Job. Documented below. A maximum of 1 are allowed.
* `dead_letter_config` - (Optional) Parameters used when you are providing a dead letter config. Documented below. A maximum of 1 are allowed.
* `ecs_target` - (Optional) Parameters used when you are using the rule to invoke Amazon ECS Task. Documented below. A maximum of 1 are allowed.
Expand Down Expand Up @@ -583,6 +679,10 @@ For more information, see [Task Networking](https://docs.aws.amazon.com/AmazonEC
* `name` - (Required) Name of parameter to start execution of a SageMaker Model Building Pipeline.
* `value` - (Required) Value of parameter to start execution of a SageMaker Model Building Pipeline.

### appsync_target

* `graphql_operation` - (Optional) Contains the GraphQL mutation to be parsed and executed.

## Attribute Reference

This resource exports no additional attributes.
Expand Down

0 comments on commit 7c94eab

Please sign in to comment.