diff --git a/aws/resource_aws_service_discovery_service.go b/aws/resource_aws_service_discovery_service.go index 167b51ab744..38f07bb7377 100644 --- a/aws/resource_aws_service_discovery_service.go +++ b/aws/resource_aws_service_discovery_service.go @@ -52,14 +52,29 @@ func resourceAwsServiceDiscoveryService() *schema.Resource { Required: true, }, "type": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validateServiceDiscoveryServiceDnsRecordsType, + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateStringIn( + servicediscovery.RecordTypeSrv, + servicediscovery.RecordTypeA, + servicediscovery.RecordTypeAaaa, + servicediscovery.RecordTypeCname, + ), }, }, }, }, + "routing_policy": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Default: servicediscovery.RoutingPolicyMultivalue, + ValidateFunc: validateStringIn( + servicediscovery.RoutingPolicyMultivalue, + servicediscovery.RoutingPolicyWeighted, + ), + }, }, }, }, @@ -78,10 +93,14 @@ func resourceAwsServiceDiscoveryService() *schema.Resource { Optional: true, }, "type": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - ValidateFunc: validateServiceDiscoveryServiceHealthCheckConfigType, + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: validateStringIn( + servicediscovery.HealthCheckTypeHttp, + servicediscovery.HealthCheckTypeHttps, + servicediscovery.HealthCheckTypeTcp, + ), }, }, }, @@ -220,6 +239,9 @@ func expandServiceDiscoveryDnsConfig(configured map[string]interface{}) *service drs[i] = dr } result.DnsRecords = drs + if v, ok := configured["routing_policy"]; ok && v != "" { + result.RoutingPolicy = aws.String(v.(string)) + } return result } @@ -228,6 +250,7 @@ func flattenServiceDiscoveryDnsConfig(config *servicediscovery.DnsConfig) []map[ result := map[string]interface{}{} result["namespace_id"] = *config.NamespaceId + result["routing_policy"] = *config.RoutingPolicy drs := make([]map[string]interface{}, 0) for _, v := range config.DnsRecords { dr := map[string]interface{}{} diff --git a/aws/resource_aws_service_discovery_service_migrate.go b/aws/resource_aws_service_discovery_service_migrate.go new file mode 100644 index 00000000000..d0fd571f7c5 --- /dev/null +++ b/aws/resource_aws_service_discovery_service_migrate.go @@ -0,0 +1,36 @@ +package aws + +import ( + "fmt" + "log" + + "github.com/aws/aws-sdk-go/service/servicediscovery" + "github.com/hashicorp/terraform/terraform" +) + +func resourceAwsServiceDiscoveryServiceMigrateState( + v int, is *terraform.InstanceState, meta interface{}) (*terraform.InstanceState, error) { + switch v { + case 0: + log.Println("[INFO] Found AWS ServiceDiscovery Service State v0; migrating to v1") + return migrateServiceDiscoveryServiceStateV0toV1(is) + default: + return is, fmt.Errorf("Unexpected schema version: %d", v) + } +} + +func migrateServiceDiscoveryServiceStateV0toV1(is *terraform.InstanceState) (*terraform.InstanceState, error) { + if is.Empty() { + log.Println("[DEBUG] Empty InstanceState; nothing to migrate.") + return is, nil + } + + log.Printf("[DEBUG] Attributes before migration: %#v", is.Attributes) + + if v, ok := is.Attributes["dns_config.0.routing_policy"]; !ok && v == "" { + is.Attributes["dns_config.0.routing_policy"] = servicediscovery.RoutingPolicyMultivalue + } + + log.Printf("[DEBUG] Attributes after migration: %#v", is.Attributes) + return is, nil +} diff --git a/aws/resource_aws_service_discovery_service_migrate_test.go b/aws/resource_aws_service_discovery_service_migrate_test.go new file mode 100644 index 00000000000..8a36485b451 --- /dev/null +++ b/aws/resource_aws_service_discovery_service_migrate_test.go @@ -0,0 +1,61 @@ +package aws + +import ( + "testing" + + "github.com/hashicorp/terraform/terraform" +) + +func TestAwsServiceDiscoveryServiceMigrateState(t *testing.T) { + cases := map[string]struct { + StateVersion int + ID string + Attributes map[string]string + Expected map[string]string + Meta interface{} + }{ + "v0_1": { + StateVersion: 0, + ID: "tf-testing-file", + Attributes: map[string]string{ + "name": "test-name", + "dns_config.#": "1", + "dns_config.0.namespace_id": "test-namespace", + "dns_config.0.dns_records.#": "1", + "dns_config.0.dns_records.0.ttl": "10", + "dns_config.0.dns_records.0.type": "A", + "arn": "arn", + }, + Expected: map[string]string{ + "name": "test-name", + "dns_config.#": "1", + "dns_config.0.namespace_id": "test-namespace", + "dns_config.0.routing_policy": "MULTIVALUE", + "dns_config.0.dns_records.#": "1", + "dns_config.0.dns_records.0.ttl": "10", + "dns_config.0.dns_records.0.type": "A", + "arn": "arn", + }, + }, + } + + for tn, tc := range cases { + is := &terraform.InstanceState{ + ID: tc.ID, + Attributes: tc.Attributes, + } + is, err := resourceAwsServiceDiscoveryServiceMigrateState(tc.StateVersion, is, tc.Meta) + + if err != nil { + t.Fatalf("bad: %s, err: %#v", tn, err) + } + + for k, v := range tc.Expected { + if is.Attributes[k] != v { + t.Fatalf( + "bad: %s\n\n expected: %#v -> %#v\n got: %#v -> %#v\n in: %#v", + tn, k, v, k, is.Attributes[k], is.Attributes) + } + } + } +} diff --git a/aws/resource_aws_service_discovery_service_test.go b/aws/resource_aws_service_discovery_service_test.go index fbb72e54dcd..17f4f8a1bb1 100644 --- a/aws/resource_aws_service_discovery_service_test.go +++ b/aws/resource_aws_service_discovery_service_test.go @@ -25,6 +25,7 @@ func TestAccAwsServiceDiscoveryService_private(t *testing.T) { resource.TestCheckResourceAttr("aws_service_discovery_service.test", "dns_config.0.dns_records.#", "1"), resource.TestCheckResourceAttr("aws_service_discovery_service.test", "dns_config.0.dns_records.0.type", "A"), resource.TestCheckResourceAttr("aws_service_discovery_service.test", "dns_config.0.dns_records.0.ttl", "5"), + resource.TestCheckResourceAttr("aws_service_discovery_service.test", "dns_config.0.routing_policy", "MULTIVALUE"), resource.TestCheckResourceAttrSet("aws_service_discovery_service.test", "arn"), ), }, @@ -58,6 +59,7 @@ func TestAccAwsServiceDiscoveryService_public(t *testing.T) { resource.TestCheckResourceAttr("aws_service_discovery_service.test", "health_check_config.0.type", "HTTP"), resource.TestCheckResourceAttr("aws_service_discovery_service.test", "health_check_config.0.failure_threshold", "5"), resource.TestCheckResourceAttr("aws_service_discovery_service.test", "health_check_config.0.resource_path", "/path"), + resource.TestCheckResourceAttr("aws_service_discovery_service.test", "dns_config.0.routing_policy", "WEIGHTED"), resource.TestCheckResourceAttrSet("aws_service_discovery_service.test", "arn"), ), }, @@ -190,6 +192,7 @@ resource "aws_service_discovery_service" "test" { ttl = 5 type = "AAAA" } + routing_policy = "MULTIVALUE" } } `, rName, rName) @@ -210,6 +213,7 @@ resource "aws_service_discovery_service" "test" { ttl = 5 type = "A" } + routing_policy = "WEIGHTED" } health_check_config { failure_threshold = %d diff --git a/aws/validators.go b/aws/validators.go index 7ca6ff05e59..cc0d1f40c8a 100644 --- a/aws/validators.go +++ b/aws/validators.go @@ -2146,30 +2146,6 @@ func validateAwsElastiCacheReplicationGroupAuthToken(v interface{}, k string) (w return } -func validateServiceDiscoveryServiceDnsRecordsType(v interface{}, k string) (ws []string, errors []error) { - value := v.(string) - validType := []string{"SRV", "A", "AAAA"} - for _, str := range validType { - if value == str { - return - } - } - errors = append(errors, fmt.Errorf("expected %s to be one of %v, got %s", k, validType, value)) - return -} - -func validateServiceDiscoveryServiceHealthCheckConfigType(v interface{}, k string) (ws []string, errors []error) { - value := v.(string) - validType := []string{"HTTP", "HTTPS", "TCP"} - for _, str := range validType { - if value == str { - return - } - } - errors = append(errors, fmt.Errorf("expected %s to be one of %v, got %s", k, validType, value)) - return -} - func validateGameliftOperatingSystem(v interface{}, k string) (ws []string, errors []error) { value := v.(string) operatingSystems := map[string]bool{ diff --git a/aws/validators_test.go b/aws/validators_test.go index 5cf9e95d844..f34b27276a4 100644 --- a/aws/validators_test.go +++ b/aws/validators_test.go @@ -2949,56 +2949,6 @@ func TestValidateCognitoUserGroupName(t *testing.T) { } } -func TestValidateServiceDiscoveryServiceDnsRecordsType(t *testing.T) { - validTypes := []string{ - "SRV", - "A", - "AAAA", - } - for _, v := range validTypes { - _, errors := validateServiceDiscoveryServiceDnsRecordsType(v, "") - if len(errors) != 0 { - t.Fatalf("%q should be a valid Service Discovery DNS Records Type: %q", v, errors) - } - } - - invalidTypes := []string{ - "hoge", - "srv", - } - for _, v := range invalidTypes { - _, errors := validateServiceDiscoveryServiceDnsRecordsType(v, "") - if len(errors) == 0 { - t.Fatalf("%q should be an invalid Service Discovery DNS Records Type", v) - } - } -} - -func TestValidateServiceDiscoveryServiceHealthCheckConfigType(t *testing.T) { - validTypes := []string{ - "HTTP", - "HTTPS", - "TCP", - } - for _, v := range validTypes { - _, errors := validateServiceDiscoveryServiceHealthCheckConfigType(v, "") - if len(errors) != 0 { - t.Fatalf("%q should be a valid Service Discovery Health Check Config Type: %q", v, errors) - } - } - - invalidTypes := []string{ - "hoge", - "tcp", - } - for _, v := range invalidTypes { - _, errors := validateServiceDiscoveryServiceHealthCheckConfigType(v, "") - if len(errors) == 0 { - t.Fatalf("%q should be an invalid Service Discovery Health Check Config Type", v) - } - } -} - func TestValidateCognitoUserPoolId(t *testing.T) { validValues := []string{ "eu-west-1_Foo123", diff --git a/website/docs/r/service_discovery_service.html.markdown b/website/docs/r/service_discovery_service.html.markdown index 586c3b301da..cb3768d9603 100644 --- a/website/docs/r/service_discovery_service.html.markdown +++ b/website/docs/r/service_discovery_service.html.markdown @@ -31,6 +31,7 @@ resource "aws_service_discovery_service" "example" { ttl = 10 type = "A" } + routing_policy = "MULTIVALUE" } } ``` @@ -73,13 +74,14 @@ The following arguments are supported: * `namespace_id` - (Required, ForceNew) The ID of the namespace to use for DNS configuration. * `dns_records` - (Required) An array that contains one DnsRecord object for each resource record set. +* `routing_policy` - (Optional) The routing policy that you want to apply to all records that Route 53 creates when you register an instance and specify the service. Valid Values: MULTIVALUE, WEIGHTED #### dns_records The following arguments are supported: * `ttl` - (Required) The amount of time, in seconds, that you want DNS resolvers to cache the settings for this resource record set. -* `type` - (Required, ForceNew) The type of the resource, which indicates the value that Amazon Route 53 returns in response to DNS queries. Valid Values: A, AAAA, SRV +* `type` - (Required, ForceNew) The type of the resource, which indicates the value that Amazon Route 53 returns in response to DNS queries. Valid Values: A, AAAA, SRV, CNAME ### health_check_config