github.com/anuaimi/terraform@v0.6.4-0.20150904235404-2bf9aec61da8/builtin/providers/aws/resource_aws_route53_record_test.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  	"testing"
     7  
     8  	"github.com/hashicorp/terraform/helper/resource"
     9  	"github.com/hashicorp/terraform/terraform"
    10  
    11  	"github.com/aws/aws-sdk-go/aws"
    12  	"github.com/aws/aws-sdk-go/service/route53"
    13  )
    14  
    15  func TestCleanRecordName(t *testing.T) {
    16  	cases := []struct {
    17  		Input, Output string
    18  	}{
    19  		{"www.nonexample.com", "www.nonexample.com"},
    20  		{"\\052.nonexample.com", "*.nonexample.com"},
    21  		{"nonexample.com", "nonexample.com"},
    22  	}
    23  
    24  	for _, tc := range cases {
    25  		actual := cleanRecordName(tc.Input)
    26  		if actual != tc.Output {
    27  			t.Fatalf("input: %s\noutput: %s", tc.Input, actual)
    28  		}
    29  	}
    30  }
    31  
    32  func TestExpandRecordName(t *testing.T) {
    33  	cases := []struct {
    34  		Input, Output string
    35  	}{
    36  		{"www", "www.nonexample.com"},
    37  		{"dev.www", "dev.www.nonexample.com"},
    38  		{"*", "*.nonexample.com"},
    39  		{"nonexample.com", "nonexample.com"},
    40  		{"test.nonexample.com", "test.nonexample.com"},
    41  		{"test.nonexample.com.", "test.nonexample.com"},
    42  	}
    43  
    44  	zone_name := "nonexample.com"
    45  	for _, tc := range cases {
    46  		actual := expandRecordName(tc.Input, zone_name)
    47  		if actual != tc.Output {
    48  			t.Fatalf("input: %s\noutput: %s", tc.Input, actual)
    49  		}
    50  	}
    51  }
    52  
    53  func TestAccAWSRoute53Record_basic(t *testing.T) {
    54  	resource.Test(t, resource.TestCase{
    55  		PreCheck:     func() { testAccPreCheck(t) },
    56  		Providers:    testAccProviders,
    57  		CheckDestroy: testAccCheckRoute53RecordDestroy,
    58  		Steps: []resource.TestStep{
    59  			resource.TestStep{
    60  				Config: testAccRoute53RecordConfig,
    61  				Check: resource.ComposeTestCheckFunc(
    62  					testAccCheckRoute53RecordExists("aws_route53_record.default"),
    63  				),
    64  			},
    65  		},
    66  	})
    67  }
    68  
    69  func TestAccAWSRoute53Record_txtSupport(t *testing.T) {
    70  	resource.Test(t, resource.TestCase{
    71  		PreCheck:     func() { testAccPreCheck(t) },
    72  		Providers:    testAccProviders,
    73  		CheckDestroy: testAccCheckRoute53RecordDestroy,
    74  		Steps: []resource.TestStep{
    75  			resource.TestStep{
    76  				Config: testAccRoute53RecordConfigTXT,
    77  				Check: resource.ComposeTestCheckFunc(
    78  					testAccCheckRoute53RecordExists("aws_route53_record.default"),
    79  				),
    80  			},
    81  		},
    82  	})
    83  }
    84  
    85  func TestAccAWSRoute53Record_generatesSuffix(t *testing.T) {
    86  	resource.Test(t, resource.TestCase{
    87  		PreCheck:     func() { testAccPreCheck(t) },
    88  		Providers:    testAccProviders,
    89  		CheckDestroy: testAccCheckRoute53RecordDestroy,
    90  		Steps: []resource.TestStep{
    91  			resource.TestStep{
    92  				Config: testAccRoute53RecordConfigSuffix,
    93  				Check: resource.ComposeTestCheckFunc(
    94  					testAccCheckRoute53RecordExists("aws_route53_record.default"),
    95  				),
    96  			},
    97  		},
    98  	})
    99  }
   100  
   101  func TestAccAWSRoute53Record_wildcard(t *testing.T) {
   102  	resource.Test(t, resource.TestCase{
   103  		PreCheck:     func() { testAccPreCheck(t) },
   104  		Providers:    testAccProviders,
   105  		CheckDestroy: testAccCheckRoute53RecordDestroy,
   106  		Steps: []resource.TestStep{
   107  			resource.TestStep{
   108  				Config: testAccRoute53WildCardRecordConfig,
   109  				Check: resource.ComposeTestCheckFunc(
   110  					testAccCheckRoute53RecordExists("aws_route53_record.wildcard"),
   111  				),
   112  			},
   113  
   114  			// Cause a change, which will trigger a refresh
   115  			resource.TestStep{
   116  				Config: testAccRoute53WildCardRecordConfigUpdate,
   117  				Check: resource.ComposeTestCheckFunc(
   118  					testAccCheckRoute53RecordExists("aws_route53_record.wildcard"),
   119  				),
   120  			},
   121  		},
   122  	})
   123  }
   124  
   125  func TestAccAWSRoute53Record_weighted(t *testing.T) {
   126  	resource.Test(t, resource.TestCase{
   127  		PreCheck:     func() { testAccPreCheck(t) },
   128  		Providers:    testAccProviders,
   129  		CheckDestroy: testAccCheckRoute53RecordDestroy,
   130  		Steps: []resource.TestStep{
   131  			resource.TestStep{
   132  				Config: testAccRoute53WeightedCNAMERecord,
   133  				Check: resource.ComposeTestCheckFunc(
   134  					testAccCheckRoute53RecordExists("aws_route53_record.www-dev"),
   135  					testAccCheckRoute53RecordExists("aws_route53_record.www-live"),
   136  				),
   137  			},
   138  		},
   139  	})
   140  }
   141  
   142  func TestAccAWSRoute53Record_alias(t *testing.T) {
   143  	resource.Test(t, resource.TestCase{
   144  		PreCheck:     func() { testAccPreCheck(t) },
   145  		Providers:    testAccProviders,
   146  		CheckDestroy: testAccCheckRoute53RecordDestroy,
   147  		Steps: []resource.TestStep{
   148  			resource.TestStep{
   149  				Config: testAccRoute53ElbAliasRecord,
   150  				Check: resource.ComposeTestCheckFunc(
   151  					testAccCheckRoute53RecordExists("aws_route53_record.alias"),
   152  				),
   153  			},
   154  		},
   155  	})
   156  }
   157  
   158  func TestAccAWSRoute53Record_s3_alias(t *testing.T) {
   159  	resource.Test(t, resource.TestCase{
   160  		PreCheck:     func() { testAccPreCheck(t) },
   161  		Providers:    testAccProviders,
   162  		CheckDestroy: testAccCheckRoute53RecordDestroy,
   163  		Steps: []resource.TestStep{
   164  			resource.TestStep{
   165  				Config: testAccRoute53S3AliasRecord,
   166  				Check: resource.ComposeTestCheckFunc(
   167  					testAccCheckRoute53RecordExists("aws_route53_record.alias"),
   168  				),
   169  			},
   170  		},
   171  	})
   172  }
   173  
   174  func TestAccAWSRoute53Record_weighted_alias(t *testing.T) {
   175  	resource.Test(t, resource.TestCase{
   176  		PreCheck:     func() { testAccPreCheck(t) },
   177  		Providers:    testAccProviders,
   178  		CheckDestroy: testAccCheckRoute53RecordDestroy,
   179  		Steps: []resource.TestStep{
   180  			resource.TestStep{
   181  				Config: testAccRoute53WeightedElbAliasRecord,
   182  				Check: resource.ComposeTestCheckFunc(
   183  					testAccCheckRoute53RecordExists("aws_route53_record.elb_weighted_alias_live"),
   184  					testAccCheckRoute53RecordExists("aws_route53_record.elb_weighted_alias_dev"),
   185  				),
   186  			},
   187  
   188  			resource.TestStep{
   189  				Config: testAccRoute53WeightedR53AliasRecord,
   190  				Check: resource.ComposeTestCheckFunc(
   191  					testAccCheckRoute53RecordExists("aws_route53_record.green_origin"),
   192  					testAccCheckRoute53RecordExists("aws_route53_record.r53_weighted_alias_live"),
   193  					testAccCheckRoute53RecordExists("aws_route53_record.blue_origin"),
   194  					testAccCheckRoute53RecordExists("aws_route53_record.r53_weighted_alias_dev"),
   195  				),
   196  			},
   197  		},
   198  	})
   199  }
   200  
   201  func TestAccAWSRoute53Record_TypeChange(t *testing.T) {
   202  	resource.Test(t, resource.TestCase{
   203  		PreCheck:     func() { testAccPreCheck(t) },
   204  		Providers:    testAccProviders,
   205  		CheckDestroy: testAccCheckRoute53RecordDestroy,
   206  		Steps: []resource.TestStep{
   207  			resource.TestStep{
   208  				Config: testAccRoute53RecordTypeChangePre,
   209  				Check: resource.ComposeTestCheckFunc(
   210  					testAccCheckRoute53RecordExists("aws_route53_record.sample"),
   211  				),
   212  			},
   213  
   214  			// Cause a change, which will trigger a refresh
   215  			resource.TestStep{
   216  				Config: testAccRoute53RecordTypeChangePost,
   217  				Check: resource.ComposeTestCheckFunc(
   218  					testAccCheckRoute53RecordExists("aws_route53_record.sample"),
   219  				),
   220  			},
   221  		},
   222  	})
   223  }
   224  
   225  func testAccCheckRoute53RecordDestroy(s *terraform.State) error {
   226  	conn := testAccProvider.Meta().(*AWSClient).r53conn
   227  	for _, rs := range s.RootModule().Resources {
   228  		if rs.Type != "aws_route53_record" {
   229  			continue
   230  		}
   231  
   232  		parts := strings.Split(rs.Primary.ID, "_")
   233  		zone := parts[0]
   234  		name := parts[1]
   235  		rType := parts[2]
   236  
   237  		lopts := &route53.ListResourceRecordSetsInput{
   238  			HostedZoneId:    aws.String(cleanZoneID(zone)),
   239  			StartRecordName: aws.String(name),
   240  			StartRecordType: aws.String(rType),
   241  		}
   242  
   243  		resp, err := conn.ListResourceRecordSets(lopts)
   244  		if err != nil {
   245  			return err
   246  		}
   247  		if len(resp.ResourceRecordSets) == 0 {
   248  			return nil
   249  		}
   250  		rec := resp.ResourceRecordSets[0]
   251  		if FQDN(*rec.Name) == FQDN(name) && *rec.Type == rType {
   252  			return fmt.Errorf("Record still exists: %#v", rec)
   253  		}
   254  	}
   255  	return nil
   256  }
   257  
   258  func testAccCheckRoute53RecordExists(n string) resource.TestCheckFunc {
   259  	return func(s *terraform.State) error {
   260  		conn := testAccProvider.Meta().(*AWSClient).r53conn
   261  		rs, ok := s.RootModule().Resources[n]
   262  		if !ok {
   263  			return fmt.Errorf("Not found: %s", n)
   264  		}
   265  
   266  		if rs.Primary.ID == "" {
   267  			return fmt.Errorf("No hosted zone ID is set")
   268  		}
   269  
   270  		parts := strings.Split(rs.Primary.ID, "_")
   271  		zone := parts[0]
   272  		name := parts[1]
   273  		rType := parts[2]
   274  
   275  		en := expandRecordName(name, "notexample.com")
   276  
   277  		lopts := &route53.ListResourceRecordSetsInput{
   278  			HostedZoneId:    aws.String(cleanZoneID(zone)),
   279  			StartRecordName: aws.String(en),
   280  			StartRecordType: aws.String(rType),
   281  		}
   282  
   283  		resp, err := conn.ListResourceRecordSets(lopts)
   284  		if err != nil {
   285  			return err
   286  		}
   287  		if len(resp.ResourceRecordSets) == 0 {
   288  			return fmt.Errorf("Record does not exist")
   289  		}
   290  		// rec := resp.ResourceRecordSets[0]
   291  		for _, rec := range resp.ResourceRecordSets {
   292  			recName := cleanRecordName(*rec.Name)
   293  			if FQDN(recName) == FQDN(en) && *rec.Type == rType {
   294  				return nil
   295  			}
   296  		}
   297  		return fmt.Errorf("Record does not exist: %#v", rs.Primary.ID)
   298  	}
   299  }
   300  
   301  const testAccRoute53RecordConfig = `
   302  resource "aws_route53_zone" "main" {
   303  	name = "notexample.com"
   304  }
   305  
   306  resource "aws_route53_record" "default" {
   307  	zone_id = "${aws_route53_zone.main.zone_id}"
   308  	name = "www.notexample.com"
   309  	type = "A"
   310  	ttl = "30"
   311  	records = ["127.0.0.1", "127.0.0.27"]
   312  }
   313  `
   314  
   315  const testAccRoute53RecordConfigSuffix = `
   316  resource "aws_route53_zone" "main" {
   317  	name = "notexample.com"
   318  }
   319  
   320  resource "aws_route53_record" "default" {
   321  	zone_id = "${aws_route53_zone.main.zone_id}"
   322  	name = "subdomain"
   323  	type = "A"
   324  	ttl = "30"
   325  	records = ["127.0.0.1", "127.0.0.27"]
   326  }
   327  `
   328  
   329  const testAccRoute53WildCardRecordConfig = `
   330  resource "aws_route53_zone" "main" {
   331      name = "notexample.com"
   332  }
   333  
   334  resource "aws_route53_record" "default" {
   335  	zone_id = "${aws_route53_zone.main.zone_id}"
   336  	name = "subdomain"
   337  	type = "A"
   338  	ttl = "30"
   339  	records = ["127.0.0.1", "127.0.0.27"]
   340  }
   341  
   342  resource "aws_route53_record" "wildcard" {
   343      zone_id = "${aws_route53_zone.main.zone_id}"
   344      name = "*.notexample.com"
   345      type = "A"
   346      ttl = "30"
   347      records = ["127.0.0.1"]
   348  }
   349  `
   350  
   351  const testAccRoute53WildCardRecordConfigUpdate = `
   352  resource "aws_route53_zone" "main" {
   353      name = "notexample.com"
   354  }
   355  
   356  resource "aws_route53_record" "default" {
   357  	zone_id = "${aws_route53_zone.main.zone_id}"
   358  	name = "subdomain"
   359  	type = "A"
   360  	ttl = "30"
   361  	records = ["127.0.0.1", "127.0.0.27"]
   362  }
   363  
   364  resource "aws_route53_record" "wildcard" {
   365      zone_id = "${aws_route53_zone.main.zone_id}"
   366      name = "*.notexample.com"
   367      type = "A"
   368      ttl = "60"
   369      records = ["127.0.0.1"]
   370  }
   371  `
   372  const testAccRoute53RecordConfigTXT = `
   373  resource "aws_route53_zone" "main" {
   374  	name = "notexample.com"
   375  }
   376  
   377  resource "aws_route53_record" "default" {
   378  	zone_id = "/hostedzone/${aws_route53_zone.main.zone_id}"
   379  	name = "subdomain"
   380  	type = "TXT"
   381  	ttl = "30"
   382  	records = ["lalalala"]
   383  }
   384  `
   385  
   386  const testAccRoute53WeightedCNAMERecord = `
   387  resource "aws_route53_zone" "main" {
   388  	name = "notexample.com"
   389  }
   390  
   391  resource "aws_route53_record" "www-dev" {
   392    zone_id = "${aws_route53_zone.main.zone_id}"
   393    name = "www"
   394    type = "CNAME"
   395    ttl = "5"
   396    weight = 10
   397    set_identifier = "dev"
   398    records = ["dev.notexample.com"]
   399  }
   400  
   401  resource "aws_route53_record" "www-live" {
   402    zone_id = "${aws_route53_zone.main.zone_id}"
   403    name = "www"
   404    type = "CNAME"
   405    ttl = "5"
   406    weight = 90
   407    set_identifier = "live"
   408    records = ["dev.notexample.com"]
   409  }
   410  `
   411  
   412  const testAccRoute53ElbAliasRecord = `
   413  resource "aws_route53_zone" "main" {
   414    name = "notexample.com"
   415  }
   416  
   417  resource "aws_route53_record" "alias" {
   418    zone_id = "${aws_route53_zone.main.zone_id}"
   419    name = "www"
   420    type = "A"
   421  
   422    alias {
   423    	zone_id = "${aws_elb.main.zone_id}"
   424    	name = "${aws_elb.main.dns_name}"
   425    	evaluate_target_health = true
   426    }
   427  }
   428  
   429  resource "aws_elb" "main" {
   430    name = "foobar-terraform-elb"
   431    availability_zones = ["us-west-2a"]
   432  
   433    listener {
   434      instance_port = 80
   435      instance_protocol = "http"
   436      lb_port = 80
   437      lb_protocol = "http"
   438    }
   439  }
   440  `
   441  
   442  const testAccRoute53AliasRecord = `
   443  resource "aws_route53_zone" "main" {
   444    name = "notexample.com"
   445  }
   446  
   447  resource "aws_route53_record" "origin" {
   448    zone_id = "${aws_route53_zone.main.zone_id}"
   449    name = "origin"
   450    type = "A"
   451    ttl = 5
   452    records = ["127.0.0.1"]
   453  }
   454  
   455  resource "aws_route53_record" "alias" {
   456    zone_id = "${aws_route53_zone.main.zone_id}"
   457    name = "www"
   458    type = "A"
   459  
   460    alias {
   461      zone_id = "${aws_route53_zone.main.zone_id}"
   462      name = "${aws_route53_record.origin.name}.${aws_route53_zone.main.name}"
   463      evaluate_target_health = true
   464    }
   465  }
   466  `
   467  
   468  const testAccRoute53S3AliasRecord = `
   469  resource "aws_route53_zone" "main" {
   470    name = "notexample.com"
   471  }
   472  
   473  resource "aws_s3_bucket" "website" {
   474    bucket = "website.notexample.com"
   475  	acl = "public-read"
   476  	website {
   477  		index_document = "index.html"
   478  	}
   479  }
   480  
   481  resource "aws_route53_record" "alias" {
   482    zone_id = "${aws_route53_zone.main.zone_id}"
   483    name = "www"
   484    type = "A"
   485  
   486    alias {
   487      zone_id = "${aws_s3_bucket.website.hosted_zone_id}"
   488      name = "${aws_s3_bucket.website.website_domain}"
   489      evaluate_target_health = true
   490    }
   491  }
   492  `
   493  
   494  const testAccRoute53WeightedElbAliasRecord = `
   495  resource "aws_route53_zone" "main" {
   496    name = "notexample.com"
   497  }
   498  
   499  resource "aws_elb" "live" {
   500    name = "foobar-terraform-elb-live"
   501    availability_zones = ["us-west-2a"]
   502  
   503    listener {
   504      instance_port = 80
   505      instance_protocol = "http"
   506      lb_port = 80
   507      lb_protocol = "http"
   508    }
   509  }
   510  
   511  resource "aws_route53_record" "elb_weighted_alias_live" {
   512    zone_id = "${aws_route53_zone.main.zone_id}"
   513    name = "www"
   514    type = "A"
   515  
   516    weight = 90
   517    set_identifier = "live"
   518  
   519    alias {
   520      zone_id = "${aws_elb.live.zone_id}"
   521      name = "${aws_elb.live.dns_name}"
   522      evaluate_target_health = true
   523    }
   524  }
   525  
   526  resource "aws_elb" "dev" {
   527    name = "foobar-terraform-elb-dev"
   528    availability_zones = ["us-west-2a"]
   529  
   530    listener {
   531      instance_port = 80
   532      instance_protocol = "http"
   533      lb_port = 80
   534      lb_protocol = "http"
   535    }
   536  }
   537  
   538  resource "aws_route53_record" "elb_weighted_alias_dev" {
   539    zone_id = "${aws_route53_zone.main.zone_id}"
   540    name = "www"
   541    type = "A"
   542  
   543    weight = 10
   544    set_identifier = "dev"
   545  
   546    alias {
   547      zone_id = "${aws_elb.dev.zone_id}"
   548      name = "${aws_elb.dev.dns_name}"
   549      evaluate_target_health = true
   550    }
   551  }
   552  `
   553  
   554  const testAccRoute53WeightedR53AliasRecord = `
   555  resource "aws_route53_zone" "main" {
   556    name = "notexample.com"
   557  }
   558  
   559  resource "aws_route53_record" "blue_origin" {
   560    zone_id = "${aws_route53_zone.main.zone_id}"
   561    name = "blue-origin"
   562    type = "CNAME"
   563    ttl = 5
   564    records = ["v1.terraform.io"]
   565  }
   566  
   567  resource "aws_route53_record" "r53_weighted_alias_live" {
   568    zone_id = "${aws_route53_zone.main.zone_id}"
   569    name = "www"
   570    type = "CNAME"
   571  
   572    weight = 90
   573    set_identifier = "blue"
   574  
   575    alias {
   576      zone_id = "${aws_route53_zone.main.zone_id}"
   577      name = "${aws_route53_record.blue_origin.name}.${aws_route53_zone.main.name}"
   578      evaluate_target_health = false
   579    }
   580  }
   581  
   582  resource "aws_route53_record" "green_origin" {
   583    zone_id = "${aws_route53_zone.main.zone_id}"
   584    name = "green-origin"
   585    type = "CNAME"
   586    ttl = 5
   587    records = ["v2.terraform.io"]
   588  }
   589  
   590  resource "aws_route53_record" "r53_weighted_alias_dev" {
   591    zone_id = "${aws_route53_zone.main.zone_id}"
   592    name = "www"
   593    type = "CNAME"
   594  
   595    weight = 10
   596    set_identifier = "green"
   597  
   598    alias {
   599      zone_id = "${aws_route53_zone.main.zone_id}"
   600      name = "${aws_route53_record.green_origin.name}.${aws_route53_zone.main.name}"
   601      evaluate_target_health = false
   602    }
   603  }
   604  `
   605  
   606  const testAccRoute53RecordTypeChangePre = `
   607  resource "aws_route53_zone" "main" {
   608  	name = "notexample.com"
   609  }
   610  
   611  resource "aws_route53_record" "sample" {
   612  	zone_id = "${aws_route53_zone.main.zone_id}"
   613    name = "sample"
   614    type = "CNAME"
   615    ttl = "30"
   616    records = ["www.terraform.io"]
   617  }
   618  `
   619  
   620  const testAccRoute53RecordTypeChangePost = `
   621  resource "aws_route53_zone" "main" {
   622  	name = "notexample.com"
   623  }
   624  
   625  resource "aws_route53_record" "sample" {
   626    zone_id = "${aws_route53_zone.main.zone_id}"
   627    name = "sample"
   628    type = "A"
   629    ttl = "30"
   630    records = ["127.0.0.1", "8.8.8.8"]
   631  }
   632  `