Merge #8353: New resources for custom domains on AWS API Gateway
This commit is contained in:
commit
38289ddbd5
|
@ -1,5 +1,8 @@
|
|||
## 0.7.2 (Unreleased)
|
||||
|
||||
FEATURES:
|
||||
* **New Resources:** `aws_api_gateway_domain_name` and `aws_api_gateway_base_path_mapping`, for using custom domains in AWS API Gateway [GH-8353]
|
||||
|
||||
BUG FIXES:
|
||||
* core: fix crash case when malformed JSON given [GH-8295]
|
||||
* core: when asking for input, spaces are allowed [GH-8394]
|
||||
|
|
|
@ -164,7 +164,9 @@ func Provider() terraform.ResourceProvider {
|
|||
"aws_api_gateway_account": resourceAwsApiGatewayAccount(),
|
||||
"aws_api_gateway_api_key": resourceAwsApiGatewayApiKey(),
|
||||
"aws_api_gateway_authorizer": resourceAwsApiGatewayAuthorizer(),
|
||||
"aws_api_gateway_base_path_mapping": resourceAwsApiGatewayBasePathMapping(),
|
||||
"aws_api_gateway_deployment": resourceAwsApiGatewayDeployment(),
|
||||
"aws_api_gateway_domain_name": resourceAwsApiGatewayDomainName(),
|
||||
"aws_api_gateway_integration": resourceAwsApiGatewayIntegration(),
|
||||
"aws_api_gateway_integration_response": resourceAwsApiGatewayIntegrationResponse(),
|
||||
"aws_api_gateway_method": resourceAwsApiGatewayMethod(),
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
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 resourceAwsApiGatewayBasePathMapping() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Create: resourceAwsApiGatewayBasePathMappingCreate,
|
||||
Read: resourceAwsApiGatewayBasePathMappingRead,
|
||||
Delete: resourceAwsApiGatewayBasePathMappingDelete,
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"api_id": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
"base_path": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
"stage_name": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
"domain_name": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceAwsApiGatewayBasePathMappingCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
conn := meta.(*AWSClient).apigateway
|
||||
|
||||
err := resource.Retry(30*time.Second, func() *resource.RetryError {
|
||||
_, err := conn.CreateBasePathMapping(&apigateway.CreateBasePathMappingInput{
|
||||
RestApiId: aws.String(d.Get("api_id").(string)),
|
||||
DomainName: aws.String(d.Get("domain_name").(string)),
|
||||
BasePath: aws.String(d.Get("base_path").(string)),
|
||||
Stage: aws.String(d.Get("stage_name").(string)),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
if err, ok := err.(awserr.Error); ok && err.Code() != "BadRequestException" {
|
||||
return resource.NonRetryableError(err)
|
||||
}
|
||||
|
||||
return resource.RetryableError(
|
||||
fmt.Errorf("Error creating Gateway base path mapping: %s", err),
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error creating Gateway base path mapping: %s", err)
|
||||
}
|
||||
|
||||
id := fmt.Sprintf("%s/%s", d.Get("domain_name").(string), d.Get("base_path").(string))
|
||||
d.SetId(id)
|
||||
|
||||
return resourceAwsApiGatewayBasePathMappingRead(d, meta)
|
||||
}
|
||||
|
||||
func resourceAwsApiGatewayBasePathMappingRead(d *schema.ResourceData, meta interface{}) error {
|
||||
conn := meta.(*AWSClient).apigateway
|
||||
|
||||
domainName := d.Get("domain_name").(string)
|
||||
basePath := d.Get("base_path").(string)
|
||||
|
||||
if domainName == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
mapping, err := conn.GetBasePathMapping(&apigateway.GetBasePathMappingInput{
|
||||
DomainName: aws.String(domainName),
|
||||
BasePath: aws.String(basePath),
|
||||
})
|
||||
if err != nil {
|
||||
if err, ok := err.(awserr.Error); ok && err.Code() == "NotFoundException" {
|
||||
log.Printf("[WARN] API gateway base path mapping %s has vanished\n", d.Id())
|
||||
d.SetId("")
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("Error reading Gateway base path mapping: %s", err)
|
||||
}
|
||||
|
||||
d.Set("base_path", *mapping.BasePath)
|
||||
d.Set("api_id", *mapping.RestApiId)
|
||||
d.Set("stage_name", *mapping.Stage)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceAwsApiGatewayBasePathMappingDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
conn := meta.(*AWSClient).apigateway
|
||||
|
||||
_, err := conn.DeleteBasePathMapping(&apigateway.DeleteBasePathMappingInput{
|
||||
DomainName: aws.String(d.Get("domain_name").(string)),
|
||||
BasePath: aws.String(d.Get("base_path").(string)),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
if err, ok := err.(awserr.Error); ok && err.Code() == "NotFoundException" {
|
||||
return nil
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,138 @@
|
|||
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 TestAccAWSAPIGatewayBasePath_basic(t *testing.T) {
|
||||
var conf apigateway.BasePathMapping
|
||||
|
||||
// Our test cert is for a wildcard on this domain
|
||||
name := fmt.Sprintf("%s.tf-acc.invalid", resource.UniqueId())
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckAWSAPIGatewayBasePathDestroy(name),
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testAccAWSAPIGatewayBasePathConfig(name),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckAWSAPIGatewayBasePathExists("aws_api_gateway_base_path_mapping.test", name, &conf),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testAccCheckAWSAPIGatewayBasePathExists(n string, name string, res *apigateway.BasePathMapping) 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 ID is set")
|
||||
}
|
||||
|
||||
conn := testAccProvider.Meta().(*AWSClient).apigateway
|
||||
|
||||
req := &apigateway.GetBasePathMappingInput{
|
||||
DomainName: aws.String(name),
|
||||
BasePath: aws.String("tf-acc"),
|
||||
}
|
||||
describe, err := conn.GetBasePathMapping(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if *describe.BasePath != "tf-acc" {
|
||||
return fmt.Errorf("base path mapping not found")
|
||||
}
|
||||
|
||||
*res = *describe
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testAccCheckAWSAPIGatewayBasePathDestroy(name string) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
conn := testAccProvider.Meta().(*AWSClient).apigateway
|
||||
|
||||
for _, rs := range s.RootModule().Resources {
|
||||
if rs.Type != "aws_api_gateway_rest_api" {
|
||||
continue
|
||||
}
|
||||
|
||||
req := &apigateway.GetBasePathMappingsInput{
|
||||
DomainName: aws.String(name),
|
||||
}
|
||||
_, err := conn.GetBasePathMappings(req)
|
||||
|
||||
if err != nil {
|
||||
if err, ok := err.(awserr.Error); ok && err.Code() == "NotFoundException" {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
return fmt.Errorf("expected error reading deleted base path, but got success")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testAccAWSAPIGatewayBasePathConfig(name string) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "aws_api_gateway_rest_api" "test" {
|
||||
name = "tf-acc-apigateway-base-path-mapping"
|
||||
description = "Terraform Acceptance Tests"
|
||||
}
|
||||
# API gateway won't let us deploy an empty API
|
||||
resource "aws_api_gateway_resource" "test" {
|
||||
rest_api_id = "${aws_api_gateway_rest_api.test.id}"
|
||||
parent_id = "${aws_api_gateway_rest_api.test.root_resource_id}"
|
||||
path_part = "tf-acc"
|
||||
}
|
||||
resource "aws_api_gateway_method" "test" {
|
||||
rest_api_id = "${aws_api_gateway_rest_api.test.id}"
|
||||
resource_id = "${aws_api_gateway_resource.test.id}"
|
||||
http_method = "GET"
|
||||
authorization = "NONE"
|
||||
}
|
||||
resource "aws_api_gateway_integration" "test" {
|
||||
rest_api_id = "${aws_api_gateway_rest_api.test.id}"
|
||||
resource_id = "${aws_api_gateway_resource.test.id}"
|
||||
http_method = "${aws_api_gateway_method.test.http_method}"
|
||||
type = "MOCK"
|
||||
}
|
||||
resource "aws_api_gateway_deployment" "test" {
|
||||
rest_api_id = "${aws_api_gateway_rest_api.test.id}"
|
||||
stage_name = "test"
|
||||
depends_on = ["aws_api_gateway_integration.test"]
|
||||
}
|
||||
resource "aws_api_gateway_base_path_mapping" "test" {
|
||||
api_id = "${aws_api_gateway_rest_api.test.id}"
|
||||
base_path = "tf-acc"
|
||||
stage_name = "${aws_api_gateway_deployment.test.stage_name}"
|
||||
domain_name = "${aws_api_gateway_domain_name.test.domain_name}"
|
||||
}
|
||||
resource "aws_api_gateway_domain_name" "test" {
|
||||
domain_name = "%s"
|
||||
certificate_name = "tf-apigateway-base-path-mapping-test"
|
||||
certificate_body = "%s"
|
||||
certificate_chain = "%s"
|
||||
certificate_private_key = "%s"
|
||||
}
|
||||
`, name, testAccAWSAPIGatewayCertBody, testAccAWSAPIGatewayCertChain, testAccAWSAPIGatewayCertPrivateKey)
|
||||
}
|
|
@ -0,0 +1,182 @@
|
|||
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 resourceAwsApiGatewayDomainName() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Create: resourceAwsApiGatewayDomainNameCreate,
|
||||
Read: resourceAwsApiGatewayDomainNameRead,
|
||||
Update: resourceAwsApiGatewayDomainNameUpdate,
|
||||
Delete: resourceAwsApiGatewayDomainNameDelete,
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
|
||||
"certificate_body": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
|
||||
"certificate_chain": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
|
||||
"certificate_name": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
|
||||
"certificate_private_key": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
|
||||
"domain_name": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
|
||||
"cloudfront_domain_name": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
|
||||
"cloudfront_zone_id": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceAwsApiGatewayDomainNameCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
conn := meta.(*AWSClient).apigateway
|
||||
log.Printf("[DEBUG] Creating API Gateway Domain Name")
|
||||
|
||||
domainName, err := conn.CreateDomainName(&apigateway.CreateDomainNameInput{
|
||||
CertificateBody: aws.String(d.Get("certificate_body").(string)),
|
||||
CertificateChain: aws.String(d.Get("certificate_chain").(string)),
|
||||
CertificateName: aws.String(d.Get("certificate_name").(string)),
|
||||
CertificatePrivateKey: aws.String(d.Get("certificate_private_key").(string)),
|
||||
DomainName: aws.String(d.Get("domain_name").(string)),
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error creating API Gateway Domain Name: %s", err)
|
||||
}
|
||||
|
||||
d.SetId(*domainName.DomainName)
|
||||
d.Set("cloudfront_domain_name", *domainName.DistributionDomainName)
|
||||
d.Set("cloudfront_zone_id", cloudFrontRoute53ZoneID)
|
||||
|
||||
return resourceAwsApiGatewayDomainNameRead(d, meta)
|
||||
}
|
||||
|
||||
func resourceAwsApiGatewayDomainNameRead(d *schema.ResourceData, meta interface{}) error {
|
||||
conn := meta.(*AWSClient).apigateway
|
||||
log.Printf("[DEBUG] Reading API Gateway Domain Name %s", d.Id())
|
||||
|
||||
domainName, err := conn.GetDomainName(&apigateway.GetDomainNameInput{
|
||||
DomainName: aws.String(d.Id()),
|
||||
})
|
||||
if err != nil {
|
||||
if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == "NotFoundException" {
|
||||
log.Printf("[WARN] API gateway domain name %s has vanished\n", d.Id())
|
||||
d.SetId("")
|
||||
return nil
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
d.Set("certificate_name", domainName.CertificateName)
|
||||
d.Set("certificate_upload_date", domainName.CertificateUploadDate)
|
||||
d.Set("cloudfront_domain_name", domainName.DistributionDomainName)
|
||||
d.Set("domain_name", domainName.DomainName)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceAwsApiGatewayDomainNameUpdateOperations(d *schema.ResourceData) []*apigateway.PatchOperation {
|
||||
operations := make([]*apigateway.PatchOperation, 0)
|
||||
|
||||
if d.HasChange("certificate_body") {
|
||||
operations = append(operations, &apigateway.PatchOperation{
|
||||
Op: aws.String("replace"),
|
||||
Path: aws.String("/certificate_body"),
|
||||
Value: aws.String(d.Get("certificate_body").(string)),
|
||||
})
|
||||
}
|
||||
|
||||
if d.HasChange("certificate_chain") {
|
||||
operations = append(operations, &apigateway.PatchOperation{
|
||||
Op: aws.String("replace"),
|
||||
Path: aws.String("/certificate_chain"),
|
||||
Value: aws.String(d.Get("certificate_chain").(string)),
|
||||
})
|
||||
}
|
||||
|
||||
if d.HasChange("certificate_name") {
|
||||
operations = append(operations, &apigateway.PatchOperation{
|
||||
Op: aws.String("replace"),
|
||||
Path: aws.String("/certificate_name"),
|
||||
Value: aws.String(d.Get("certificate_name").(string)),
|
||||
})
|
||||
}
|
||||
|
||||
if d.HasChange("certificate_private_key") {
|
||||
operations = append(operations, &apigateway.PatchOperation{
|
||||
Op: aws.String("replace"),
|
||||
Path: aws.String("/certificate_private_key"),
|
||||
Value: aws.String(d.Get("certificate_private_key").(string)),
|
||||
})
|
||||
}
|
||||
|
||||
return operations
|
||||
}
|
||||
|
||||
func resourceAwsApiGatewayDomainNameUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||
conn := meta.(*AWSClient).apigateway
|
||||
log.Printf("[DEBUG] Updating API Gateway Domain Name %s", d.Id())
|
||||
|
||||
_, err := conn.UpdateDomainName(&apigateway.UpdateDomainNameInput{
|
||||
DomainName: aws.String(d.Id()),
|
||||
PatchOperations: resourceAwsApiGatewayDomainNameUpdateOperations(d),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return resourceAwsApiGatewayDomainNameRead(d, meta)
|
||||
}
|
||||
|
||||
func resourceAwsApiGatewayDomainNameDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
conn := meta.(*AWSClient).apigateway
|
||||
log.Printf("[DEBUG] Deleting API Gateway Domain Name: %s", d.Id())
|
||||
|
||||
return resource.Retry(5*time.Minute, func() *resource.RetryError {
|
||||
_, err := conn.DeleteDomainName(&apigateway.DeleteDomainNameInput{
|
||||
DomainName: aws.String(d.Id()),
|
||||
})
|
||||
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if apigatewayErr, ok := err.(awserr.Error); ok && apigatewayErr.Code() == "NotFoundException" {
|
||||
return nil
|
||||
}
|
||||
|
||||
return resource.NonRetryableError(err)
|
||||
})
|
||||
}
|
|
@ -0,0 +1,211 @@
|
|||
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 TestAccAWSAPIGatewayDomainName_basic(t *testing.T) {
|
||||
var conf apigateway.DomainName
|
||||
|
||||
// Our test cert is for a wildcard on this domain
|
||||
name := fmt.Sprintf("%s.tf-acc.invalid", resource.UniqueId())
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckAWSAPIGatewayDomainNameDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testAccAWSAPIGatewayDomainNameConfigCreate(name),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckAWSAPIGatewayDomainNameExists("aws_api_gateway_domain_name.test", &conf),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_api_gateway_domain_name.test", "certificate_body", testAccAWSAPIGatewayCertBody,
|
||||
),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_api_gateway_domain_name.test", "certificate_chain", testAccAWSAPIGatewayCertChain,
|
||||
),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_api_gateway_domain_name.test", "certificate_name", "tf-acc-apigateway-domain-name",
|
||||
),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_api_gateway_domain_name.test", "certificate_private_key", testAccAWSAPIGatewayCertPrivateKey,
|
||||
),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_api_gateway_domain_name.test", "domain_name", name,
|
||||
),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testAccCheckAWSAPIGatewayDomainNameExists(n string, res *apigateway.DomainName) 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 DomainName ID is set")
|
||||
}
|
||||
|
||||
conn := testAccProvider.Meta().(*AWSClient).apigateway
|
||||
|
||||
req := &apigateway.GetDomainNameInput{
|
||||
DomainName: aws.String(rs.Primary.ID),
|
||||
}
|
||||
describe, err := conn.GetDomainName(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if *describe.DomainName != rs.Primary.ID {
|
||||
return fmt.Errorf("APIGateway DomainName not found")
|
||||
}
|
||||
|
||||
*res = *describe
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testAccCheckAWSAPIGatewayDomainNameDestroy(s *terraform.State) error {
|
||||
conn := testAccProvider.Meta().(*AWSClient).apigateway
|
||||
|
||||
for _, rs := range s.RootModule().Resources {
|
||||
if rs.Type != "aws_api_gateway_api_key" {
|
||||
continue
|
||||
}
|
||||
|
||||
describe, err := conn.GetDomainNames(&apigateway.GetDomainNamesInput{})
|
||||
|
||||
if err == nil {
|
||||
if len(describe.Items) != 0 &&
|
||||
*describe.Items[0].DomainName == rs.Primary.ID {
|
||||
return fmt.Errorf("API Gateway DomainName still exists")
|
||||
}
|
||||
}
|
||||
|
||||
aws2err, ok := err.(awserr.Error)
|
||||
if !ok {
|
||||
return err
|
||||
}
|
||||
if aws2err.Code() != "NotFoundException" {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Expires on August 20, 2026
|
||||
const testAccAWSAPIGatewayCertBody = `-----BEGIN CERTIFICATE-----
|
||||
MIIEfjCCA2agAwIBAgIRAPHiUbRWC/Ff/reiyzqh3wAwDQYJKoZIhvcNAQELBQAw
|
||||
gcsxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNUGlyYXRlIEhh
|
||||
cmJvcjEZMBcGA1UECRMQNTg3OSBDb3R0b24gTGluazETMBEGA1UEERMKOTU1NTkt
|
||||
MTIyNzEVMBMGA1UEChMMRXhhbXBsZSwgSW5jMSgwJgYDVQQLEx9EZXBhcnRtZW50
|
||||
IG9mIFRlcnJhZm9ybSBUZXN0aW5nMRowGAYDVQQDExF0Zi1hY2MtY2EuaW52YWxp
|
||||
ZDEKMAgGA1UEBRMBMjAeFw0xNjA4MjIxNjQ1NTZaFw0yNjA4MjAxNjQ1NTZaMIHK
|
||||
MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDVBpcmF0ZSBIYXJi
|
||||
b3IxGTAXBgNVBAkTEDU4NzkgQ290dG9uIExpbmsxEzARBgNVBBETCjk1NTU5LTEy
|
||||
MjcxFTATBgNVBAoTDEV4YW1wbGUsIEluYzEoMCYGA1UECxMfRGVwYXJ0bWVudCBv
|
||||
ZiBUZXJyYWZvcm0gVGVzdGluZzEZMBcGA1UEAxMQKi50Zi1hY2MuaW52YWxpZDEK
|
||||
MAgGA1UEBRMBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL/xTPoz
|
||||
3tnvkLjthqsMKwWVtE1yi210UnseBYkc2w6iQUXMCsXkw2PZXW6QIW7o1GNjnrE5
|
||||
9jkeEJ2ABEYyor+ooaNZmjJ0dvY1tFerMhsOkQudDBz+eaR13UQvMFc42nFWrS5/
|
||||
XCInm4HjWblEfw2b/wbGwTPzIN3+zWdt2XTsSzIRUYgjXy/93aLIVhWaYDsP45RM
|
||||
C48qhJKSsYOVH/PSkgw4AfohDXzn2iltTUBFdGZqBufMW4sPp8G8DIOvt01NsXB2
|
||||
QLLVgcMJVegx9xxg50+cf6ILck5Ap/SzkCN7XYk8zWC36/QIkiQ6bMMy0nJtgE0B
|
||||
jwmwnFF+zF/A4oMCAwEAAaNcMFowDgYDVR0PAQH/BAQDAgWgMBkGA1UdJQQSMBAG
|
||||
CCsGAQUFBwMBBgRVHSUAMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAU/hWQ+UUh
|
||||
7EiLd0fCsgy1jvSgxkswDQYJKoZIhvcNAQELBQADggEBABnTdSEOqj2+7FTeiSR9
|
||||
iPGQ3swhrmk59j8XUszrlm6MvZX9AeV9gLcE9J0PfFaAcZM0pR+XZBmyZLoBxUgU
|
||||
8Y17yWwAxZo13EwgzTOmebDxm4W+Og4vBxsKS3x/L8D8BKdzBcmVJvggJqTs5Qau
|
||||
ePetAQcD/Tfbq7vY9fNQJ4XQTlF5sN625miijTQcNg/s/H2Fj3FENR3UaFiQDtLQ
|
||||
eatV0KGF/ik8XFHPbFm7XUZfUcDxvoaljglJfXyVttU956j892ZakvAHzhylFRyy
|
||||
/wJnKV7K3zQVCEV0n/dJpXhf7w9PuWHrCp+HZJLMPMtm1IPblVxPNwHhGBG40I+Z
|
||||
FSg=
|
||||
-----END CERTIFICATE-----
|
||||
`
|
||||
|
||||
// Expires on August 20, 2026
|
||||
const testAccAWSAPIGatewayCertChain = `-----BEGIN CERTIFICATE-----
|
||||
MIIEoDCCA4igAwIBAgIQRR1EBw7bN+mMYtXrrvzLdzANBgkqhkiG9w0BAQsFADCB
|
||||
yzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1QaXJhdGUgSGFy
|
||||
Ym9yMRkwFwYDVQQJExA1ODc5IENvdHRvbiBMaW5rMRMwEQYDVQQREwo5NTU1OS0x
|
||||
MjI3MRUwEwYDVQQKEwxFeGFtcGxlLCBJbmMxKDAmBgNVBAsTH0RlcGFydG1lbnQg
|
||||
b2YgVGVycmFmb3JtIFRlc3RpbmcxGjAYBgNVBAMTEXRmLWFjYy1jYS5pbnZhbGlk
|
||||
MQowCAYDVQQFEwEyMB4XDTE2MDgyMjE2NDU1NloXDTI2MDgyMDE2NDU1Nlowgcsx
|
||||
CzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNUGlyYXRlIEhhcmJv
|
||||
cjEZMBcGA1UECRMQNTg3OSBDb3R0b24gTGluazETMBEGA1UEERMKOTU1NTktMTIy
|
||||
NzEVMBMGA1UEChMMRXhhbXBsZSwgSW5jMSgwJgYDVQQLEx9EZXBhcnRtZW50IG9m
|
||||
IFRlcnJhZm9ybSBUZXN0aW5nMRowGAYDVQQDExF0Zi1hY2MtY2EuaW52YWxpZDEK
|
||||
MAgGA1UEBRMBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK7k1xdX
|
||||
HdA0HTajtSPvCwIeNE4HO3IsYn9jnUBvhQ52EJ72GPzlg91AhdVufIncJRjk51iP
|
||||
n86TO/bg/dx4d+G45aUFw7WmZGTTZjurhnVWCDPeeetItV3PmsWHkwTiBj4GJYW4
|
||||
1mJk0ACjmmGEyz24T46Cn87Tljk+ivdCQL/oYTjpC7jc2i5b7ziiwsToWMEljWV1
|
||||
cf/4qQNFmFnETbaQW2qcFdjUoO8N1gRNkC9yvOjo6Fc+lETRHn3e926jDSaqfbwJ
|
||||
hKKBoXciYnddNXgA83GBTdnsRiRoD4zFEhNThmgvy5MmkEEdwKl5QIz6ajo4Xxtd
|
||||
54XZpt0y/ZVy6BECAwEAAaN+MHwwDgYDVR0PAQH/BAQDAgIEMBkGA1UdJQQSMBAG
|
||||
CCsGAQUFBwMBBgRVHSUAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP4VkPlF
|
||||
IexIi3dHwrIMtY70oMZLMB8GA1UdIwQYMBaAFP4VkPlFIexIi3dHwrIMtY70oMZL
|
||||
MA0GCSqGSIb3DQEBCwUAA4IBAQBlXSOkvE/c8pcI6vijInnAWY+eX2W7njCzEfmP
|
||||
gkDeW/2A1/6eSM6C/ym+9zEgZ9YLxPfiQKzN8Ej+EziFiZW3ZBHnWcW9rZt36wFA
|
||||
swF2nIqWa5nkVnAX2aPVfULN1u1BQiv3XZqNNlBk6m9AsgxiZ9jtOY8oQQU3uDYe
|
||||
bs9ttLMKJApbe08sKmPawVlXHqj6qb85Pg4bzzknA+euRee9KIi87eTlWc/Ht+WN
|
||||
Huh16WqokePii7e/PAaiTAe7ubsPav29lzmHq2NooXrs+FljXveQJpBqu6wKKTXe
|
||||
6/5BBsp2474RiZgTbuO2Mbr2nwcoJ9V6iu1M9siCGbbt1nQr
|
||||
-----END CERTIFICATE-----
|
||||
`
|
||||
|
||||
const testAccAWSAPIGatewayCertPrivateKey = `-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAv/FM+jPe2e+QuO2GqwwrBZW0TXKLbXRSex4FiRzbDqJBRcwK
|
||||
xeTDY9ldbpAhbujUY2OesTn2OR4QnYAERjKiv6iho1maMnR29jW0V6syGw6RC50M
|
||||
HP55pHXdRC8wVzjacVatLn9cIiebgeNZuUR/DZv/BsbBM/Mg3f7NZ23ZdOxLMhFR
|
||||
iCNfL/3doshWFZpgOw/jlEwLjyqEkpKxg5Uf89KSDDgB+iENfOfaKW1NQEV0ZmoG
|
||||
58xbiw+nwbwMg6+3TU2xcHZAstWBwwlV6DH3HGDnT5x/ogtyTkCn9LOQI3tdiTzN
|
||||
YLfr9AiSJDpswzLScm2ATQGPCbCcUX7MX8DigwIDAQABAoIBAFSRcXQPpJFrDt2b
|
||||
sajtTItCYVV6MVpBVRHvsUqvDwkMjiu9ccWtPDVjENpk4IYoSWOdAc9eFVEnIPTz
|
||||
8W4oYzKEjusU0G6Ih92E3fd+cy4epeNzB2JC8L94OswO6oKThxNGuDjzXlmiD88T
|
||||
p3WMa1pIr/2BVqCX75Q/7qoyaQwtR/anvOes154gRGY70ucsUpEzo3fyfXdCKO/o
|
||||
y1quQ4mmCS50lPCJ3i8JZH2YmGY+xThnXzk7Q9ipjGrHTjinpX8f9tQB2RRwqlA/
|
||||
uQ+/q6cOKUAehLtriXyr2QAoCzdz1Lfm8L5KQ3EdrxUUe9dhs/a7bKw4N5eHjw/x
|
||||
eBUagsECgYEAyoaIqZ0ur5NQEHuY9Givs6a+ObWLjM18EdfQ7zX7NJRPL3q0jdkm
|
||||
KW+pn2OzoRxhwgaD6WuJJmj3rd3ledkwxoO6Efwo8x2z1u/T43FsknW/X3wJLLga
|
||||
fPU2T9lSHRufBQUAhPYkf4dSqUklHJ4YSMafbCkvSXKGZqGVLQfu1iECgYEA8p9s
|
||||
/5+d0Pcnykau7Hp8a9z9ehHEIF+ce/wb6/6p3fgCP04FLvKqs74p9SrEnyl9uiFx
|
||||
ZC9P2XhmEwNFGA+qKPaRBo4RoGeAYgCKD0BfdaGfmp6WLhO0pSnl4c06bXnvwqbD
|
||||
DhhT6UvMs6m/uSufwtfCGO48yYiY1z6DqBjuHCMCgYBWJyrltHbSu8D4cgucFRiB
|
||||
PPJ5DDCkIhmgYYWA7R7CvEB/OxyppvFj+RtYMYqNg8xWRH1DA7rhOw/5x4ZB8lGc
|
||||
cRbrZbBp033YdkdV3r9IAoz5aoNgoaSq+Yk0KIeU2FYqRXl2FltqYL+aQgJmjR5Z
|
||||
fxz8Xvy9qtlfuWcDM/e24QKBgQDGtH8mk+lCfUkfRuh4UJCaHnGSif5grS2R9ZZA
|
||||
n18rpbThd9qS6reXYgUm/5Hs8KRBzqX5cS4qY4rlw2XRIPMxfU6lWbFh96KToPFx
|
||||
MD1+L5JxpbRFpGnsYvYdCmHxy03r03wojRAcH7JU6o9U7j936hDTLjqmq7LRhid5
|
||||
goFwlQKBgQCGxTWqQu9FJjtmjdM/ARi7CcwWT40NI8ybyebjDtElekILFMUwO+/w
|
||||
M78Me3d5g/oyeS6qCfyK1f7vBb/WhxLBBegaqMGUWbRoKYD0LH5U3zkqZ9ehnDFB
|
||||
vhcEnoxPD9HmdFkRduJscyzVNJ50lMuQ3uk7zwiYuS/Z7shH81xzMQ==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
`
|
||||
|
||||
func testAccAWSAPIGatewayDomainNameConfigCreate(name string) string {
|
||||
return fmt.Sprintf(`
|
||||
resource "aws_api_gateway_domain_name" "test" {
|
||||
domain_name = "%s"
|
||||
certificate_body = "%v"
|
||||
certificate_chain = "%v"
|
||||
certificate_name = "tf-acc-apigateway-domain-name"
|
||||
certificate_private_key = "%v"
|
||||
}
|
||||
`, name, testAccAWSAPIGatewayCertBody, testAccAWSAPIGatewayCertChain, testAccAWSAPIGatewayCertPrivateKey)
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
---
|
||||
layout: "aws"
|
||||
page_title: "AWS: aws_api_gateway_base_path_mapping"
|
||||
sidebar_current: "docs-aws-resource-api-gateway-base-path-mapping"
|
||||
description: |-
|
||||
Connects a custom domain with a deployed API
|
||||
---
|
||||
|
||||
# aws\_api\_gateway\_base\_path\_mapping
|
||||
|
||||
Connects a custom domain name registered via `aws_api_gateway_domain_name`
|
||||
with a deployed API so that its methods can be called via the
|
||||
custom domain name.
|
||||
|
||||
## Example Usage
|
||||
|
||||
```
|
||||
resource "aws_api_gateway_deployment" "example" {
|
||||
# See aws_api_gateway_rest_api_docs for how to create this
|
||||
rest_api_id = "${aws_api_gateway_rest_api.MyDemoAPI.id}"
|
||||
stage_name = "live"
|
||||
}
|
||||
|
||||
resource "aws_api_gateway_domain_name" "example" {
|
||||
domain_name = "example.com"
|
||||
|
||||
certificate_name = "example-api"
|
||||
certificate_body = "${file("${path.module}/example.com/example.crt")}"
|
||||
certificate_chain = "${file("${path.module}/example.com/ca.crt")}"
|
||||
certificate_private_key = "${file("${path.module}/example.com/example.key")}"
|
||||
}
|
||||
|
||||
resource "aws_api_gateway_base_path_mapping" "test" {
|
||||
api_id = "${aws_api_gateway_rest_api.MyDemoAPI.id}"
|
||||
stage = "${aws_api_gateway_deployment.example.stage_name}"
|
||||
domain_name = "${aws_api_gateway_domain_name.example.domain_name}"
|
||||
}
|
||||
```
|
||||
|
||||
## Argument Reference
|
||||
|
||||
The following arguments are supported:
|
||||
|
||||
* `domain_name` - (Required) The already-registered domain name to connect the API to.
|
||||
* `api_id` - (Required) The id of the API to connect.
|
||||
* `stage` - (Optional) The name of a specific deployment stage to expose at the given path. If omitted, callers may select any stage by including its name as a path element after the base path.
|
||||
* `base_path` - (Optional) Path segment that must be prepended to the path when accessing the API via this mapping. If omitted, the API is exposed at the root of the given domain.
|
|
@ -0,0 +1,75 @@
|
|||
---
|
||||
layout: "aws"
|
||||
page_title: "AWS: aws_api_gateway_domain_name"
|
||||
sidebar_current: "docs-aws-resource-api-gateway-domain-name"
|
||||
description: |-
|
||||
Registers a custom domain name for use with AWS API Gateway.
|
||||
---
|
||||
|
||||
# aws\_api\_gateway\_domain\_name
|
||||
|
||||
Registers a custom domain name for use with AWS API Gateway.
|
||||
|
||||
This resource just establishes ownership of and the TLS settings for
|
||||
a particular domain name. An API can be attached to a particular path
|
||||
under the registered domain name using
|
||||
[the `aws_api_gateway_base_path_mapping` resource](api_gateway_base_path_mapping.html).
|
||||
|
||||
Internally API Gateway creates a CloudFront distribution to
|
||||
route requests on the given hostname. In addition to this resource
|
||||
it's necessary to create a DNS record corresponding to the
|
||||
given domain name which is an alias (either Route53 alias or
|
||||
traditional CNAME) to the Cloudfront domain name exported in the
|
||||
`cloudfront_domain_name` attribute.
|
||||
|
||||
## Example Usage
|
||||
|
||||
```
|
||||
resource "aws_api_gateway_domain_name" "example" {
|
||||
domain_name = "api.example.com"
|
||||
|
||||
certificate_name = "example-api"
|
||||
certificate_body = "${file("${path.module}/example.com/example.crt")}"
|
||||
certificate_chain = "${file("${path.module}/example.com/ca.crt")}"
|
||||
certificate_private_key = "${file("${path.module}/example.com/example.key")}"
|
||||
}
|
||||
|
||||
# Example DNS record using Route53.
|
||||
# Route53 is not specifically required; any DNS host can be used.
|
||||
resource "aws_route53_record" "example" {
|
||||
zone_id = "${aws_route53_zone.example.id}" # See aws_route53_zone for how to create this
|
||||
|
||||
name = "${aws_api_gateway_domain_name.example.domain_name}"
|
||||
type = "A"
|
||||
|
||||
alias {
|
||||
name = "${aws_api_gateway_domain_name.example.cloudfront_domain_name}"
|
||||
zone_id = "${aws_api_gateway_domain_name.example.cloudfront_zone_id}"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Argument Reference
|
||||
|
||||
The following arguments are supported:
|
||||
|
||||
* `domain_name` - (Required) The fully-qualified domain name to register
|
||||
* `certificate_name` - (Required) The unique name to use when registering this
|
||||
cert as an IAM server certificate
|
||||
* `certificate_body` - (Required) The certificate issued for the domain name
|
||||
being registered, in PEM format
|
||||
* `certificate_chain` - (Required) The certificate for the CA that issued the
|
||||
certificate, along with any intermediate CA certificates required to
|
||||
create an unbroken chain to a certificate trusted by the intended API clients.
|
||||
* `certificate_private_key` - (Required) The private key associated with the
|
||||
domain certificate given in `certificate_body`.
|
||||
|
||||
## Attributes Reference
|
||||
|
||||
The following attributes are exported:
|
||||
|
||||
* `id` - The internal id assigned to this domain name by API Gateway.
|
||||
* `cloudfront_domain_name` - The hostname created by Cloudfront to represent
|
||||
the distribution that implements this domain name mapping.
|
||||
* `cloudfront_zone_id` - For convenience, the hosted zone id (`Z2FDTNDATAQYW2`)
|
||||
that can be used to create a Route53 alias record for the distribution.
|
|
@ -56,9 +56,15 @@
|
|||
<li<%= sidebar_current("docs-aws-resource-api-gateway-authorizer") %>>
|
||||
<a href="/docs/providers/aws/r/api_gateway_authorizer.html">aws_api_gateway_authorizer</a>
|
||||
</li>
|
||||
<li<%= sidebar_current("docs-aws-resource-api-gateway-base-path-mapping") %>>
|
||||
<a href="/docs/providers/aws/r/api_gateway_base_path_mapping.html">aws_api_gateway_base_path_mapping</a>
|
||||
</li>
|
||||
<li<%= sidebar_current("docs-aws-resource-api-gateway-deployment") %>>
|
||||
<a href="/docs/providers/aws/r/api_gateway_deployment.html">aws_api_gateway_deployment</a>
|
||||
</li>
|
||||
<li<%= sidebar_current("docs-aws-resource-api-gateway-domain-name") %>>
|
||||
<a href="/docs/providers/aws/r/api_gateway_domain_name.html">aws_api_gateway_domain_name</a>
|
||||
</li>
|
||||
<li<%= sidebar_current("docs-aws-resource-api-gateway-integration") %>>
|
||||
<a href="/docs/providers/aws/r/api_gateway_integration.html">aws_api_gateway_integration</a>
|
||||
</li>
|
||||
|
|
Loading…
Reference in New Issue