Skip to content

Commit

Permalink
Add AWS ApiGateway Authorizer resource
Browse files Browse the repository at this point in the history
  • Loading branch information
mvantellingen committed Apr 13, 2016
1 parent f5f84ec commit e793f22
Show file tree
Hide file tree
Showing 4 changed files with 383 additions and 0 deletions.
1 change: 1 addition & 0 deletions builtin/providers/aws/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ func Provider() terraform.ResourceProvider {
"aws_ami_copy": resourceAwsAmiCopy(),
"aws_ami_from_instance": resourceAwsAmiFromInstance(),
"aws_api_gateway_api_key": resourceAwsApiGatewayApiKey(),
"aws_api_gateway_authorizer": resourceAwsApiGatewayAuthorizer(),
"aws_api_gateway_deployment": resourceAwsApiGatewayDeployment(),
"aws_api_gateway_integration": resourceAwsApiGatewayIntegration(),
"aws_api_gateway_integration_response": resourceAwsApiGatewayIntegrationResponse(),
Expand Down
189 changes: 189 additions & 0 deletions builtin/providers/aws/resource_aws_api_gateway_authorizer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
package aws

import (
"fmt"
"log"
"time"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/service/apigateway"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
)

func resourceAwsApiGatewayAuthorizer() *schema.Resource {
return &schema.Resource{
Create: resourceAwsApiGatewayAuthorizerCreate,
Read: resourceAwsApiGatewayAuthorizerRead,
Update: resourceAwsApiGatewayAuthorizerUpdate,
Delete: resourceAwsApiGatewayAuthorizerDelete,

Schema: map[string]*schema.Schema{

"name": &schema.Schema{
Type: schema.TypeString,
Required: true,
},

"authorizer_uri": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},

"identity_source": &schema.Schema{
Type: schema.TypeString,
Required: true,
},

"rest_api_id": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},

"type": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},

"credentials": &schema.Schema{
Type: schema.TypeString,
Optional: true,
},

"result_in_ttl": &schema.Schema{
Type: schema.TypeInt,
Optional: true,
},

"identity_validation_expression": &schema.Schema{
Type: schema.TypeString,
Optional: true,
},
},
}
}

func resourceAwsApiGatewayAuthorizerCreate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).apigateway
// Create the gateway
log.Printf("[DEBUG] Creating API Gateway Authorizer")

var credentials *string
if v, ok := d.GetOk("credentials"); ok {
credentials = aws.String(v.(string))
}

var result_in_ttl *int64
if v, ok := d.GetOk("result_in_ttl"); ok {
result_in_ttl = aws.Int64(int64(v.(int)))
}

var identity_validation_expression *string
if v, ok := d.GetOk("identity_validation_expression"); ok {
identity_validation_expression = aws.String(v.(string))
}

var err error
authorizer, err := conn.CreateAuthorizer(&apigateway.CreateAuthorizerInput{
AuthorizerUri: aws.String(d.Get("authorizer_uri").(string)),
IdentitySource: aws.String(d.Get("identity_source").(string)),
Name: aws.String(d.Get("name").(string)),
RestApiId: aws.String(d.Get("rest_api_id").(string)),
Type: aws.String(d.Get("type").(string)),

AuthorizerCredentials: credentials,
AuthorizerResultTtlInSeconds: result_in_ttl,
IdentityValidationExpression: identity_validation_expression,
})
if err != nil {
return fmt.Errorf("Error creating API Gateway Authorizer: %s", err)
}

d.SetId(*authorizer.Id)
log.Printf("[DEBUG] API Gateway Authorizer ID: %s", d.Id())

return nil
}

func resourceAwsApiGatewayAuthorizerRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).apigateway

log.Printf("[DEBUG] Reading API Gateway Deployment %s", d.Id())
out, err := conn.GetAuthorizer(&apigateway.GetAuthorizerInput{
RestApiId: aws.String(d.Get("rest_api_id").(string)),
AuthorizerId: aws.String(d.Id()),
})
if err != nil {
if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == "NotFoundException" {
d.SetId("")
return nil
}
return err
}
log.Printf("[DEBUG] Received API Gateway Authorizer: %s", out)
d.SetId(*out.Id)

return nil
}

func resourceAwsApiGatewayAuthorizerUpdateOperations(d *schema.ResourceData) []*apigateway.PatchOperation {
operations := make([]*apigateway.PatchOperation, 0)

if d.HasChange("description") {
operations = append(operations, &apigateway.PatchOperation{
Op: aws.String("replace"),
Path: aws.String("/description"),
Value: aws.String(d.Get("description").(string)),
})
}

return operations
}

func resourceAwsApiGatewayAuthorizerUpdate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).apigateway

log.Printf("[DEBUG] Updating API Gateway API Key: %s", d.Id())

_, err := conn.UpdateAuthorizer(&apigateway.UpdateAuthorizerInput{
AuthorizerId: aws.String(d.Id()),
RestApiId: aws.String(d.Get("rest_api_id").(string)),
PatchOperations: resourceAwsApiGatewayAuthorizerUpdateOperations(d),
})
if err != nil {
return err
}

return resourceAwsApiGatewayAuthorizerRead(d, meta)
}

func resourceAwsApiGatewayAuthorizerDelete(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).apigateway
log.Printf("[DEBUG] Deleting API Gateway Authorizer: %s", d.Id())

