Skip to content

Commit

Permalink
resource/aws_apigatewayv2_integration: AWS service integrations for H…
Browse files Browse the repository at this point in the history
…TTP APIs. (#14860)

Output from acceptance testing:

```
--- PASS: TestAccAWSAPIGatewayV2Integration_disappears (29.00s)
--- PASS: TestAccAWSAPIGatewayV2Integration_basicHttp (30.37s)
--- PASS: TestAccAWSAPIGatewayV2IntegrationResponse_basic (32.64s)
--- PASS: TestAccAWSAPIGatewayV2Integration_basicWebSocket (32.81s)
--- PASS: TestAccAWSAPIGatewayV2Integration_AwsServiceIntegration (33.16s)
--- PASS: TestAccAWSAPIGatewayV2IntegrationResponse_disappears (36.85s)
--- PASS: TestAccAWSAPIGatewayV2Integration_IntegrationTypeHttp (41.16s)
--- PASS: TestAccAWSAPIGatewayV2IntegrationResponse_AllAttributes (42.63s)
--- PASS: TestAccAWSAPIGatewayV2Integration_LambdaHttp (46.09s)
--- PASS: TestAccAWSAPIGatewayV2Integration_LambdaWebSocket (52.54s)
--- PASS: TestAccAWSAPIGatewayV2Integration_VpcLinkHttp (417.62s)
--- PASS: TestAccAWSAPIGatewayV2Integration_VpcLinkWebSocket (687.74s)
```
  • Loading branch information
ewbankkit authored Aug 27, 2020
1 parent 684357c commit 373a23c
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 31 deletions.
56 changes: 25 additions & 31 deletions aws/resource_aws_apigatewayv2_integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,15 @@ func resourceAwsApiGatewayV2Integration() *schema.Resource {
ValidateFunc: validation.StringLenBetween(1, 1024),
},
"connection_type": {
Type: schema.TypeString,
Optional: true,
Default: apigatewayv2.ConnectionTypeInternet,
ValidateFunc: validation.StringInSlice([]string{
apigatewayv2.ConnectionTypeInternet,
apigatewayv2.ConnectionTypeVpcLink,
}, false),
Type: schema.TypeString,
Optional: true,
Default: apigatewayv2.ConnectionTypeInternet,
ValidateFunc: validation.StringInSlice(apigatewayv2.ConnectionType_Values(), false),
},
"content_handling_strategy": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringInSlice([]string{
apigatewayv2.ContentHandlingStrategyConvertToBinary,
apigatewayv2.ContentHandlingStrategyConvertToText,
}, false),
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringInSlice(apigatewayv2.ContentHandlingStrategy_Values(), false),
},
"credentials_arn": {
Type: schema.TypeString,
Expand Down Expand Up @@ -75,31 +69,27 @@ func resourceAwsApiGatewayV2Integration() *schema.Resource {
Type: schema.TypeString,
Computed: true,
},
"integration_subtype": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
ValidateFunc: validation.StringLenBetween(1, 128),
},
"integration_type": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringInSlice([]string{
apigatewayv2.IntegrationTypeAws,
apigatewayv2.IntegrationTypeAwsProxy,
apigatewayv2.IntegrationTypeHttp,
apigatewayv2.IntegrationTypeHttpProxy,
apigatewayv2.IntegrationTypeMock,
}, false),
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringInSlice(apigatewayv2.IntegrationType_Values(), false),
},
"integration_uri": {
Type: schema.TypeString,
Optional: true,
},
"passthrough_behavior": {
Type: schema.TypeString,
Optional: true,
Default: apigatewayv2.PassthroughBehaviorWhenNoMatch,
ValidateFunc: validation.StringInSlice([]string{
apigatewayv2.PassthroughBehaviorWhenNoMatch,
apigatewayv2.PassthroughBehaviorNever,
apigatewayv2.PassthroughBehaviorWhenNoTemplates,
}, false),
Type: schema.TypeString,
Optional: true,
Default: apigatewayv2.PassthroughBehaviorWhenNoMatch,
ValidateFunc: validation.StringInSlice(apigatewayv2.PassthroughBehavior_Values(), false),
DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
// Not set for HTTP APIs.
if old == "" && new == apigatewayv2.PassthroughBehaviorWhenNoMatch {
Expand Down Expand Up @@ -182,6 +172,9 @@ func resourceAwsApiGatewayV2IntegrationCreate(d *schema.ResourceData, meta inter
if v, ok := d.GetOk("integration_method"); ok {
req.IntegrationMethod = aws.String(v.(string))
}
if v, ok := d.GetOk("integration_subtype"); ok {
req.IntegrationSubtype = aws.String(v.(string))
}
if v, ok := d.GetOk("integration_uri"); ok {
req.IntegrationUri = aws.String(v.(string))
}
Expand Down Expand Up @@ -241,6 +234,7 @@ func resourceAwsApiGatewayV2IntegrationRead(d *schema.ResourceData, meta interfa
d.Set("description", resp.Description)
d.Set("integration_method", resp.IntegrationMethod)
d.Set("integration_response_selection_expression", resp.IntegrationResponseSelectionExpression)
d.Set("integration_subtype", resp.IntegrationSubtype)
d.Set("integration_type", resp.IntegrationType)
d.Set("integration_uri", resp.IntegrationUri)
d.Set("passthrough_behavior", resp.PassthroughBehavior)
Expand Down
105 changes: 105 additions & 0 deletions aws/resource_aws_apigatewayv2_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ func TestAccAWSAPIGatewayV2Integration_basicWebSocket(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "description", ""),
resource.TestCheckResourceAttr(resourceName, "integration_method", ""),
resource.TestCheckResourceAttr(resourceName, "integration_response_selection_expression", "${integration.response.statuscode}"),
resource.TestCheckResourceAttr(resourceName, "integration_subtype", ""),
resource.TestCheckResourceAttr(resourceName, "integration_type", "MOCK"),
resource.TestCheckResourceAttr(resourceName, "integration_uri", ""),
resource.TestCheckResourceAttr(resourceName, "passthrough_behavior", "WHEN_NO_MATCH"),
Expand Down Expand Up @@ -76,6 +77,7 @@ func TestAccAWSAPIGatewayV2Integration_basicHttp(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "description", ""),
resource.TestCheckResourceAttr(resourceName, "integration_method", "GET"),
resource.TestCheckResourceAttr(resourceName, "integration_response_selection_expression", ""),
resource.TestCheckResourceAttr(resourceName, "integration_subtype", ""),
resource.TestCheckResourceAttr(resourceName, "integration_type", "HTTP_PROXY"),
resource.TestCheckResourceAttr(resourceName, "integration_uri", "https://example.com"),
resource.TestCheckResourceAttr(resourceName, "passthrough_behavior", ""),
Expand Down Expand Up @@ -140,6 +142,7 @@ func TestAccAWSAPIGatewayV2Integration_IntegrationTypeHttp(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "description", "Test HTTP"),
resource.TestCheckResourceAttr(resourceName, "integration_method", "GET"),
resource.TestCheckResourceAttr(resourceName, "integration_response_selection_expression", "${integration.response.statuscode}"),
resource.TestCheckResourceAttr(resourceName, "integration_subtype", ""),
resource.TestCheckResourceAttr(resourceName, "integration_type", "HTTP"),
resource.TestCheckResourceAttr(resourceName, "integration_uri", "http://www.example.com"),
resource.TestCheckResourceAttr(resourceName, "passthrough_behavior", "WHEN_NO_MATCH"),
Expand All @@ -164,6 +167,7 @@ func TestAccAWSAPIGatewayV2Integration_IntegrationTypeHttp(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "description", "Test HTTP updated"),
resource.TestCheckResourceAttr(resourceName, "integration_method", "POST"),
resource.TestCheckResourceAttr(resourceName, "integration_response_selection_expression", "${integration.response.statuscode}"),
resource.TestCheckResourceAttr(resourceName, "integration_subtype", ""),
resource.TestCheckResourceAttr(resourceName, "integration_type", "HTTP"),
resource.TestCheckResourceAttr(resourceName, "integration_uri", "http://www.example.org"),
resource.TestCheckResourceAttr(resourceName, "passthrough_behavior", "WHEN_NO_TEMPLATES"),
Expand Down Expand Up @@ -212,6 +216,7 @@ func TestAccAWSAPIGatewayV2Integration_LambdaWebSocket(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "description", "Test Lambda"),
resource.TestCheckResourceAttr(resourceName, "integration_method", "POST"),
resource.TestCheckResourceAttr(resourceName, "integration_response_selection_expression", "${integration.response.body.errorMessage}"),
resource.TestCheckResourceAttr(resourceName, "integration_subtype", ""),
resource.TestCheckResourceAttr(resourceName, "integration_type", "AWS"),
resource.TestCheckResourceAttrPair(resourceName, "integration_uri", lambdaResourceName, "invoke_arn"),
resource.TestCheckResourceAttr(resourceName, "passthrough_behavior", "WHEN_NO_MATCH"),
Expand Down Expand Up @@ -256,6 +261,7 @@ func TestAccAWSAPIGatewayV2Integration_LambdaHttp(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "description", "Test Lambda"),
resource.TestCheckResourceAttr(resourceName, "integration_method", "POST"),
resource.TestCheckResourceAttr(resourceName, "integration_response_selection_expression", ""),
resource.TestCheckResourceAttr(resourceName, "integration_subtype", ""),
resource.TestCheckResourceAttr(resourceName, "integration_type", "AWS_PROXY"),
resource.TestCheckResourceAttrPair(resourceName, "integration_uri", lambdaResourceName, "invoke_arn"),
resource.TestCheckResourceAttr(resourceName, "passthrough_behavior", ""),
Expand Down Expand Up @@ -300,6 +306,7 @@ func TestAccAWSAPIGatewayV2Integration_VpcLinkWebSocket(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "description", "Test VPC Link"),
resource.TestCheckResourceAttr(resourceName, "integration_method", "PUT"),
resource.TestCheckResourceAttr(resourceName, "integration_response_selection_expression", ""),
resource.TestCheckResourceAttr(resourceName, "integration_subtype", ""),
resource.TestCheckResourceAttr(resourceName, "integration_type", "HTTP_PROXY"),
resource.TestCheckResourceAttr(resourceName, "integration_uri", "http://www.example.net"),
resource.TestCheckResourceAttr(resourceName, "passthrough_behavior", "NEVER"),
Expand Down Expand Up @@ -345,6 +352,7 @@ func TestAccAWSAPIGatewayV2Integration_VpcLinkHttp(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "description", "Test private integration"),
resource.TestCheckResourceAttr(resourceName, "integration_method", "GET"),
resource.TestCheckResourceAttr(resourceName, "integration_response_selection_expression", ""),
resource.TestCheckResourceAttr(resourceName, "integration_subtype", ""),
resource.TestCheckResourceAttr(resourceName, "integration_type", "HTTP_PROXY"),
resource.TestCheckResourceAttrPair(resourceName, "integration_uri", lbListenerResourceName, "arn"),
resource.TestCheckResourceAttr(resourceName, "passthrough_behavior", ""),
Expand Down Expand Up @@ -373,6 +381,7 @@ func TestAccAWSAPIGatewayV2Integration_VpcLinkHttp(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "description", "Test private integration updated"),
resource.TestCheckResourceAttr(resourceName, "integration_method", "POST"),
resource.TestCheckResourceAttr(resourceName, "integration_response_selection_expression", ""),
resource.TestCheckResourceAttr(resourceName, "integration_subtype", ""),
resource.TestCheckResourceAttr(resourceName, "integration_type", "HTTP_PROXY"),
resource.TestCheckResourceAttrPair(resourceName, "integration_uri", lbListenerResourceName, "arn"),
resource.TestCheckResourceAttr(resourceName, "passthrough_behavior", ""),
Expand All @@ -394,6 +403,50 @@ func TestAccAWSAPIGatewayV2Integration_VpcLinkHttp(t *testing.T) {
})
}

func TestAccAWSAPIGatewayV2Integration_AwsServiceIntegration(t *testing.T) {
var apiId string
var v apigatewayv2.GetIntegrationOutput
resourceName := "aws_apigatewayv2_integration.test"
rName := acctest.RandomWithPrefix("tf-acc-test")

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSAPIGatewayV2IntegrationDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSAPIGatewayV2IntegrationConfig_sqsIntegration(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSAPIGatewayV2IntegrationExists(resourceName, &apiId, &v),
resource.TestCheckResourceAttr(resourceName, "connection_type", "INTERNET"),
resource.TestCheckResourceAttr(resourceName, "content_handling_strategy", ""),
resource.TestCheckResourceAttr(resourceName, "description", "Test SQS send"),
resource.TestCheckResourceAttr(resourceName, "integration_method", ""),
resource.TestCheckResourceAttr(resourceName, "integration_response_selection_expression", ""),
resource.TestCheckResourceAttr(resourceName, "integration_subtype", "SQS-SendMessage"),
resource.TestCheckResourceAttr(resourceName, "integration_type", "AWS_PROXY"),
resource.TestCheckResourceAttr(resourceName, "integration_uri", ""),
resource.TestCheckResourceAttr(resourceName, "passthrough_behavior", ""),
resource.TestCheckResourceAttr(resourceName, "payload_format_version", "1.0"),
resource.TestCheckResourceAttr(resourceName, "request_parameters.%", "2"),
resource.TestCheckResourceAttr(resourceName, "request_parameters.QueueUrl", "$request.header.queueUrl"),
resource.TestCheckResourceAttr(resourceName, "request_parameters.MessageBody", "$request.body.message"),
resource.TestCheckResourceAttr(resourceName, "request_templates.%", "0"),
resource.TestCheckResourceAttr(resourceName, "template_selection_expression", ""),
resource.TestCheckResourceAttr(resourceName, "timeout_milliseconds", "29000"),
resource.TestCheckResourceAttr(resourceName, "tls_config.#", "0"),
),
},
{
ResourceName: resourceName,
ImportStateIdFunc: testAccAWSAPIGatewayV2IntegrationImportStateIdFunc(resourceName),
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func testAccCheckAWSAPIGatewayV2IntegrationDestroy(s *terraform.State) error {
conn := testAccProvider.Meta().(*AWSClient).apigatewayv2conn

Expand Down Expand Up @@ -776,3 +829,55 @@ resource "aws_apigatewayv2_integration" "test" {
}
`, rName))
}

func testAccAWSAPIGatewayV2IntegrationConfig_sqsIntegration(rName string) string {
return composeConfig(
testAccAWSAPIGatewayV2IntegrationConfig_apiHttp(rName),
fmt.Sprintf(`
resource "aws_iam_role" "test" {
name = %[1]q
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Service": "apigateway.amazonaws.com"},
"Action": "sts:AssumeRole"
}]
}
EOF
}
resource "aws_iam_role_policy" "test" {
name = %[1]q
role = aws_iam_role.test.id
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": ["sqs:*"],
"Resource": "*"
}]
}
EOF
}
resource "aws_apigatewayv2_integration" "test" {
api_id = aws_apigatewayv2_api.test.id
credentials_arn = aws_iam_role.test.arn
description = "Test SQS send"
integration_type = "AWS_PROXY"
integration_subtype = "SQS-SendMessage"
request_parameters = {
"QueueUrl" = "$request.header.queueUrl"
"MessageBody" = "$request.body.message"
}
depends_on = [aws_iam_role_policy.test]
}
`, rName))
}
18 changes: 18 additions & 0 deletions website/docs/r/apigatewayv2_integration.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,23 @@ resource "aws_apigatewayv2_integration" "example" {
}
```

