Merge pull request #2226 from Banno/add-aws-route53-health-checks-squashed
provider/aws: add aws_route53_health_check (rebase,squash+docs)
This commit is contained in:
commit
924278c33f
|
@ -125,8 +125,9 @@ func Provider() terraform.ResourceProvider {
|
|||
"aws_route53_record": resourceAwsRoute53Record(),
|
||||
"aws_route53_zone_association": resourceAwsRoute53ZoneAssociation(),
|
||||
"aws_route53_zone": resourceAwsRoute53Zone(),
|
||||
"aws_route_table_association": resourceAwsRouteTableAssociation(),
|
||||
"aws_route53_health_check": resourceAwsRoute53HealthCheck(),
|
||||
"aws_route_table": resourceAwsRouteTable(),
|
||||
"aws_route_table_association": resourceAwsRouteTableAssociation(),
|
||||
"aws_s3_bucket": resourceAwsS3Bucket(),
|
||||
"aws_security_group": resourceAwsSecurityGroup(),
|
||||
"aws_security_group_rule": resourceAwsSecurityGroupRule(),
|
||||
|
|
|
@ -0,0 +1,211 @@
|
|||
package aws
|
||||
|
||||
import (
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/service/route53"
|
||||
)
|
||||
|
||||
func resourceAwsRoute53HealthCheck() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Create: resourceAwsRoute53HealthCheckCreate,
|
||||
Read: resourceAwsRoute53HealthCheckRead,
|
||||
Update: resourceAwsRoute53HealthCheckUpdate,
|
||||
Delete: resourceAwsRoute53HealthCheckDelete,
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"type": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
"failure_threshold": &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
},
|
||||
"request_interval": &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ForceNew: true, // todo this should be updateable but the awslabs route53 service doesnt have the ability
|
||||
},
|
||||
"ip_address": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
"fqdn": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"port": &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
},
|
||||
|
||||
"resource_path": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"search_string": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"tags": tagsSchema(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceAwsRoute53HealthCheckUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||
conn := meta.(*AWSClient).r53conn
|
||||
|
||||
updateHealthCheck := &route53.UpdateHealthCheckInput{
|
||||
HealthCheckID: aws.String(d.Id()),
|
||||
}
|
||||
|
||||
if d.HasChange("failure_threshold") {
|
||||
updateHealthCheck.FailureThreshold = aws.Long(int64(d.Get("failure_threshold").(int)))
|
||||
}
|
||||
|
||||
if d.HasChange("fqdn") {
|
||||
updateHealthCheck.FullyQualifiedDomainName = aws.String(d.Get("fqdn").(string))
|
||||
}
|
||||
|
||||
if d.HasChange("port") {
|
||||
updateHealthCheck.Port = aws.Long(int64(d.Get("port").(int)))
|
||||
}
|
||||
|
||||
if d.HasChange("resource_path") {
|
||||
updateHealthCheck.ResourcePath = aws.String(d.Get("resource_path").(string))
|
||||
}
|
||||
|
||||
if d.HasChange("search_string") {
|
||||
updateHealthCheck.SearchString = aws.String(d.Get("search_string").(string))
|
||||
}
|
||||
|
||||
_, err := conn.UpdateHealthCheck(updateHealthCheck)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := setTagsR53(conn, d, "healthcheck"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return resourceAwsRoute53HealthCheckRead(d, meta)
|
||||
}
|
||||
|
||||
func resourceAwsRoute53HealthCheckCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
conn := meta.(*AWSClient).r53conn
|
||||
|
||||
healthConfig := &route53.HealthCheckConfig{
|
||||
Type: aws.String(d.Get("type").(string)),
|
||||
FailureThreshold: aws.Long(int64(d.Get("failure_threshold").(int))),
|
||||
RequestInterval: aws.Long(int64(d.Get("request_interval").(int))),
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("fqdn"); ok {
|
||||
healthConfig.FullyQualifiedDomainName = aws.String(v.(string))
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("search_string"); ok {
|
||||
healthConfig.SearchString = aws.String(v.(string))
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("ip_address"); ok {
|
||||
healthConfig.IPAddress = aws.String(v.(string))
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("port"); ok {
|
||||
healthConfig.Port = aws.Long(int64(v.(int)))
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("resource_path"); ok {
|
||||
healthConfig.ResourcePath = aws.String(v.(string))
|
||||
}
|
||||
|
||||
input := &route53.CreateHealthCheckInput{
|
||||
CallerReference: aws.String(time.Now().Format(time.RFC3339Nano)),
|
||||
HealthCheckConfig: healthConfig,
|
||||
}
|
||||
|
||||
resp, err := conn.CreateHealthCheck(input)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
d.SetId(*resp.HealthCheck.ID)
|
||||
|
||||
if err := setTagsR53(conn, d, "healthcheck"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return resourceAwsRoute53HealthCheckRead(d, meta)
|
||||
}
|
||||
|
||||
func resourceAwsRoute53HealthCheckRead(d *schema.ResourceData, meta interface{}) error {
|
||||
conn := meta.(*AWSClient).r53conn
|
||||
|
||||
read, err := conn.GetHealthCheck(&route53.GetHealthCheckInput{HealthCheckID: aws.String(d.Id())})
|
||||
if err != nil {
|
||||
if r53err, ok := err.(awserr.Error); ok && r53err.Code() == "NoSuchHealthCheck" {
|
||||
d.SetId("")
|
||||
return nil
|
||||
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
if read == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
updated := read.HealthCheck.HealthCheckConfig
|
||||
d.Set("type", updated.Type)
|
||||
d.Set("failure_threshold", updated.FailureThreshold)
|
||||
d.Set("request_interval", updated.RequestInterval)
|
||||
d.Set("fqdn", updated.FullyQualifiedDomainName)
|
||||
d.Set("search_string", updated.SearchString)
|
||||
d.Set("ip_address", updated.IPAddress)
|
||||
d.Set("port", updated.Port)
|
||||
d.Set("resource_path", updated.ResourcePath)
|
||||
|
||||
// read the tags
|
||||
req := &route53.ListTagsForResourceInput{
|
||||
ResourceID: aws.String(d.Id()),
|
||||
ResourceType: aws.String("healthcheck"),
|
||||
}
|
||||
|
||||
resp, err := conn.ListTagsForResource(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var tags []*route53.Tag
|
||||
if resp.ResourceTagSet != nil {
|
||||
tags = resp.ResourceTagSet.Tags
|
||||
}
|
||||
|
||||
if err := d.Set("tags", tagsToMapR53(tags)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceAwsRoute53HealthCheckDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
conn := meta.(*AWSClient).r53conn
|
||||
|
||||
log.Printf("[DEBUG] Deleteing Route53 health check: %s", d.Id())
|
||||
_, err := conn.DeleteHealthCheck(&route53.DeleteHealthCheckInput{HealthCheckID: aws.String(d.Id())})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,162 @@
|
|||
package aws
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
|
||||
"github.com/aws/aws-sdk-go/service/route53"
|
||||
)
|
||||
|
||||
func TestAccRoute53HealthCheck_basic(t *testing.T) {
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckRoute53HealthCheckDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testAccRoute53HealthCheckConfig,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckRoute53HealthCheckExists("aws_route53_health_check.foo"),
|
||||
),
|
||||
},
|
||||
resource.TestStep{
|
||||
Config: testAccRoute53HealthCheckConfigUpdate,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckRoute53HealthCheckExists("aws_route53_health_check.foo"),
|
||||
resource.TestCheckResourceAttr(
|
||||
"aws_route53_health_check.foo", "failure_threshold", "5"),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccRoute53HealthCheck_IpConfig(t *testing.T) {
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckRoute53HealthCheckDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testAccRoute53HealthCheckIpConfig,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckRoute53HealthCheckExists("aws_route53_health_check.bar"),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testAccCheckRoute53HealthCheckDestroy(s *terraform.State) error {
|
||||
conn := testAccProvider.Meta().(*AWSClient).r53conn
|
||||
|
||||
for _, rs := range s.RootModule().Resources {
|
||||
if rs.Type != "aws_route53_health_check" {
|
||||
continue
|
||||
}
|
||||
|
||||
lopts := &route53.ListHealthChecksInput{}
|
||||
resp, err := conn.ListHealthChecks(lopts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(resp.HealthChecks) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, check := range resp.HealthChecks {
|
||||
if *check.ID == rs.Primary.ID {
|
||||
return fmt.Errorf("Record still exists: %#v", check)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func testAccCheckRoute53HealthCheckExists(n string) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
conn := testAccProvider.Meta().(*AWSClient).r53conn
|
||||
|
||||
rs, ok := s.RootModule().Resources[n]
|
||||
if !ok {
|
||||
return fmt.Errorf("Not found: %s", n)
|
||||
}
|
||||
|
||||
fmt.Print(rs.Primary.ID)
|
||||
|
||||
if rs.Primary.ID == "" {
|
||||
return fmt.Errorf("No health check ID is set")
|
||||
}
|
||||
|
||||
lopts := &route53.ListHealthChecksInput{}
|
||||
resp, err := conn.ListHealthChecks(lopts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(resp.HealthChecks) == 0 {
|
||||
return fmt.Errorf("Health Check does not exist")
|
||||
}
|
||||
|
||||
for _, check := range resp.HealthChecks {
|
||||
if *check.ID == rs.Primary.ID {
|
||||
return nil
|
||||
}
|
||||
|
||||
}
|
||||
return fmt.Errorf("Health Check does not exist")
|
||||
}
|
||||
}
|
||||
|
||||
func testUpdateHappened(n string) resource.TestCheckFunc {
|
||||
return nil
|
||||
}
|
||||
|
||||
const testAccRoute53HealthCheckConfig = `
|
||||
resource "aws_route53_health_check" "foo" {
|
||||
fqdn = "dev.notexample.com"
|
||||
port = 80
|
||||
type = "HTTP"
|
||||
resource_path = "/"
|
||||
failure_threshold = "2"
|
||||
request_interval = "30"
|
||||
|
||||
tags = {
|
||||
Name = "tf-test-health-check"
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const testAccRoute53HealthCheckConfigUpdate = `
|
||||
resource "aws_route53_health_check" "foo" {
|
||||
fqdn = "dev.notexample.com"
|
||||
port = 80
|
||||
type = "HTTP"
|
||||
resource_path = "/"
|
||||
failure_threshold = "5"
|
||||
request_interval = "30"
|
||||
|
||||
tags = {
|
||||
Name = "tf-test-health-check"
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
const testAccRoute53HealthCheckIpConfig = `
|
||||
resource "aws_route53_health_check" "bar" {
|
||||
ip_address = "1.2.3.4"
|
||||
port = 80
|
||||
type = "HTTP"
|
||||
resource_path = "/"
|
||||
failure_threshold = "2"
|
||||
request_interval = "30"
|
||||
|
||||
tags = {
|
||||
Name = "tf-test-health-check"
|
||||
}
|
||||
}
|
||||
`
|
|
@ -89,6 +89,16 @@ func resourceAwsRoute53Record() *schema.Resource {
|
|||
Set: resourceAwsRoute53AliasRecordHash,
|
||||
},
|
||||
|
||||
"failover": &schema.Schema{ // PRIMARY | SECONDARY
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
|
||||
"health_check_id": &schema.Schema{ // ID of health check
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
|
||||
"records": &schema.Schema{
|
||||
Type: schema.TypeSet,
|
||||
ConflictsWith: []string{"alias"},
|
||||
|
@ -232,10 +242,6 @@ func resourceAwsRoute53RecordRead(d *schema.ResourceData, meta interface{}) erro
|
|||
StartRecordType: aws.String(d.Get("type").(string)),
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("set_identifier"); ok {
|
||||
lopts.StartRecordIdentifier = aws.String(v.(string))
|
||||
}
|
||||
|
||||
resp, err := conn.ListResourceRecordSets(lopts)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -252,7 +258,7 @@ func resourceAwsRoute53RecordRead(d *schema.ResourceData, meta interface{}) erro
|
|||
continue
|
||||
}
|
||||
|
||||
if lopts.StartRecordIdentifier != nil && *record.SetIdentifier != *lopts.StartRecordIdentifier {
|
||||
if record.SetIdentifier != nil && *record.SetIdentifier != d.Get("set_identifier") {
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -262,9 +268,12 @@ func resourceAwsRoute53RecordRead(d *schema.ResourceData, meta interface{}) erro
|
|||
if err != nil {
|
||||
return fmt.Errorf("[DEBUG] Error setting records for: %s, error: %#v", en, err)
|
||||
}
|
||||
|
||||
d.Set("ttl", record.TTL)
|
||||
d.Set("weight", record.Weight)
|
||||
d.Set("set_identifier", record.SetIdentifier)
|
||||
d.Set("failover", record.Failover)
|
||||
d.Set("health_check_id", record.HealthCheckID)
|
||||
|
||||
break
|
||||
}
|
||||
|
@ -390,6 +399,14 @@ func resourceAwsRoute53RecordBuildSet(d *schema.ResourceData, zoneName string) (
|
|||
}
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("failover"); ok {
|
||||
rec.Failover = aws.String(v.(string))
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("health_check_id"); ok {
|
||||
rec.HealthCheckID = aws.String(v.(string))
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("weight"); ok {
|
||||
rec.Weight = aws.Long(int64(v.(int)))
|
||||
}
|
||||
|
|
|
@ -183,7 +183,7 @@ func resourceAwsRoute53ZoneRead(d *schema.ResourceData, meta interface{}) error
|
|||
func resourceAwsRoute53ZoneUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||
conn := meta.(*AWSClient).r53conn
|
||||
|
||||
if err := setTagsR53(conn, d); err != nil {
|
||||
if err := setTagsR53(conn, d, "hostedzone"); err != nil {
|
||||
return err
|
||||
} else {
|
||||
d.SetPartial("tags")
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
|
||||
// setTags is a helper to set the tags for a resource. It expects the
|
||||
// tags field to be named "tags"
|
||||
func setTagsR53(conn *route53.Route53, d *schema.ResourceData) error {
|
||||
func setTagsR53(conn *route53.Route53, d *schema.ResourceData, resourceType string) error {
|
||||
if d.HasChange("tags") {
|
||||
oraw, nraw := d.GetChange("tags")
|
||||
o := oraw.(map[string]interface{})
|
||||
|
@ -25,7 +25,7 @@ func setTagsR53(conn *route53.Route53, d *schema.ResourceData) error {
|
|||
log.Printf("[DEBUG] Changing tags: \n\tadding: %#v\n\tremoving:%#v", create, remove)
|
||||
req := &route53.ChangeTagsForResourceInput{
|
||||
ResourceID: aws.String(d.Id()),
|
||||
ResourceType: aws.String("hostedzone"),
|
||||
ResourceType: aws.String(resourceType),
|
||||
}
|
||||
|
||||
if len(create) > 0 {
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
---
|
||||
layout: "aws"
|
||||
page_title: "AWS: aws_route53_health_check"
|
||||
sidebar_current: "docs-aws-resource-health-check"
|
||||
description: |-
|
||||
Provides a Route53 health check.
|
||||
---
|
||||
# aws\_route53\_health\_check
|
||||
|
||||
Provides a Route53 health check.
|
||||
|
||||
## Example Usage
|
||||
|
||||
```
|
||||
resource "aws_route53_health_check" "foo" {
|
||||
fqdn = "foobar.terraform.com"
|
||||
port = 80
|
||||
type = "HTTP"
|
||||
resource_path = "/"
|
||||
failure_threshold = "5"
|
||||
request_interval = "30"
|
||||
|
||||
tags = {
|
||||
Name = "tf-test-health-check"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Argument Reference
|
||||
|
||||
The following arguments are supported:
|
||||
|
||||
* `fqdn` - (Optional) The fully qualified domain name of the endpoint to be checked.
|
||||
* `ip_address` - (Optional) The IP address of the endpoint to be checked.
|
||||
* `failure_threshold` - (Required) The number of consecutive health checks that an endpoint must pass or fai.
|
||||
* `request_interval` - (Required) The number of seconds between the time that Amazon Route 53 gets a response from your endpoint and the time that it sends the next health-check request.
|
||||
* `resource_path` - (Optional) The path that you want Amazon Route 53 to request when performing health checks.
|
||||
* `search_string` - (Optional) String searched in respoonse body for check to considered healthy.
|
||||
* `tags` - (Optional) A mapping of tags to assign to the health check.
|
||||
|
||||
Exactly one of `fqdn` or `ip_address` must be specified.
|
||||
|
|
@ -94,6 +94,8 @@ The following arguments are supported:
|
|||
* `weight` - (Optional) The weight of weighted record (0-255).
|
||||
* `set_identifier` - (Optional) Unique identifier to differentiate weighted
|
||||
record from one another. Required for each weighted record.
|
||||
* `failover` - (Optional) The routing behavior when associated health check fails. Must be PRIMARY or SECONDARY.
|
||||
* `health_check_id` - (Optional) The health check the record should be associated with.
|
||||
* `alias` - (Optional) An alias block. Conflicts with `ttl` & `records`.
|
||||
Alias record documented below.
|
||||
|
||||
|
|
Loading…
Reference in New Issue