return resource.Retry(5*time.Minute, func() *resource.RetryError {
log.Printf("[DEBUG] schema is %#v", d)
_, err := conn.DeleteAuthorizer(&apigateway.DeleteAuthorizerInput{
AuthorizerId: aws.String(d.Id()),
RestApiId: aws.String(d.Get("rest_api_id").(string)),
})
if err == nil {
return nil
}

apigatewayErr, ok := err.(awserr.Error)
if apigatewayErr.Code() == "NotFoundException" {
return nil
}

if !ok {
return resource.NonRetryableError(err)
}

return resource.NonRetryableError(err)
})
}
144 changes: 144 additions & 0 deletions builtin/providers/aws/resource_aws_api_gateway_authorizer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
package aws

import (
"fmt"
"testing"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/service/apigateway"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)

func TestAccAWSAPIGatewayAuthorizer_basic(t *testing.T) {
var conf apigateway.Authorizer

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSAPIGatewayAuthorizerDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccAWSAPIGatewayAuthorizerConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSAPIGatewayAuthorizerExists("aws_api_gateway_authorizer.test", &conf),
resource.TestCheckResourceAttr("aws_api_gateway_authorizer.test", "name", "test"),
resource.TestCheckResourceAttr("aws_api_gateway_authorizer.test", "identity_source", "method.request.header.Authorization"),
resource.TestCheckResourceAttr("aws_api_gateway_authorizer.test", "type", "TOKEN"),
resource.TestCheckResourceAttr("aws_api_gateway_authorizer.test", "result_in_ttl", "300"),
),
},
},
})
}

func testAccCheckAWSAPIGatewayAuthorizerExists(n string, res *apigateway.Authorizer) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Not found: %s", n)
}

if rs.Primary.ID == "" {
return fmt.Errorf("No API Gateway Authorizer ID is set")
}

conn := testAccProvider.Meta().(*AWSClient).apigateway

req := &apigateway.GetAuthorizerInput{
AuthorizerId: aws.String(rs.Primary.ID),
RestApiId: aws.String(s.RootModule().Resources["aws_api_gateway_rest_api.test"].Primary.ID),
}
describe, err := conn.GetAuthorizer(req)
if err != nil {
return err
}
if *describe.Id != rs.Primary.ID {
return fmt.Errorf("APIGateway Authorizer not found")
}

*res = *describe

return nil
}
}

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

for _, rs := range s.RootModule().Resources {
if rs.Type != "aws_api_gateway_authorizer" {
continue
}

req := &apigateway.GetAuthorizersInput{
RestApiId: aws.String(s.RootModule().Resources["aws_api_gateway_rest_api.test"].Primary.ID),
}
describe, err := conn.GetAuthorizers(req)

if err == nil {
if len(describe.Items) != 0 &&
*describe.Items[0].Id == rs.Primary.ID {
return fmt.Errorf("API Gateway Authorizer still exists")
}
}

aws2err, ok := err.(awserr.Error)
if !ok {
return err
}
if aws2err.Code() != "NotFoundException" {
return err
}

return nil
}

return nil
}

const testAccAWSAPIGatewayAuthorizerConfig = `
resource "aws_api_gateway_rest_api" "test" {
name = "test"
}
resource "aws_iam_role" "iam_for_lambda" {
name = "iam_for_lambda"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
resource "aws_lambda_function" "lambda_auth" {
filename = "test-fixtures/lambdatest.zip"
function_name = "lambda_auth"
role = "${aws_iam_role.iam_for_lambda.arn}"
handler = "exports.example"
}
resource "aws_api_gateway_authorizer" "test" {
rest_api_id = "${aws_api_gateway_rest_api.test.id}"
name = "test"
authorizer_uri = "arn:aws:apigateway:eu-west-1:lambda:path/2015-03-31/functions/${aws_lambda_function.lambda_auth.arn}/invocations"
credentials = "arn:aws:iam::108016248797:role/lambda_auth"
identity_source = "method.request.header.Authorization"
type = "TOKEN"
result_in_ttl = 300
}
`
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
layout: "aws"
page_title: "AWS: aws_api_gateway_authorizer"
sidebar_current: "docs-aws-resource-api-gateway-authorizer"
description: |-
Provides an API Gateway Authorizer.
---

# aws\_api\_gateway\_authorizer

Provides an API Gateway Authorizer.

## Example Usage

```
resource "aws_api_gateway_rest_api" "MyDemoAPI" {
name = "MyDemoAPI"
description = "This is my API for demonstration purposes"
}
resource "aws_api_gateway_authorizer" "test" {
rest_api_id = "${aws_api_gateway_rest_api.test.id}"
name = "my_authorizer"
authorizer_uri = "arn:aws:apigateway:eu-west-1:lambda:path/2015-03-31/functions/arn:aws:lambda:eu-west-1:123456789012:function:auth_function/invocations"
credentials = "arn:aws:iam::123456789012:role/lambda_auth"
identity_source = "method.request.header.Authorization"
type = "TOKEN"
result_in_ttl = 300
}
```

## Argument Reference

The following arguments are supported:

* `type` - (Required) The type of the authorizer.
* `rest_api_id` - (Required) The ID of the associated REST API
* `name` - (Required) The name of the authorizer.
* `authorizer_uri` - (Required) Specifies the authorizer's Uniform Resource Identifier (URI).
* `identity_source` - (Required) The source of the identity in an incoming request.
* `identity_validation_expression` - (Optional) The TTL of cached authorizer results.
* `result_in_ttl` - (Optional) The TTL of cached authorizer results.
* `credentials` - (Optional) Specifies the credentials required for the authorizer, if any.

## Attribute Reference

The following attributes are exported:

* `id` - The ID of the authorizer

0 comments on commit e793f22

Please sign in to comment.