### AWS Service Integration

```hcl
resource "aws_apigatewayv2_integration" "example" {
api_id = aws_apigatewayv2_api.example.id
credentials_arn = aws_iam_role.example.arn
description = "SQS example"
integration_type = "AWS_PROXY"
integration_subtype = "SQS-SendMessage"
request_parameters = {
"QueueUrl" = "$request.header.queueUrl"
"MessageBody" = "$request.body.message"
}
}
```

## Argument Reference

The following arguments are supported:
Expand All @@ -59,6 +76,7 @@ Valid values: `AWS`, `AWS_PROXY`, `HTTP`, `HTTP_PROXY`, `MOCK`.
* `credentials_arn` - (Optional) The credentials required for the integration, if any.
* `description` - (Optional) The description of the integration.
* `integration_method` - (Optional) The integration's HTTP method. Must be specified if `integration_type` is not `MOCK`.
* `integration_subtype` - (Optional) Specifies the AWS service action to invoke. Supported only for HTTP APIs when `integration_type` is `AWS_PROXY`. See the [AWS service integration reference](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-aws-services-reference.html) documentation for supported values.
* `integration_uri` - (Optional) The URI of the Lambda function for a Lambda proxy integration, when `integration_type` is `AWS_PROXY`.
For an `HTTP` integration, specify a fully-qualified URL. For an HTTP API private integration, specify the ARN of an Application Load Balancer listener, Network Load Balancer listener, or AWS Cloud Map service.
* `passthrough_behavior` - (Optional) The pass-through behavior for incoming requests based on the Content-Type header in the request, and the available mapping templates specified as the `request_templates` attribute.
Expand Down

0 comments on commit 373a23c

Please sign in to comment.