From eb0a513aa42f1e8b40d8969fcb7ce25f2abe7f83 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Sat, 7 Mar 2020 18:45:10 -0500 Subject: [PATCH 01/21] r/aws_appmesh_virtual_node: Add listener.tls attribute. Acceptance test output: $ make testacc TEST=./aws TESTARGS='-run=TestAccAWSAppmesh/VirtualNode' ==> Checking that code complies with gofmt requirements... GO111MODULE=off TF_ACC=1 go test ./aws -v -count 1 -parallel 20 -run=TestAccAWSAppmesh/VirtualNode -timeout 120m === RUN TestAccAWSAppmesh === RUN TestAccAWSAppmesh/VirtualNode === RUN TestAccAWSAppmesh/VirtualNode/cloudMapServiceDiscovery === RUN TestAccAWSAppmesh/VirtualNode/listenerHealthChecks === RUN TestAccAWSAppmesh/VirtualNode/logging === RUN TestAccAWSAppmesh/VirtualNode/basic --- PASS: TestAccAWSAppmesh (221.62s) --- PASS: TestAccAWSAppmesh/VirtualNode (221.62s) --- PASS: TestAccAWSAppmesh/VirtualNode/cloudMapServiceDiscovery (114.06s) --- PASS: TestAccAWSAppmesh/VirtualNode/listenerHealthChecks (40.76s) --- PASS: TestAccAWSAppmesh/VirtualNode/logging (41.45s) --- PASS: TestAccAWSAppmesh/VirtualNode/basic (25.35s) PASS ok github.com/terraform-providers/terraform-provider-aws/aws 221.667s --- aws/resource_aws_appmesh_virtual_node.go | 108 ++++++++ aws/resource_aws_appmesh_virtual_node_test.go | 2 + aws/structure.go | 262 +++++++++++++----- .../docs/r/appmesh_virtual_node.html.markdown | 34 +++ 4 files changed, 342 insertions(+), 64 deletions(-) diff --git a/aws/resource_aws_appmesh_virtual_node.go b/aws/resource_aws_appmesh_virtual_node.go index 7f1ba854a89..f7e19bc3eb1 100644 --- a/aws/resource_aws_appmesh_virtual_node.go +++ b/aws/resource_aws_appmesh_virtual_node.go @@ -171,6 +171,114 @@ func resourceAwsAppmeshVirtualNode() *schema.Resource { }, }, }, + + "tls": { + Type: schema.TypeList, + Optional: true, + MinItems: 0, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "certificate": { + Type: schema.TypeList, + Required: true, + MinItems: 1, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "acm": { + Type: schema.TypeList, + Optional: true, + MinItems: 0, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "certificate_arn": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validateArn, + }, + }, + }, + }, + + "file": { + Type: schema.TypeList, + Optional: true, + MinItems: 0, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "certificate_chain": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringLenBetween(1, 255), + }, + + "private_key": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringLenBetween(1, 255), + }, + }, + }, + }, + + "sds": { + Type: schema.TypeList, + Optional: true, + MinItems: 0, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "secret_name": { + Type: schema.TypeString, + Required: true, + }, + + "source": { + Type: schema.TypeList, + Required: true, + MinItems: 1, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "unix_domain_socket": { + Type: schema.TypeList, + Required: true, + MinItems: 1, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "path": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + + "mode": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + appmesh.ListenerTlsModeDisabled, + appmesh.ListenerTlsModePermissive, + appmesh.ListenerTlsModeStrict, + }, false), + }, + }, + }, + }, }, }, }, diff --git a/aws/resource_aws_appmesh_virtual_node_test.go b/aws/resource_aws_appmesh_virtual_node_test.go index fc3ceb7d8e8..9228195b334 100644 --- a/aws/resource_aws_appmesh_virtual_node_test.go +++ b/aws/resource_aws_appmesh_virtual_node_test.go @@ -210,6 +210,7 @@ func testAccAwsAppmeshVirtualNode_listenerHealthChecks(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.0.port", "8080"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.0.protocol", "http"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.tls.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.logging.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.#", "1"), @@ -248,6 +249,7 @@ func testAccAwsAppmeshVirtualNode_listenerHealthChecks(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.0.port", "8081"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.0.protocol", "http"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.tls.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.logging.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.#", "1"), diff --git a/aws/structure.go b/aws/structure.go index 299475bbe7a..319ba99de82 100644 --- a/aws/structure.go +++ b/aws/structure.go @@ -4739,14 +4739,17 @@ func expandAppmeshVirtualNodeSpec(vSpec []interface{}) *appmesh.VirtualNodeSpec mBackend := vBackend.(map[string]interface{}) if vVirtualService, ok := mBackend["virtual_service"].([]interface{}); ok && len(vVirtualService) > 0 && vVirtualService[0] != nil { - mVirtualService := vVirtualService[0].(map[string]interface{}) + virtualService := &appmesh.VirtualServiceBackend{} - backend.VirtualService = &appmesh.VirtualServiceBackend{} + mVirtualService := vVirtualService[0].(map[string]interface{}) if vVirtualServiceName, ok := mVirtualService["virtual_service_name"].(string); ok { - backend.VirtualService.VirtualServiceName = aws.String(vVirtualServiceName) + virtualService.VirtualServiceName = aws.String(vVirtualServiceName) } + + backend.VirtualService = virtualService } + backends = append(backends, backend) } @@ -4762,44 +4765,127 @@ func expandAppmeshVirtualNodeSpec(vSpec []interface{}) *appmesh.VirtualNodeSpec mListener := vListener.(map[string]interface{}) if vHealthCheck, ok := mListener["health_check"].([]interface{}); ok && len(vHealthCheck) > 0 && vHealthCheck[0] != nil { - mHealthCheck := vHealthCheck[0].(map[string]interface{}) + healthCheck := &appmesh.HealthCheckPolicy{} - listener.HealthCheck = &appmesh.HealthCheckPolicy{} + mHealthCheck := vHealthCheck[0].(map[string]interface{}) if vHealthyThreshold, ok := mHealthCheck["healthy_threshold"].(int); ok && vHealthyThreshold > 0 { - listener.HealthCheck.HealthyThreshold = aws.Int64(int64(vHealthyThreshold)) + healthCheck.HealthyThreshold = aws.Int64(int64(vHealthyThreshold)) } if vIntervalMillis, ok := mHealthCheck["interval_millis"].(int); ok && vIntervalMillis > 0 { - listener.HealthCheck.IntervalMillis = aws.Int64(int64(vIntervalMillis)) + healthCheck.IntervalMillis = aws.Int64(int64(vIntervalMillis)) } if vPath, ok := mHealthCheck["path"].(string); ok && vPath != "" { - listener.HealthCheck.Path = aws.String(vPath) + healthCheck.Path = aws.String(vPath) } if vPort, ok := mHealthCheck["port"].(int); ok && vPort > 0 { - listener.HealthCheck.Port = aws.Int64(int64(vPort)) + healthCheck.Port = aws.Int64(int64(vPort)) } if vProtocol, ok := mHealthCheck["protocol"].(string); ok && vProtocol != "" { - listener.HealthCheck.Protocol = aws.String(vProtocol) + healthCheck.Protocol = aws.String(vProtocol) } if vTimeoutMillis, ok := mHealthCheck["timeout_millis"].(int); ok && vTimeoutMillis > 0 { - listener.HealthCheck.TimeoutMillis = aws.Int64(int64(vTimeoutMillis)) + healthCheck.TimeoutMillis = aws.Int64(int64(vTimeoutMillis)) } if vUnhealthyThreshold, ok := mHealthCheck["unhealthy_threshold"].(int); ok && vUnhealthyThreshold > 0 { - listener.HealthCheck.UnhealthyThreshold = aws.Int64(int64(vUnhealthyThreshold)) + healthCheck.UnhealthyThreshold = aws.Int64(int64(vUnhealthyThreshold)) } + + listener.HealthCheck = healthCheck } if vPortMapping, ok := mListener["port_mapping"].([]interface{}); ok && len(vPortMapping) > 0 && vPortMapping[0] != nil { - mPortMapping := vPortMapping[0].(map[string]interface{}) + portMapping := &appmesh.PortMapping{} - listener.PortMapping = &appmesh.PortMapping{} + mPortMapping := vPortMapping[0].(map[string]interface{}) if vPort, ok := mPortMapping["port"].(int); ok && vPort > 0 { - listener.PortMapping.Port = aws.Int64(int64(vPort)) + portMapping.Port = aws.Int64(int64(vPort)) } if vProtocol, ok := mPortMapping["protocol"].(string); ok && vProtocol != "" { - listener.PortMapping.Protocol = aws.String(vProtocol) + portMapping.Protocol = aws.String(vProtocol) } + + listener.PortMapping = portMapping + } + + if vTls, ok := mListener["tls"].([]interface{}); ok && len(vTls) > 0 && vTls[0] != nil { + tls := &appmesh.ListenerTls{} + + mTls := vTls[0].(map[string]interface{}) + + if vMode, ok := mTls["mode"].(string); ok && vMode != "" { + tls.Mode = aws.String(vMode) + } + + if vCertificate, ok := mTls["certificate"].([]interface{}); ok && len(vCertificate) > 0 && vCertificate[0] != nil { + certificate := &appmesh.ListenerTlsCertificate{} + + mCertificate := vCertificate[0].(map[string]interface{}) + + if vAcm, ok := mCertificate["acm"].([]interface{}); ok && len(vAcm) > 0 && vAcm[0] != nil { + acm := &appmesh.ListenerTlsAcmCertificate{} + + mAcm := vAcm[0].(map[string]interface{}) + + if vCertificateArn, ok := mAcm["certificate_arn"].(string); ok && vCertificateArn != "" { + acm.CertificateArn = aws.String(vCertificateArn) + } + + certificate.Acm = acm + } + + if vFile, ok := mCertificate["file"].([]interface{}); ok && len(vFile) > 0 && vFile[0] != nil { + file := &appmesh.ListenerTlsFileCertificate{} + + mFile := vFile[0].(map[string]interface{}) + + if vCertificateChain, ok := mFile["certificate_chain"].(string); ok && vCertificateChain != "" { + file.CertificateChain = aws.String(vCertificateChain) + } + if vPrivateKey, ok := mFile["private_key"].(string); ok && vPrivateKey != "" { + file.PrivateKey = aws.String(vPrivateKey) + } + + certificate.File = file + } + + if vSds, ok := mCertificate["sds"].([]interface{}); ok && len(vSds) > 0 && vSds[0] != nil { + sds := &appmesh.ListenerTlsSdsCertificate{} + + mSds := vSds[0].(map[string]interface{}) + + if vSecretName, ok := mSds["secret_name"].(string); ok && vSecretName != "" { + sds.SecretName = aws.String(vSecretName) + } + + if vSource, ok := mSds["source"].([]interface{}); ok && len(vSource) > 0 && vSource[0] != nil { + source := &appmesh.SdsSource{} + + mSource := vSource[0].(map[string]interface{}) + + if vUnixDomainSocket, ok := mSource["unix_domain_socket"].([]interface{}); ok && len(vUnixDomainSocket) > 0 && vUnixDomainSocket[0] != nil { + unixDomainSocket := &appmesh.SdsUnixDomainSocketSource{} + + mUnixDomainSocket := vUnixDomainSocket[0].(map[string]interface{}) + + if vPath, ok := mUnixDomainSocket["path"].(string); ok && vPath != "" { + unixDomainSocket.Path = aws.String(vPath) + } + + source.UnixDomainSocket = unixDomainSocket + } + + sds.Source = source + } + + certificate.Sds = sds + } + + tls.Certificate = certificate + } + + listener.Tls = tls } listeners = append(listeners, listener) @@ -4809,34 +4895,40 @@ func expandAppmeshVirtualNodeSpec(vSpec []interface{}) *appmesh.VirtualNodeSpec } if vLogging, ok := mSpec["logging"].([]interface{}); ok && len(vLogging) > 0 && vLogging[0] != nil { + logging := &appmesh.Logging{} + mLogging := vLogging[0].(map[string]interface{}) if vAccessLog, ok := mLogging["access_log"].([]interface{}); ok && len(vAccessLog) > 0 && vAccessLog[0] != nil { + accessLog := &appmesh.AccessLog{} + mAccessLog := vAccessLog[0].(map[string]interface{}) if vFile, ok := mAccessLog["file"].([]interface{}); ok && len(vFile) > 0 && vFile[0] != nil { + file := &appmesh.FileAccessLog{} + mFile := vFile[0].(map[string]interface{}) if vPath, ok := mFile["path"].(string); ok && vPath != "" { - spec.Logging = &appmesh.Logging{ - AccessLog: &appmesh.AccessLog{ - File: &appmesh.FileAccessLog{ - Path: aws.String(vPath), - }, - }, - } + file.Path = aws.String(vPath) } + + accessLog.File = file } + + logging.AccessLog = accessLog } + + spec.Logging = logging } if vServiceDiscovery, ok := mSpec["service_discovery"].([]interface{}); ok && len(vServiceDiscovery) > 0 && vServiceDiscovery[0] != nil { - spec.ServiceDiscovery = &appmesh.ServiceDiscovery{} + serviceDiscovery := &appmesh.ServiceDiscovery{} mServiceDiscovery := vServiceDiscovery[0].(map[string]interface{}) if vAwsCloudMap, ok := mServiceDiscovery["aws_cloud_map"].([]interface{}); ok && len(vAwsCloudMap) > 0 && vAwsCloudMap[0] != nil { - spec.ServiceDiscovery.AwsCloudMap = &appmesh.AwsCloudMapServiceDiscovery{} + awsCloudMap := &appmesh.AwsCloudMapServiceDiscovery{} mAwsCloudMap := vAwsCloudMap[0].(map[string]interface{}) @@ -4850,25 +4942,31 @@ func expandAppmeshVirtualNodeSpec(vSpec []interface{}) *appmesh.VirtualNodeSpec }) } - spec.ServiceDiscovery.AwsCloudMap.Attributes = attributes + awsCloudMap.Attributes = attributes } if vNamespaceName, ok := mAwsCloudMap["namespace_name"].(string); ok && vNamespaceName != "" { - spec.ServiceDiscovery.AwsCloudMap.NamespaceName = aws.String(vNamespaceName) + awsCloudMap.NamespaceName = aws.String(vNamespaceName) } if vServiceName, ok := mAwsCloudMap["service_name"].(string); ok && vServiceName != "" { - spec.ServiceDiscovery.AwsCloudMap.ServiceName = aws.String(vServiceName) + awsCloudMap.ServiceName = aws.String(vServiceName) } + + serviceDiscovery.AwsCloudMap = awsCloudMap } if vDns, ok := mServiceDiscovery["dns"].([]interface{}); ok && len(vDns) > 0 && vDns[0] != nil { + dns := &appmesh.DnsServiceDiscovery{} + mDns := vDns[0].(map[string]interface{}) if vHostname, ok := mDns["hostname"].(string); ok && vHostname != "" { - spec.ServiceDiscovery.Dns = &appmesh.DnsServiceDiscovery{ - Hostname: aws.String(vHostname), - } + dns.Hostname = aws.String(vHostname) } + + serviceDiscovery.Dns = dns } + + spec.ServiceDiscovery = serviceDiscovery } return spec @@ -4881,16 +4979,17 @@ func flattenAppmeshVirtualNodeSpec(spec *appmesh.VirtualNodeSpec) []interface{} mSpec := map[string]interface{}{} - if spec.Backends != nil { + if backends := spec.Backends; backends != nil { vBackends := []interface{}{} - for _, backend := range spec.Backends { + for _, backend := range backends { mBackend := map[string]interface{}{} - if backend.VirtualService != nil { + if virtualService := backend.VirtualService; virtualService != nil { mVirtualService := map[string]interface{}{ - "virtual_service_name": aws.StringValue(backend.VirtualService.VirtualServiceName), + "virtual_service_name": aws.StringValue(virtualService.VirtualServiceName), } + mBackend["virtual_service"] = []interface{}{mVirtualService} } @@ -4905,69 +5004,104 @@ func flattenAppmeshVirtualNodeSpec(spec *appmesh.VirtualNodeSpec) []interface{} listener := spec.Listeners[0] mListener := map[string]interface{}{} - if listener.HealthCheck != nil { + if healthCheck := listener.HealthCheck; healthCheck != nil { mHealthCheck := map[string]interface{}{ - "healthy_threshold": int(aws.Int64Value(listener.HealthCheck.HealthyThreshold)), - "interval_millis": int(aws.Int64Value(listener.HealthCheck.IntervalMillis)), - "path": aws.StringValue(listener.HealthCheck.Path), - "port": int(aws.Int64Value(listener.HealthCheck.Port)), - "protocol": aws.StringValue(listener.HealthCheck.Protocol), - "timeout_millis": int(aws.Int64Value(listener.HealthCheck.TimeoutMillis)), - "unhealthy_threshold": int(aws.Int64Value(listener.HealthCheck.UnhealthyThreshold)), + "healthy_threshold": int(aws.Int64Value(healthCheck.HealthyThreshold)), + "interval_millis": int(aws.Int64Value(healthCheck.IntervalMillis)), + "path": aws.StringValue(healthCheck.Path), + "port": int(aws.Int64Value(healthCheck.Port)), + "protocol": aws.StringValue(healthCheck.Protocol), + "timeout_millis": int(aws.Int64Value(healthCheck.TimeoutMillis)), + "unhealthy_threshold": int(aws.Int64Value(healthCheck.UnhealthyThreshold)), } mListener["health_check"] = []interface{}{mHealthCheck} } - if listener.PortMapping != nil { + if portMapping := listener.PortMapping; portMapping != nil { mPortMapping := map[string]interface{}{ - "port": int(aws.Int64Value(listener.PortMapping.Port)), - "protocol": aws.StringValue(listener.PortMapping.Protocol), + "port": int(aws.Int64Value(portMapping.Port)), + "protocol": aws.StringValue(portMapping.Protocol), } mListener["port_mapping"] = []interface{}{mPortMapping} } + if tls := listener.Tls; tls != nil { + mTls := map[string]interface{}{ + "mode": aws.StringValue(tls.Mode), + } + + if certificate := tls.Certificate; certificate != nil { + mCertificate := map[string]interface{}{} + + if acm := certificate.Acm; acm != nil { + mAcm := map[string]interface{}{ + "certificate_arn": aws.StringValue(acm.CertificateArn), + } + + mCertificate["acm"] = []interface{}{mAcm} + } + + if file := certificate.File; file != nil { + mFile := map[string]interface{}{ + "certificate_chain": aws.StringValue(file.CertificateChain), + "private_key": aws.StringValue(file.PrivateKey), + } + + mCertificate["file"] = []interface{}{mFile} + } + + mTls["certificate"] = []interface{}{mCertificate} + } + + mListener["tls"] = []interface{}{mTls} + } + mSpec["listener"] = []interface{}{mListener} } - if spec.Logging != nil && spec.Logging.AccessLog != nil && spec.Logging.AccessLog.File != nil { - mSpec["logging"] = []interface{}{ - map[string]interface{}{ - "access_log": []interface{}{ + if logging := spec.Logging; logging != nil { + mLogging := map[string]interface{}{} + + if accessLog := logging.AccessLog; accessLog != nil { + mAccessLog := map[string]interface{}{} + + if file := accessLog.File; file != nil { + mAccessLog["file"] = []interface{}{ map[string]interface{}{ - "file": []interface{}{ - map[string]interface{}{ - "path": aws.StringValue(spec.Logging.AccessLog.File.Path), - }, - }, + "path": aws.StringValue(file.Path), }, - }, - }, + } + } + + mLogging["access_log"] = []interface{}{mAccessLog} } + + mSpec["logging"] = []interface{}{mLogging} } - if spec.ServiceDiscovery != nil { + if serviceDiscovery := spec.ServiceDiscovery; serviceDiscovery != nil { mServiceDiscovery := map[string]interface{}{} - if spec.ServiceDiscovery.AwsCloudMap != nil { + if awsCloudMap := serviceDiscovery.AwsCloudMap; awsCloudMap != nil { vAttributes := map[string]interface{}{} - for _, attribute := range spec.ServiceDiscovery.AwsCloudMap.Attributes { + for _, attribute := range awsCloudMap.Attributes { vAttributes[aws.StringValue(attribute.Key)] = aws.StringValue(attribute.Value) } mServiceDiscovery["aws_cloud_map"] = []interface{}{ map[string]interface{}{ "attributes": vAttributes, - "namespace_name": aws.StringValue(spec.ServiceDiscovery.AwsCloudMap.NamespaceName), - "service_name": aws.StringValue(spec.ServiceDiscovery.AwsCloudMap.ServiceName), + "namespace_name": aws.StringValue(awsCloudMap.NamespaceName), + "service_name": aws.StringValue(awsCloudMap.ServiceName), }, } } - if spec.ServiceDiscovery.Dns != nil { + if dns := serviceDiscovery.Dns; dns != nil { mServiceDiscovery["dns"] = []interface{}{ map[string]interface{}{ - "hostname": aws.StringValue(spec.ServiceDiscovery.Dns.Hostname), + "hostname": aws.StringValue(dns.Hostname), }, } } diff --git a/website/docs/r/appmesh_virtual_node.html.markdown b/website/docs/r/appmesh_virtual_node.html.markdown index 0878e3a36a8..2ff40473a63 100644 --- a/website/docs/r/appmesh_virtual_node.html.markdown +++ b/website/docs/r/appmesh_virtual_node.html.markdown @@ -198,6 +198,7 @@ The `listener` object supports the following: * `port_mapping` - (Required) The port mapping information for the listener. * `health_check` - (Optional) The health check information for the listener. +* `tls` - (Optional) The Transport Layer Security (TLS) properties for the listener The `logging` object supports the following: @@ -242,6 +243,39 @@ The `health_check` object supports the following: * `path` - (Optional) The destination path for the health check request. This is only required if the specified protocol is `http`. * `port` - (Optional) The destination port for the health check request. This port must match the port defined in the `port_mapping` for the listener. +The `tls` object supports the following: + +* `certificate` - (Required) The listener's TLS certificate. +* `mode`- (Required) The listener's TLS mode. Valid values: `DISABLED`, `PERMISSIVE`, `STRICT`. + +The `certificate` object supports the following: + +* `acm` - (Optional) An AWS Certicate Manager (ACM) certificate. +* `file` - (optional) A local file certificate. +* `sds` - (Optional) A [secret discovery service](https://www.envoyproxy.io/docs/envoy/latest/configuration/security/secret) (SDS) secret. + +The `acm` object supports the following: + +* `certificate_arn` - (Required) The Amazon Resource Name (ARN) for the certificate. + +The `file` object supports the following: + +* `certificate_chain` - (Required) The certificate chain for the certificate. +* `private_key` - (Required) The private key for a certificate stored on the file system of the virtual node that the proxy is running on. + +The `sds` object supports the following: + +* `secret_name` - (Required) The secret name. +* `source` - (Required) The secret source. + +The `source` object supports the following: + +* `unix_domain_socket` - (Required) The Unix domain socket source location. + +The `unix_domain_socket` object supports the following: + +* `path` - (Required) file system path for the socket. + ## Attributes Reference In addition to all arguments above, the following attributes are exported: From e5e653d4468f184f8db17563b5e1fcac4df86811 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Sun, 8 Mar 2020 18:11:20 -0400 Subject: [PATCH 02/21] r/aws_appmesh_virtual_node: Test listener.tls attribute. Disable SDS support (ForbiddenException: TLS Certificates from SDS are not supported). Acceptance test output: $ make testacc TEST=./aws TESTARGS='-run=TestAccAWSAppmesh/VirtualNode/tls' ==> Checking that code complies with gofmt requirements... GO111MODULE=off TF_ACC=1 go test ./aws -v -count 1 -parallel 20 -run=TestAccAWSAppmesh/VirtualNode/tls -timeout 120m === RUN TestAccAWSAppmesh === RUN TestAccAWSAppmesh/VirtualNode === RUN TestAccAWSAppmesh/VirtualNode/tls --- PASS: TestAccAWSAppmesh (56.32s) --- PASS: TestAccAWSAppmesh/VirtualNode (56.32s) --- PASS: TestAccAWSAppmesh/VirtualNode/tls (56.32s) PASS ok github.com/terraform-providers/terraform-provider-aws/aws 56.365s --- aws/resource_aws_appmesh_test.go | 1 + aws/resource_aws_appmesh_virtual_node.go | 79 +++--- aws/resource_aws_appmesh_virtual_node_test.go | 268 ++++++++++++++++++ aws/structure.go | 32 --- .../docs/r/appmesh_virtual_node.html.markdown | 14 - 5 files changed, 309 insertions(+), 85 deletions(-) diff --git a/aws/resource_aws_appmesh_test.go b/aws/resource_aws_appmesh_test.go index cc6f17a61c7..e43b26b7784 100644 --- a/aws/resource_aws_appmesh_test.go +++ b/aws/resource_aws_appmesh_test.go @@ -24,6 +24,7 @@ func TestAccAWSAppmesh_serial(t *testing.T) { "cloudMapServiceDiscovery": testAccAwsAppmeshVirtualNode_cloudMapServiceDiscovery, "listenerHealthChecks": testAccAwsAppmeshVirtualNode_listenerHealthChecks, "logging": testAccAwsAppmeshVirtualNode_logging, + "tls": testAccAwsAppmeshVirtualNode_tls, "tags": testAccAwsAppmeshVirtualNode_tags, }, "VirtualRouter": { diff --git a/aws/resource_aws_appmesh_virtual_node.go b/aws/resource_aws_appmesh_virtual_node.go index f7e19bc3eb1..832987d783a 100644 --- a/aws/resource_aws_appmesh_virtual_node.go +++ b/aws/resource_aws_appmesh_virtual_node.go @@ -224,45 +224,46 @@ func resourceAwsAppmeshVirtualNode() *schema.Resource { }, }, - "sds": { - Type: schema.TypeList, - Optional: true, - MinItems: 0, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "secret_name": { - Type: schema.TypeString, - Required: true, - }, - - "source": { - Type: schema.TypeList, - Required: true, - MinItems: 1, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "unix_domain_socket": { - Type: schema.TypeList, - Required: true, - MinItems: 1, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "path": { - Type: schema.TypeString, - Required: true, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, + // ForbiddenException: TLS Certificates from SDS are not supported. + // "sds": { + // Type: schema.TypeList, + // Optional: true, + // MinItems: 0, + // MaxItems: 1, + // Elem: &schema.Resource{ + // Schema: map[string]*schema.Schema{ + // "secret_name": { + // Type: schema.TypeString, + // Required: true, + // }, + + // "source": { + // Type: schema.TypeList, + // Required: true, + // MinItems: 1, + // MaxItems: 1, + // Elem: &schema.Resource{ + // Schema: map[string]*schema.Schema{ + // "unix_domain_socket": { + // Type: schema.TypeList, + // Required: true, + // MinItems: 1, + // MaxItems: 1, + // Elem: &schema.Resource{ + // Schema: map[string]*schema.Schema{ + // "path": { + // Type: schema.TypeString, + // Required: true, + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // }, }, }, }, diff --git a/aws/resource_aws_appmesh_virtual_node_test.go b/aws/resource_aws_appmesh_virtual_node_test.go index 9228195b334..170820bbb76 100644 --- a/aws/resource_aws_appmesh_virtual_node_test.go +++ b/aws/resource_aws_appmesh_virtual_node_test.go @@ -364,6 +364,122 @@ func testAccAwsAppmeshVirtualNode_tags(t *testing.T) { }) } +func testAccAwsAppmeshVirtualNode_tls(t *testing.T) { + var vn appmesh.VirtualNodeData + resourceName := "aws_appmesh_virtual_node.test" + acmCertificateResourceName := "aws_acm_certificate.cert" + meshName := acctest.RandomWithPrefix("tf-acc-test") + vnName := acctest.RandomWithPrefix("tf-acc-test") + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAppmeshVirtualNodeDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAppmeshVirtualNodeConfig_tlsFile(meshName, vnName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAppmeshVirtualNodeExists(resourceName, &vn), + resource.TestCheckResourceAttr(resourceName, "name", vnName), + resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), + testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), + resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.2622272660.virtual_service.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.2622272660.virtual_service.0.virtual_service_name", "servicea.simpleapp.local"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.health_check.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.port_mapping.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.port_mapping.0.port", "8080"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.port_mapping.0.protocol", "http"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.tls.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.tls.0.certificate.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.tls.0.certificate.0.acm.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.tls.0.certificate.0.file.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.tls.0.certificate.0.file.0.certificate_chain", "/cert_chain.pem"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.tls.0.certificate.0.file.0.private_key", "/key.pem"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.tls.0.certificate.0.sds.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.tls.0.mode", "PERMISSIVE"), + resource.TestCheckResourceAttr(resourceName, "spec.0.logging.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.0.hostname", "serviceb.simpleapp.local"), + resource.TestCheckResourceAttrSet(resourceName, "created_date"), + resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), + testAccCheckResourceAttrAccountID(resourceName, "resource_owner"), + testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh-preview", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), + ), + }, + // ForbiddenException: TLS Certificates from SDS are not supported. + // { + // Config: testAccAppmeshVirtualNodeConfig_tlsSds(meshName, vnName), + // Check: resource.ComposeTestCheckFunc( + // testAccCheckAppmeshVirtualNodeExists(resourceName, &vn), + // resource.TestCheckResourceAttr(resourceName, "name", vnName), + // resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), + // testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), + // resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), + // resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "1"), + // resource.TestCheckResourceAttr(resourceName, "spec.0.backend.2622272660.virtual_service.#", "1"), + // resource.TestCheckResourceAttr(resourceName, "spec.0.backend.2622272660.virtual_service.0.virtual_service_name", "servicea.simpleapp.local"), + // resource.TestCheckResourceAttr(resourceName, "spec.0.listener.#", "1"), + // resource.TestCheckResourceAttr(resourceName, "spec.0.listener.3024651324.health_check.#", "0"), + // resource.TestCheckResourceAttr(resourceName, "spec.0.listener.3024651324.port_mapping.#", "1"), + // resource.TestCheckResourceAttr(resourceName, "spec.0.listener.3024651324.port_mapping.0.port", "8080"), + // resource.TestCheckResourceAttr(resourceName, "spec.0.listener.3024651324.port_mapping.0.protocol", "http"), + // resource.TestCheckResourceAttr(resourceName, "spec.0.listener.3024651324.tls.#", "1"), + // resource.TestCheckResourceAttr(resourceName, "spec.0.listener.3024651324.tls.0.certificate.#", "1"), + // resource.TestCheckResourceAttr(resourceName, "spec.0.listener.3024651324.tls.0.certificate.0.acm.#", "0"), + // resource.TestCheckResourceAttr(resourceName, "spec.0.listener.3024651324.tls.0.certificate.0.file.#", "0"), + // resource.TestCheckResourceAttr(resourceName, "spec.0.listener.3024651324.tls.0.certificate.0.sds.#", "1"), + // resource.TestCheckResourceAttr(resourceName, "spec.0.listener.3024651324.tls.0.certificate.0.sds.0.secret_name", "secret"), + // resource.TestCheckResourceAttr(resourceName, "spec.0.listener.3024651324.tls.0.certificate.0.sds.0.source.#", "1"), + // resource.TestCheckResourceAttr(resourceName, "spec.0.listener.3024651324.tls.0.certificate.0.sds.0.source.0.unix_domain_socket.#", "1"), + // resource.TestCheckResourceAttr(resourceName, "spec.0.listener.3024651324.tls.0.certificate.0.sds.0.source.0.unix_domain_socket.0.path", "/sds-server.sock"), + // resource.TestCheckResourceAttr(resourceName, "spec.0.listener.3024651324.tls.0.mode", "DISABLED"), + // resource.TestCheckResourceAttr(resourceName, "spec.0.logging.#", "0"), + // resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.#", "1"), + // resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.#", "1"), + // resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.0.hostname", "serviceb.simpleapp.local"), + // resource.TestCheckResourceAttrSet(resourceName, "created_date"), + // resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), + // testAccCheckResourceAttrAccountID(resourceName, "resource_owner"), + // testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh-preview", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), + // ), + // }, + { + Config: testAccAppmeshVirtualNodeConfig_tlsAcm(meshName, vnName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAppmeshVirtualNodeExists(resourceName, &vn), + resource.TestCheckResourceAttr(resourceName, "name", vnName), + resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), + testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), + resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.2622272660.virtual_service.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.2622272660.virtual_service.0.virtual_service_name", "servicea.simpleapp.local"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.#", "1"), + testAccCheckAppmeshVirtualNodeTlsAcmCertificateArn(acmCertificateResourceName, "arn", &vn), + resource.TestCheckResourceAttr(resourceName, "spec.0.logging.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.0.hostname", "serviceb.simpleapp.local"), + resource.TestCheckResourceAttrSet(resourceName, "created_date"), + resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), + testAccCheckResourceAttrAccountID(resourceName, "resource_owner"), + testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh-preview", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), + ), + }, + { + ResourceName: resourceName, + ImportStateId: fmt.Sprintf("%s/%s", meshName, vnName), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testAccCheckAppmeshVirtualNodeDestroy(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).appmeshconn @@ -414,6 +530,31 @@ func testAccCheckAppmeshVirtualNodeExists(name string, v *appmesh.VirtualNodeDat } } +// testAccCheckAppmeshVirtualNodeTlsAcmCertificateArn(acmCertificateResourceName, "arn", &vn), +func testAccCheckAppmeshVirtualNodeTlsAcmCertificateArn(name, key string, v *appmesh.VirtualNodeData) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + expected, ok := rs.Primary.Attributes[key] + if !ok { + return fmt.Errorf("Key not found: %s", key) + } + if v.Spec == nil || v.Spec.Listeners == nil || len(v.Spec.Listeners) != 1 || v.Spec.Listeners[0].Tls == nil || + v.Spec.Listeners[0].Tls.Certificate == nil || v.Spec.Listeners[0].Tls.Certificate.Acm == nil { + return fmt.Errorf("Not found: v.Spec.Listeners[0].Tls.Certificate.Acm") + } + got := aws.StringValue(v.Spec.Listeners[0].Tls.Certificate.Acm.CertificateArn) + if got != expected { + return fmt.Errorf("Expected ACM certificate ARN %q, got %q", expected, got) + } + + return nil + } +} + func testAccAppmeshVirtualNodeConfig_mesh(rName string) string { return fmt.Sprintf(` resource "aws_appmesh_mesh" "test" { @@ -609,3 +750,130 @@ resource "aws_appmesh_virtual_node" "test" { } `, vnName, tagKey1, tagValue1, tagKey2, tagValue2) } + +func testAccAppmeshVirtualNodeConfig_tlsFile(meshName, vnName string) string { + return testAccAppmeshVirtualNodeConfig_mesh(meshName) + fmt.Sprintf(` +resource "aws_appmesh_virtual_node" "test" { + name = %[1]q + mesh_name = "${aws_appmesh_mesh.test.id}" + + spec { + backend { + virtual_service { + virtual_service_name = "servicea.simpleapp.local" + } + } + + listener { + port_mapping { + port = 8080 + protocol = "http" + } + + tls { + certificate { + file { + certificate_chain = "/cert_chain.pem" + private_key = "/key.pem" + } + } + + mode = "PERMISSIVE" + } + } + + service_discovery { + dns { + hostname = "serviceb.simpleapp.local" + } + } + } +} +`, vnName) +} + +func testAccAppmeshVirtualNodeConfig_tlsSds(meshName, vnName string) string { + return testAccAppmeshVirtualNodeConfig_mesh(meshName) + fmt.Sprintf(` +resource "aws_appmesh_virtual_node" "test" { + name = %[1]q + mesh_name = "${aws_appmesh_mesh.test.id}" + + spec { + backend { + virtual_service { + virtual_service_name = "servicea.simpleapp.local" + } + } + + listener { + port_mapping { + port = 8080 + protocol = "http" + } + + tls { + certificate { + sds { + secret_name = "secret" + + source { + unix_domain_socket { + path = "/sds-server.sock" + } + } + } + } + + mode = "DISABLED" + } + } + + service_discovery { + dns { + hostname = "serviceb.simpleapp.local" + } + } + } +} +`, vnName) +} + +func testAccAppmeshVirtualNodeConfig_tlsAcm(meshName, vnName string) string { + return testAccAcmCertificateConfig_privateCert(meshName) + testAccAppmeshVirtualNodeConfig_mesh(meshName) + fmt.Sprintf(` +resource "aws_appmesh_virtual_node" "test" { + name = %[1]q + mesh_name = "${aws_appmesh_mesh.test.id}" + + spec { + backend { + virtual_service { + virtual_service_name = "servicea.simpleapp.local" + } + } + + listener { + port_mapping { + port = 8080 + protocol = "http" + } + + tls { + certificate { + acm { + certificate_arn = "${aws_acm_certificate.cert.arn}" + } + } + + mode = "STRICT" + } + } + + service_discovery { + dns { + hostname = "serviceb.simpleapp.local" + } + } + } +} +`, vnName) +} diff --git a/aws/structure.go b/aws/structure.go index 319ba99de82..fff1af7eb0e 100644 --- a/aws/structure.go +++ b/aws/structure.go @@ -4850,38 +4850,6 @@ func expandAppmeshVirtualNodeSpec(vSpec []interface{}) *appmesh.VirtualNodeSpec certificate.File = file } - if vSds, ok := mCertificate["sds"].([]interface{}); ok && len(vSds) > 0 && vSds[0] != nil { - sds := &appmesh.ListenerTlsSdsCertificate{} - - mSds := vSds[0].(map[string]interface{}) - - if vSecretName, ok := mSds["secret_name"].(string); ok && vSecretName != "" { - sds.SecretName = aws.String(vSecretName) - } - - if vSource, ok := mSds["source"].([]interface{}); ok && len(vSource) > 0 && vSource[0] != nil { - source := &appmesh.SdsSource{} - - mSource := vSource[0].(map[string]interface{}) - - if vUnixDomainSocket, ok := mSource["unix_domain_socket"].([]interface{}); ok && len(vUnixDomainSocket) > 0 && vUnixDomainSocket[0] != nil { - unixDomainSocket := &appmesh.SdsUnixDomainSocketSource{} - - mUnixDomainSocket := vUnixDomainSocket[0].(map[string]interface{}) - - if vPath, ok := mUnixDomainSocket["path"].(string); ok && vPath != "" { - unixDomainSocket.Path = aws.String(vPath) - } - - source.UnixDomainSocket = unixDomainSocket - } - - sds.Source = source - } - - certificate.Sds = sds - } - tls.Certificate = certificate } diff --git a/website/docs/r/appmesh_virtual_node.html.markdown b/website/docs/r/appmesh_virtual_node.html.markdown index 2ff40473a63..028f6f23cf1 100644 --- a/website/docs/r/appmesh_virtual_node.html.markdown +++ b/website/docs/r/appmesh_virtual_node.html.markdown @@ -252,7 +252,6 @@ The `certificate` object supports the following: * `acm` - (Optional) An AWS Certicate Manager (ACM) certificate. * `file` - (optional) A local file certificate. -* `sds` - (Optional) A [secret discovery service](https://www.envoyproxy.io/docs/envoy/latest/configuration/security/secret) (SDS) secret. The `acm` object supports the following: @@ -263,19 +262,6 @@ The `file` object supports the following: * `certificate_chain` - (Required) The certificate chain for the certificate. * `private_key` - (Required) The private key for a certificate stored on the file system of the virtual node that the proxy is running on. -The `sds` object supports the following: - -* `secret_name` - (Required) The secret name. -* `source` - (Required) The secret source. - -The `source` object supports the following: - -* `unix_domain_socket` - (Required) The Unix domain socket source location. - -The `unix_domain_socket` object supports the following: - -* `path` - (Required) file system path for the socket. - ## Attributes Reference In addition to all arguments above, the following attributes are exported: From 47d441f93a17aaad24bf7727394b0decfef491b5 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Sun, 22 Mar 2020 21:37:50 -0400 Subject: [PATCH 03/21] r/aws_appmesh_virtual_node: Add backend.virtual_service.client_policy attribute. TODO: Enabled acceptance tests. Acceptance testing output: $ make testacc TEST=./aws TESTARGS='-run=TestAccAWSAppmesh/VirtualNode' ==> Checking that code complies with gofmt requirements... GO111MODULE=off TF_ACC=1 go test ./aws -v -count 1 -parallel 20 -run=TestAccAWSAppmesh/VirtualNode -timeout 120m === RUN TestAccAWSAppmesh === RUN TestAccAWSAppmesh/VirtualNode === RUN TestAccAWSAppmesh/VirtualNode/tls === RUN TestAccAWSAppmesh/VirtualNode/basic === RUN TestAccAWSAppmesh/VirtualNode/cloudMapServiceDiscovery === RUN TestAccAWSAppmesh/VirtualNode/listenerHealthChecks === RUN TestAccAWSAppmesh/VirtualNode/logging --- PASS: TestAccAWSAppmesh (283.47s) --- PASS: TestAccAWSAppmesh/VirtualNode (283.47s) --- PASS: TestAccAWSAppmesh/VirtualNode/tls (56.13s) --- PASS: TestAccAWSAppmesh/VirtualNode/basic (26.08s) --- PASS: TestAccAWSAppmesh/VirtualNode/cloudMapServiceDiscovery (115.83s) --- PASS: TestAccAWSAppmesh/VirtualNode/listenerHealthChecks (43.04s) --- PASS: TestAccAWSAppmesh/VirtualNode/logging (42.39s) PASS ok github.com/terraform-providers/terraform-provider-aws/aws 283.517s --- aws/resource_aws_appmesh_virtual_node.go | 161 ++++++++--- aws/resource_aws_appmesh_virtual_node_test.go | 256 ++++++++++++++---- aws/structure.go | 122 +++++++++ .../docs/r/appmesh_virtual_node.html.markdown | 28 ++ 4 files changed, 469 insertions(+), 98 deletions(-) diff --git a/aws/resource_aws_appmesh_virtual_node.go b/aws/resource_aws_appmesh_virtual_node.go index 832987d783a..2aaf61491d1 100644 --- a/aws/resource_aws_appmesh_virtual_node.go +++ b/aws/resource_aws_appmesh_virtual_node.go @@ -77,6 +77,92 @@ func resourceAwsAppmeshVirtualNode() *schema.Resource { Required: true, ValidateFunc: validation.StringLenBetween(1, 255), }, + + "client_policy": { + Type: schema.TypeList, + Optional: true, + MinItems: 0, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "tls": { + Type: schema.TypeList, + Optional: true, + MinItems: 0, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enforce": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + + "ports": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeInt}, + Set: schema.HashInt, + }, + + "validation": { + Type: schema.TypeList, + Required: true, + MinItems: 1, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "trust": { + Type: schema.TypeList, + Required: true, + MinItems: 1, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "acm": { + Type: schema.TypeList, + Optional: true, + MinItems: 0, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "certificate_authority_arns": { + Type: schema.TypeSet, + Required: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: schema.HashString, + }, + }, + }, + }, + + "file": { + Type: schema.TypeList, + Optional: true, + MinItems: 0, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "certificate_chain": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringLenBetween(1, 255), + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, }, }, }, @@ -223,47 +309,6 @@ func resourceAwsAppmeshVirtualNode() *schema.Resource { }, }, }, - - // ForbiddenException: TLS Certificates from SDS are not supported. - // "sds": { - // Type: schema.TypeList, - // Optional: true, - // MinItems: 0, - // MaxItems: 1, - // Elem: &schema.Resource{ - // Schema: map[string]*schema.Schema{ - // "secret_name": { - // Type: schema.TypeString, - // Required: true, - // }, - - // "source": { - // Type: schema.TypeList, - // Required: true, - // MinItems: 1, - // MaxItems: 1, - // Elem: &schema.Resource{ - // Schema: map[string]*schema.Schema{ - // "unix_domain_socket": { - // Type: schema.TypeList, - // Required: true, - // MinItems: 1, - // MaxItems: 1, - // Elem: &schema.Resource{ - // Schema: map[string]*schema.Schema{ - // "path": { - // Type: schema.TypeString, - // Required: true, - // }, - // }, - // }, - // }, - // }, - // }, - // }, - // }, - // }, - // }, }, }, }, @@ -567,6 +612,40 @@ func appmeshVirtualNodeBackendHash(vBackend interface{}) int { if v, ok := mVirtualService["virtual_service_name"].(string); ok { buf.WriteString(fmt.Sprintf("%s-", v)) } + if vClientPolicy, ok := mVirtualService["client_policy"].([]interface{}); ok && len(vClientPolicy) > 0 && vClientPolicy[0] != nil { + mClientPolicy := vClientPolicy[0].(map[string]interface{}) + if vTls, ok := mClientPolicy["tls"].([]interface{}); ok && len(vTls) > 0 && vTls[0] != nil { + mTls := vTls[0].(map[string]interface{}) + if v, ok := mTls["enforce"].(bool); ok { + buf.WriteString(fmt.Sprintf("%t-", v)) + } + if v, ok := mTls["ports"].(*schema.Set); ok && v.Len() > 0 { + for _, port := range v.List() { + buf.WriteString(fmt.Sprintf("%d-", port.(int))) + } + } + if vValidation, ok := mTls["validation"].([]interface{}); ok && len(vValidation) > 0 && vValidation[0] != nil { + mValidation := vValidation[0].(map[string]interface{}) + if vTrust, ok := mValidation["trust"].([]interface{}); ok && len(vTrust) > 0 && vTrust[0] != nil { + mTrust := vTrust[0].(map[string]interface{}) + if vAcm, ok := mTrust["acm"].([]interface{}); ok && len(vAcm) > 0 && vAcm[0] != nil { + mAcm := vAcm[0].(map[string]interface{}) + if v, ok := mAcm["certificate_authority_arns"].(*schema.Set); ok && v.Len() > 0 { + for _, arn := range v.List() { + buf.WriteString(fmt.Sprintf("%s-", arn.(string))) + } + } + } + if vFile, ok := mTrust["file"].([]interface{}); ok && len(vFile) > 0 && vFile[0] != nil { + mFile := vFile[0].(map[string]interface{}) + if v, ok := mFile["certificate_chain"].(string); ok { + buf.WriteString(fmt.Sprintf("%s-", v)) + } + } + } + } + } + } } return hashcode.String(buf.String()) } diff --git a/aws/resource_aws_appmesh_virtual_node_test.go b/aws/resource_aws_appmesh_virtual_node_test.go index 170820bbb76..52461da140d 100644 --- a/aws/resource_aws_appmesh_virtual_node_test.go +++ b/aws/resource_aws_appmesh_virtual_node_test.go @@ -195,6 +195,7 @@ func testAccAwsAppmeshVirtualNode_listenerHealthChecks(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "1"), tfawsresource.TestCheckTypeSetElemNestedAttrs(resourceName, "spec.0.backend.*", map[string]string{ + "virtual_service.client_policy.#": "0", "virtual_service.#": "1", "virtual_service.0.virtual_service_name": "servicea.simpleapp.local", }), @@ -231,10 +232,12 @@ func testAccAwsAppmeshVirtualNode_listenerHealthChecks(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "2"), tfawsresource.TestCheckTypeSetElemNestedAttrs(resourceName, "spec.0.backend.*", map[string]string{ + "virtual_service.client_policy.#": "0", "virtual_service.#": "1", "virtual_service.0.virtual_service_name": "servicec.simpleapp.local", }), tfawsresource.TestCheckTypeSetElemNestedAttrs(resourceName, "spec.0.backend.*", map[string]string{ + "virtual_service.client_policy.#": "0", "virtual_service.#": "1", "virtual_service.0.virtual_service_name": "serviced.simpleapp.local", }), @@ -385,6 +388,7 @@ func testAccAwsAppmeshVirtualNode_tls(t *testing.T) { testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.2622272660.virtual_service.client_policy.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.2622272660.virtual_service.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.2622272660.virtual_service.0.virtual_service_name", "servicea.simpleapp.local"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.#", "1"), @@ -398,7 +402,6 @@ func testAccAwsAppmeshVirtualNode_tls(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.tls.0.certificate.0.file.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.tls.0.certificate.0.file.0.certificate_chain", "/cert_chain.pem"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.tls.0.certificate.0.file.0.private_key", "/key.pem"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.tls.0.certificate.0.sds.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.tls.0.mode", "PERMISSIVE"), resource.TestCheckResourceAttr(resourceName, "spec.0.logging.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.#", "1"), @@ -410,43 +413,6 @@ func testAccAwsAppmeshVirtualNode_tls(t *testing.T) { testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh-preview", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), ), }, - // ForbiddenException: TLS Certificates from SDS are not supported. - // { - // Config: testAccAppmeshVirtualNodeConfig_tlsSds(meshName, vnName), - // Check: resource.ComposeTestCheckFunc( - // testAccCheckAppmeshVirtualNodeExists(resourceName, &vn), - // resource.TestCheckResourceAttr(resourceName, "name", vnName), - // resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), - // testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), - // resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), - // resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "1"), - // resource.TestCheckResourceAttr(resourceName, "spec.0.backend.2622272660.virtual_service.#", "1"), - // resource.TestCheckResourceAttr(resourceName, "spec.0.backend.2622272660.virtual_service.0.virtual_service_name", "servicea.simpleapp.local"), - // resource.TestCheckResourceAttr(resourceName, "spec.0.listener.#", "1"), - // resource.TestCheckResourceAttr(resourceName, "spec.0.listener.3024651324.health_check.#", "0"), - // resource.TestCheckResourceAttr(resourceName, "spec.0.listener.3024651324.port_mapping.#", "1"), - // resource.TestCheckResourceAttr(resourceName, "spec.0.listener.3024651324.port_mapping.0.port", "8080"), - // resource.TestCheckResourceAttr(resourceName, "spec.0.listener.3024651324.port_mapping.0.protocol", "http"), - // resource.TestCheckResourceAttr(resourceName, "spec.0.listener.3024651324.tls.#", "1"), - // resource.TestCheckResourceAttr(resourceName, "spec.0.listener.3024651324.tls.0.certificate.#", "1"), - // resource.TestCheckResourceAttr(resourceName, "spec.0.listener.3024651324.tls.0.certificate.0.acm.#", "0"), - // resource.TestCheckResourceAttr(resourceName, "spec.0.listener.3024651324.tls.0.certificate.0.file.#", "0"), - // resource.TestCheckResourceAttr(resourceName, "spec.0.listener.3024651324.tls.0.certificate.0.sds.#", "1"), - // resource.TestCheckResourceAttr(resourceName, "spec.0.listener.3024651324.tls.0.certificate.0.sds.0.secret_name", "secret"), - // resource.TestCheckResourceAttr(resourceName, "spec.0.listener.3024651324.tls.0.certificate.0.sds.0.source.#", "1"), - // resource.TestCheckResourceAttr(resourceName, "spec.0.listener.3024651324.tls.0.certificate.0.sds.0.source.0.unix_domain_socket.#", "1"), - // resource.TestCheckResourceAttr(resourceName, "spec.0.listener.3024651324.tls.0.certificate.0.sds.0.source.0.unix_domain_socket.0.path", "/sds-server.sock"), - // resource.TestCheckResourceAttr(resourceName, "spec.0.listener.3024651324.tls.0.mode", "DISABLED"), - // resource.TestCheckResourceAttr(resourceName, "spec.0.logging.#", "0"), - // resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.#", "1"), - // resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.#", "1"), - // resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.0.hostname", "serviceb.simpleapp.local"), - // resource.TestCheckResourceAttrSet(resourceName, "created_date"), - // resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), - // testAccCheckResourceAttrAccountID(resourceName, "resource_owner"), - // testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh-preview", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), - // ), - // }, { Config: testAccAppmeshVirtualNodeConfig_tlsAcm(meshName, vnName), Check: resource.ComposeTestCheckFunc( @@ -456,6 +422,7 @@ func testAccAwsAppmeshVirtualNode_tls(t *testing.T) { testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.2622272660.virtual_service.client_policy.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.2622272660.virtual_service.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.2622272660.virtual_service.0.virtual_service_name", "servicea.simpleapp.local"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.#", "1"), @@ -480,6 +447,113 @@ func testAccAwsAppmeshVirtualNode_tls(t *testing.T) { }) } +func testAccAwsAppmeshVirtualNode_clientPolicyFile(t *testing.T) { + var vn appmesh.VirtualNodeData + resourceName := "aws_appmesh_virtual_node.test" + meshName := acctest.RandomWithPrefix("tf-acc-test") + vnName := acctest.RandomWithPrefix("tf-acc-test") + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAppmeshVirtualNodeDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAppmeshVirtualNodeConfig_clientPolicyFile(meshName, vnName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAppmeshVirtualNodeExists(resourceName, &vn), + resource.TestCheckResourceAttr(resourceName, "name", vnName), + resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), + testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), + resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.906924271.virtual_service.0.client_policy.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.906924271.virtual_service.0.client_policy.0.tls.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.906924271.virtual_service.0.client_policy.0.tls.0.enforce", "true"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.906924271.virtual_service.0.client_policy.0.tls.0.ports.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.906924271.virtual_service.0.client_policy.0.tls.0.ports.860082431", "8443"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.906924271.virtual_service.0.client_policy.0.tls.0.validation.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.906924271.virtual_service.0.client_policy.0.tls.0.validation.0.trust.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.906924271.virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.acm.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.906924271.virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.file.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.906924271.virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.file.0.certificate_chain", "/cert_chain.pem"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.906924271.virtual_service.0.virtual_service_name", "servicea.simpleapp.local"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.health_check.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.port_mapping.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.port_mapping.0.port", "8080"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.port_mapping.0.protocol", "http"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.tls.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.logging.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.0.hostname", "serviceb.simpleapp.local"), + resource.TestCheckResourceAttrSet(resourceName, "created_date"), + resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), + testAccCheckResourceAttrAccountID(resourceName, "resource_owner"), + testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh-preview", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), + ), + }, + { + ResourceName: resourceName, + ImportStateId: fmt.Sprintf("%s/%s", meshName, vnName), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccAwsAppmeshVirtualNode_clientPolicyAcm(t *testing.T) { + var vn appmesh.VirtualNodeData + resourceName := "aws_appmesh_virtual_node.test" + acmCAResourceName := "aws_acmpca_certificate_authority.cert" + meshName := acctest.RandomWithPrefix("tf-acc-test") + vnName := acctest.RandomWithPrefix("tf-acc-test") + + t.Skip("Requires an active ACM PCA") + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAppmeshVirtualNodeDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAppmeshVirtualNodeConfig_clientPolicyAcm(meshName, vnName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAppmeshVirtualNodeExists(resourceName, &vn), + resource.TestCheckResourceAttr(resourceName, "name", vnName), + resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), + testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), + resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "1"), + testAccCheckAppmeshVirtualNodeClientPolicyAcmCertificateAuthorityArn(acmCAResourceName, "arn", &vn), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.health_check.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.port_mapping.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.port_mapping.0.port", "8080"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.port_mapping.0.protocol", "http"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.tls.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.logging.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.0.hostname", "serviceb.simpleapp.local"), + resource.TestCheckResourceAttrSet(resourceName, "created_date"), + resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), + testAccCheckResourceAttrAccountID(resourceName, "resource_owner"), + testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh-preview", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), + ), + }, + { + ResourceName: resourceName, + ImportStateId: fmt.Sprintf("%s/%s", meshName, vnName), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testAccCheckAppmeshVirtualNodeDestroy(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).appmeshconn @@ -530,7 +604,33 @@ func testAccCheckAppmeshVirtualNodeExists(name string, v *appmesh.VirtualNodeDat } } -// testAccCheckAppmeshVirtualNodeTlsAcmCertificateArn(acmCertificateResourceName, "arn", &vn), +func testAccCheckAppmeshVirtualNodeClientPolicyAcmCertificateAuthorityArn(name, key string, v *appmesh.VirtualNodeData) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + expected, ok := rs.Primary.Attributes[key] + if !ok { + return fmt.Errorf("Key not found: %s", key) + } + if v.Spec == nil || len(v.Spec.Backends) != 1 || v.Spec.Backends[0].VirtualService == nil || + v.Spec.Backends[0].VirtualService.ClientPolicy == nil || v.Spec.Backends[0].VirtualService.ClientPolicy.Tls == nil || + v.Spec.Backends[0].VirtualService.ClientPolicy.Tls.Validation == nil || v.Spec.Backends[0].VirtualService.ClientPolicy.Tls.Validation.Trust == nil || + v.Spec.Backends[0].VirtualService.ClientPolicy.Tls.Validation.Trust.Acm == nil || + len(v.Spec.Backends[0].VirtualService.ClientPolicy.Tls.Validation.Trust.Acm.CertificateAuthorityArns) != 1 { + return fmt.Errorf("Not found: .Spec.Backends[0].VirtualService.ClientPolicy.Tls.Validation.Trust.Acm.CertificateAuthorityArns[0]") + } + got := aws.StringValue(v.Spec.Backends[0].VirtualService.ClientPolicy.Tls.Validation.Trust.Acm.CertificateAuthorityArns[0]) + if got != expected { + return fmt.Errorf("Expected ACM CA ARN %q, got %q", expected, got) + } + + return nil + } +} + func testAccCheckAppmeshVirtualNodeTlsAcmCertificateArn(name, key string, v *appmesh.VirtualNodeData) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[name] @@ -792,8 +892,8 @@ resource "aws_appmesh_virtual_node" "test" { `, vnName) } -func testAccAppmeshVirtualNodeConfig_tlsSds(meshName, vnName string) string { - return testAccAppmeshVirtualNodeConfig_mesh(meshName) + fmt.Sprintf(` +func testAccAppmeshVirtualNodeConfig_tlsAcm(meshName, vnName string) string { + return testAccAcmCertificateConfig_privateCert(meshName) + testAccAppmeshVirtualNodeConfig_mesh(meshName) + fmt.Sprintf(` resource "aws_appmesh_virtual_node" "test" { name = %[1]q mesh_name = "${aws_appmesh_mesh.test.id}" @@ -813,18 +913,12 @@ resource "aws_appmesh_virtual_node" "test" { tls { certificate { - sds { - secret_name = "secret" - - source { - unix_domain_socket { - path = "/sds-server.sock" - } - } + acm { + certificate_arn = "${aws_acm_certificate.cert.arn}" } } - mode = "DISABLED" + mode = "STRICT" } } @@ -838,8 +932,8 @@ resource "aws_appmesh_virtual_node" "test" { `, vnName) } -func testAccAppmeshVirtualNodeConfig_tlsAcm(meshName, vnName string) string { - return testAccAcmCertificateConfig_privateCert(meshName) + testAccAppmeshVirtualNodeConfig_mesh(meshName) + fmt.Sprintf(` +func testAccAppmeshVirtualNodeConfig_clientPolicyFile(meshName, vnName string) string { + return testAccAppmeshVirtualNodeConfig_mesh(meshName) + fmt.Sprintf(` resource "aws_appmesh_virtual_node" "test" { name = %[1]q mesh_name = "${aws_appmesh_mesh.test.id}" @@ -848,6 +942,20 @@ resource "aws_appmesh_virtual_node" "test" { backend { virtual_service { virtual_service_name = "servicea.simpleapp.local" + + client_policy { + tls { + ports = [8443] + + validation { + trust { + file { + certificate_chain = "/cert_chain.pem" + } + } + } + } + } } } @@ -856,15 +964,49 @@ resource "aws_appmesh_virtual_node" "test" { port = 8080 protocol = "http" } + } - tls { - certificate { - acm { - certificate_arn = "${aws_acm_certificate.cert.arn}" + service_discovery { + dns { + hostname = "serviceb.simpleapp.local" + } + } + } +} +`, vnName) +} + +func testAccAppmeshVirtualNodeConfig_clientPolicyAcm(meshName, vnName string) string { + return testAccAcmCertificateConfig_privateCert(meshName) + testAccAppmeshVirtualNodeConfig_mesh(meshName) + fmt.Sprintf(` +resource "aws_appmesh_virtual_node" "test" { + name = %[1]q + mesh_name = "${aws_appmesh_mesh.test.id}" + + spec { + backend { + virtual_service { + virtual_service_name = "servicea.simpleapp.local" + + client_policy { + tls { + ports = [443, 8443] + + validation { + trust { + acm { + certificate_authority_arns = ["${aws_acm_certificate.cert.arn}"] + } + } + } } } + } + } - mode = "STRICT" + listener { + port_mapping { + port = 8080 + protocol = "http" } } diff --git a/aws/structure.go b/aws/structure.go index fff1af7eb0e..a86b408935f 100644 --- a/aws/structure.go +++ b/aws/structure.go @@ -1072,6 +1072,21 @@ func flattenCaseInsensitiveStringSet(list []*string) *schema.Set { return schema.NewSet(hashStringCaseInsensitive, flattenStringList(list)) } +// Takes list of pointers to int64s. Expand to an array +// of raw ints and returns a []interface{} +// to keep compatibility w/ schema.NewSet +func flattenIntList(list []*int64) []interface{} { + vs := make([]interface{}, 0, len(list)) + for _, v := range list { + vs = append(vs, int(aws.Int64Value(v))) + } + return vs +} + +func flattenIntSet(list []*int64) *schema.Set { + return schema.NewSet(schema.HashInt, flattenIntList(list)) +} + //Flattens an array of private ip addresses into a []string, where the elements returned are the IP strings e.g. "192.168.0.0" func flattenNetworkInterfacesPrivateIPAddresses(dtos []*ec2.NetworkInterfacePrivateIpAddress) []string { ips := make([]string, 0, len(dtos)) @@ -4747,6 +4762,70 @@ func expandAppmeshVirtualNodeSpec(vSpec []interface{}) *appmesh.VirtualNodeSpec virtualService.VirtualServiceName = aws.String(vVirtualServiceName) } + if vClientPolicy, ok := mVirtualService["client_policy"].([]interface{}); ok && len(vClientPolicy) > 0 && vClientPolicy[0] != nil { + clientPolicy := &appmesh.ClientPolicy{} + + mClientPolicy := vClientPolicy[0].(map[string]interface{}) + + if vTls, ok := mClientPolicy["tls"].([]interface{}); ok && len(vTls) > 0 && vTls[0] != nil { + tls := &appmesh.ClientPolicyTls{} + + mTls := vTls[0].(map[string]interface{}) + + if vEnforce, ok := mTls["enforce"].(bool); ok { + tls.Enforce = aws.Bool(vEnforce) + } + + if vPorts, ok := mTls["ports"].(*schema.Set); ok && vPorts.Len() > 0 { + tls.Ports = expandInt64Set(vPorts) + } + + if vValidation, ok := mTls["validation"].([]interface{}); ok && len(vValidation) > 0 && vValidation[0] != nil { + validation := &appmesh.TlsValidationContext{} + + mValidation := vValidation[0].(map[string]interface{}) + + if vTrust, ok := mValidation["trust"].([]interface{}); ok && len(vTrust) > 0 && vTrust[0] != nil { + trust := &appmesh.TlsValidationContextTrust{} + + mTrust := vTrust[0].(map[string]interface{}) + + if vAcm, ok := mTrust["acm"].([]interface{}); ok && len(vAcm) > 0 && vAcm[0] != nil { + acm := &appmesh.TlsValidationContextAcmTrust{} + + mAcm := vAcm[0].(map[string]interface{}) + + if vCertificateAuthorityArns, ok := mAcm["certificate_authority_arns"].(*schema.Set); ok && vCertificateAuthorityArns.Len() > 0 { + acm.CertificateAuthorityArns = expandStringSet(vCertificateAuthorityArns) + } + + trust.Acm = acm + } + + if vFile, ok := mTrust["file"].([]interface{}); ok && len(vFile) > 0 && vFile[0] != nil { + file := &appmesh.TlsValidationContextFileTrust{} + + mFile := vFile[0].(map[string]interface{}) + + if vCertificateChain, ok := mFile["certificate_chain"].(string); ok && vCertificateChain != "" { + file.CertificateChain = aws.String(vCertificateChain) + } + + trust.File = file + } + + validation.Trust = trust + } + + tls.Validation = validation + } + + clientPolicy.Tls = tls + } + + virtualService.ClientPolicy = clientPolicy + } + backend.VirtualService = virtualService } @@ -4958,6 +5037,49 @@ func flattenAppmeshVirtualNodeSpec(spec *appmesh.VirtualNodeSpec) []interface{} "virtual_service_name": aws.StringValue(virtualService.VirtualServiceName), } + if clientPolicy := virtualService.ClientPolicy; clientPolicy != nil { + mClientPolicy := map[string]interface{}{} + + if tls := clientPolicy.Tls; tls != nil { + mTls := map[string]interface{}{ + "enforce": aws.BoolValue(tls.Enforce), + "ports": flattenIntSet(tls.Ports), + } + + if validation := tls.Validation; validation != nil { + mValidation := map[string]interface{}{} + + if trust := validation.Trust; trust != nil { + mTrust := map[string]interface{}{} + + if acm := trust.Acm; acm != nil { + mAcm := map[string]interface{}{ + "certificate_authority_arns": flattenStringSet(acm.CertificateAuthorityArns), + } + + mTrust["acm"] = []interface{}{mAcm} + } + + if file := trust.File; file != nil { + mFile := map[string]interface{}{ + "certificate_chain": aws.StringValue(file.CertificateChain), + } + + mTrust["file"] = []interface{}{mFile} + } + + mValidation["trust"] = []interface{}{mTrust} + } + + mTls["validation"] = []interface{}{mValidation} + } + + mClientPolicy["tls"] = []interface{}{mTls} + } + + mVirtualService["client_policy"] = []interface{}{mClientPolicy} + } + mBackend["virtual_service"] = []interface{}{mVirtualService} } diff --git a/website/docs/r/appmesh_virtual_node.html.markdown b/website/docs/r/appmesh_virtual_node.html.markdown index 028f6f23cf1..a51e28e2c1e 100644 --- a/website/docs/r/appmesh_virtual_node.html.markdown +++ b/website/docs/r/appmesh_virtual_node.html.markdown @@ -192,8 +192,36 @@ The `backend` object supports the following: The `virtual_service` object supports the following: +* `client_policy` - (Optional) The client policy for the backend. * `virtual_service_name` - (Required) The name of the virtual service that is acting as a virtual node backend. +The `client_policy` object supports the following: + +* `tls` - (Optional) The Transport Layer Security (TLS) client policy. + +The `tls` object supports the following: + +* `enforced` - (Optional) Whether the policy is enforced. Default is `true`. +* `ports` - (Optional) One or more ports that the policy is enforced for. +* `validation` - (Required) The TLS validation context. + +The `validation` object supports the following: + +* `trust` - (Required) The TLS validation context trust. + +The `trust` object supports the following: + +* `acm` - (Optional) The TLS validation context trust for an AWS Certicate Manager (ACM) certificate. +* `file` - (Optional) The TLS validation context trust for a local file. + +The `acm` object supports the following: + +* `certificate_authority_arns` - (Required) One or more ACM Amazon Resource Name (ARN)s. + +The `file` object supports the following: + +* `certificate_chain` - (Required) The certificate trust chain for a certificate stored on the file system of the virtual node that the proxy is running on. + The `listener` object supports the following: * `port_mapping` - (Required) The port mapping information for the listener. From f8b7e3758e05a1c83dd5d2487afe42ca2ab2d019 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 24 Mar 2020 15:38:38 -0400 Subject: [PATCH 04/21] r/aws_appmesh_virtual_node: Test backend.virtual_service.client_policy...file attribute. Acceptance testing output: $ make testacc TEST=./aws TESTARGS='-run=TestAccAWSAppmesh/VirtualNode/clientPolicyFile' ==> Checking that code complies with gofmt requirements... GO111MODULE=off TF_ACC=1 go test ./aws -v -count 1 -parallel 20 -run=TestAccAWSAppmesh/VirtualNode/clientPolicyFile -timeout 120m === RUN TestAccAWSAppmesh === RUN TestAccAWSAppmesh/VirtualNode === RUN TestAccAWSAppmesh/VirtualNode/clientPolicyFile --- PASS: TestAccAWSAppmesh (41.99s) --- PASS: TestAccAWSAppmesh/VirtualNode (41.99s) --- PASS: TestAccAWSAppmesh/VirtualNode/clientPolicyFile (41.99s) PASS ok github.com/terraform-providers/terraform-provider-aws/aws 42.027s --- aws/resource_aws_appmesh_test.go | 2 + aws/resource_aws_appmesh_virtual_node_test.go | 82 +++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/aws/resource_aws_appmesh_test.go b/aws/resource_aws_appmesh_test.go index e43b26b7784..0a4f642fd36 100644 --- a/aws/resource_aws_appmesh_test.go +++ b/aws/resource_aws_appmesh_test.go @@ -21,6 +21,8 @@ func TestAccAWSAppmesh_serial(t *testing.T) { }, "VirtualNode": { "basic": testAccAwsAppmeshVirtualNode_basic, + "clientPolicyAcm": testAccAwsAppmeshVirtualNode_clientPolicyAcm, + "clientPolicyFile": testAccAwsAppmeshVirtualNode_clientPolicyFile, "cloudMapServiceDiscovery": testAccAwsAppmeshVirtualNode_cloudMapServiceDiscovery, "listenerHealthChecks": testAccAwsAppmeshVirtualNode_listenerHealthChecks, "logging": testAccAwsAppmeshVirtualNode_logging, diff --git a/aws/resource_aws_appmesh_virtual_node_test.go b/aws/resource_aws_appmesh_virtual_node_test.go index 52461da140d..0d5780151f8 100644 --- a/aws/resource_aws_appmesh_virtual_node_test.go +++ b/aws/resource_aws_appmesh_virtual_node_test.go @@ -544,6 +544,44 @@ func testAccAwsAppmeshVirtualNode_clientPolicyAcm(t *testing.T) { testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh-preview", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), ), }, + { + Config: testAccAppmeshVirtualNodeConfig_clientPolicyFileUpdated(meshName, vnName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAppmeshVirtualNodeExists(resourceName, &vn), + resource.TestCheckResourceAttr(resourceName, "name", vnName), + resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), + testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), + resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.enforce", "true"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.ports.#", "2"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.ports.3638101695", "443"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.ports.860082431", "8443"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.validation.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.validation.0.trust.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.acm.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.file.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.file.0.certificate_chain", "/etc/ssl/certs/cert_chain.pem"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.sds.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.virtual_service_name", "servicea.simpleapp.local"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.health_check.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.port_mapping.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.port_mapping.0.port", "8080"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.port_mapping.0.protocol", "http"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.tls.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.logging.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.0.hostname", "serviceb.simpleapp.local"), + resource.TestCheckResourceAttrSet(resourceName, "created_date"), + resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), + testAccCheckResourceAttrAccountID(resourceName, "resource_owner"), + testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh-preview", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), + ), + }, { ResourceName: resourceName, ImportStateId: fmt.Sprintf("%s/%s", meshName, vnName), @@ -976,6 +1014,50 @@ resource "aws_appmesh_virtual_node" "test" { `, vnName) } +func testAccAppmeshVirtualNodeConfig_clientPolicyFileUpdated(meshName, vnName string) string { + return testAccAppmeshVirtualNodeConfig_mesh(meshName) + fmt.Sprintf(` +resource "aws_appmesh_virtual_node" "test" { + name = %[1]q + mesh_name = "${aws_appmesh_mesh.test.id}" + + spec { + backend { + virtual_service { + virtual_service_name = "servicea.simpleapp.local" + + client_policy { + tls { + ports = [443, 8443] + + validation { + trust { + file { + certificate_chain = "/etc/ssl/certs/cert_chain.pem" + } + } + } + } + } + } + } + + listener { + port_mapping { + port = 8080 + protocol = "http" + } + } + + service_discovery { + dns { + hostname = "serviceb.simpleapp.local" + } + } + } +} +`, vnName) +} + func testAccAppmeshVirtualNodeConfig_clientPolicyAcm(meshName, vnName string) string { return testAccAcmCertificateConfig_privateCert(meshName) + testAccAppmeshVirtualNodeConfig_mesh(meshName) + fmt.Sprintf(` resource "aws_appmesh_virtual_node" "test" { From 9c8df8bc2f470c726548c15cb9b21967dcbdf107 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Tue, 24 Mar 2020 17:08:14 -0400 Subject: [PATCH 05/21] r/aws_appmesh_virtual_node: Test backend.virtual_service.client_policy...acm attribute. Acceptance test output: $ make testacc TEST=./aws TESTARGS='-run=TestAccAWSAppmesh/VirtualNode/clientPolicyAcm' ==> Checking that code complies with gofmt requirements... GO111MODULE=off TF_ACC=1 go test ./aws -v -count 1 -parallel 20 -run=TestAccAWSAppmesh/VirtualNode/clientPolicyAcm -timeout 120m === RUN TestAccAWSAppmesh === RUN TestAccAWSAppmesh/VirtualNode === RUN TestAccAWSAppmesh/VirtualNode/clientPolicyAcm --- PASS: TestAccAWSAppmesh (68.09s) --- PASS: TestAccAWSAppmesh/VirtualNode (68.09s) --- PASS: TestAccAWSAppmesh/VirtualNode/clientPolicyAcm (68.09s) PASS ok github.com/terraform-providers/terraform-provider-aws/aws 68.124s --- aws/resource_aws_appmesh_virtual_node_test.go | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/aws/resource_aws_appmesh_virtual_node_test.go b/aws/resource_aws_appmesh_virtual_node_test.go index 0d5780151f8..872d0453cbc 100644 --- a/aws/resource_aws_appmesh_virtual_node_test.go +++ b/aws/resource_aws_appmesh_virtual_node_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/acmpca" "github.com/aws/aws-sdk-go/service/appmesh" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" @@ -506,18 +507,24 @@ func testAccAwsAppmeshVirtualNode_clientPolicyFile(t *testing.T) { func testAccAwsAppmeshVirtualNode_clientPolicyAcm(t *testing.T) { var vn appmesh.VirtualNodeData + var ca acmpca.CertificateAuthority resourceName := "aws_appmesh_virtual_node.test" - acmCAResourceName := "aws_acmpca_certificate_authority.cert" + acmCAResourceName := "aws_acmpca_certificate_authority.test" meshName := acctest.RandomWithPrefix("tf-acc-test") vnName := acctest.RandomWithPrefix("tf-acc-test") - t.Skip("Requires an active ACM PCA") - resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccCheckAppmeshVirtualNodeDestroy, Steps: []resource.TestStep{ + { + Config: testAccAwsAcmpcaCertificateAuthorityConfigType(meshName, acmpca.CertificateAuthorityTypeRoot), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsAcmpcaCertificateAuthorityExists(acmCAResourceName, &ca), + testAccCheckAwsAcmpcaCertificateAuthorityActivateCA(&ca), + ), + }, { Config: testAccAppmeshVirtualNodeConfig_clientPolicyAcm(meshName, vnName), Check: resource.ComposeTestCheckFunc( @@ -582,6 +589,14 @@ func testAccAwsAppmeshVirtualNode_clientPolicyAcm(t *testing.T) { testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh-preview", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), ), }, + { + Config: testAccAppmeshVirtualNodeConfig_clientPolicyAcm(meshName, vnName), + Check: resource.ComposeTestCheckFunc( + // CA must be DISABLED for deletion. + testAccCheckAwsAcmpcaCertificateAuthorityDisableCA(&ca), + ), + ExpectNonEmptyPlan: true, + }, { ResourceName: resourceName, ImportStateId: fmt.Sprintf("%s/%s", meshName, vnName), @@ -1059,7 +1074,7 @@ resource "aws_appmesh_virtual_node" "test" { } func testAccAppmeshVirtualNodeConfig_clientPolicyAcm(meshName, vnName string) string { - return testAccAcmCertificateConfig_privateCert(meshName) + testAccAppmeshVirtualNodeConfig_mesh(meshName) + fmt.Sprintf(` + return testAccAwsAcmpcaCertificateAuthorityConfigType(meshName, acmpca.CertificateAuthorityTypeRoot) + testAccAppmeshVirtualNodeConfig_mesh(meshName) + fmt.Sprintf(` resource "aws_appmesh_virtual_node" "test" { name = %[1]q mesh_name = "${aws_appmesh_mesh.test.id}" @@ -1071,12 +1086,12 @@ resource "aws_appmesh_virtual_node" "test" { client_policy { tls { - ports = [443, 8443] + ports = [8443] validation { trust { acm { - certificate_authority_arns = ["${aws_acm_certificate.cert.arn}"] + certificate_authority_arns = ["${aws_acmpca_certificate_authority.test.arn}"] } } } From bd908b57dfc2685aac7f91d9437d70f4dcde52c2 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 25 Mar 2020 16:16:02 -0400 Subject: [PATCH 06/21] r/aws_appmesh_virtual_node: Add spec.backend_defaults attribute. Acceptance test output: $ make testacc TEST=./aws TESTARGS='-run=TestAccAWSAppmesh/VirtualNode/clientPolicyFile' ==> Checking that code complies with gofmt requirements... GO111MODULE=off TF_ACC=1 go test ./aws -v -count 1 -parallel 20 -run=TestAccAWSAppmesh/VirtualNode/clientPolicyFile -timeout 120m === RUN TestAccAWSAppmesh === RUN TestAccAWSAppmesh/VirtualNode === RUN TestAccAWSAppmesh/VirtualNode/clientPolicyFile --- PASS: TestAccAWSAppmesh (42.17s) --- PASS: TestAccAWSAppmesh/VirtualNode (42.17s) --- PASS: TestAccAWSAppmesh/VirtualNode/clientPolicyFile (42.17s) PASS ok github.com/terraform-providers/terraform-provider-aws/aws 42.221s --- aws/resource_aws_appmesh_virtual_node.go | 228 +++++++++----- aws/structure.go | 295 +++++++++++------- .../docs/r/appmesh_virtual_node.html.markdown | 5 + 3 files changed, 338 insertions(+), 190 deletions(-) diff --git a/aws/resource_aws_appmesh_virtual_node.go b/aws/resource_aws_appmesh_virtual_node.go index 2aaf61491d1..38871bd948c 100644 --- a/aws/resource_aws_appmesh_virtual_node.go +++ b/aws/resource_aws_appmesh_virtual_node.go @@ -78,91 +78,7 @@ func resourceAwsAppmeshVirtualNode() *schema.Resource { ValidateFunc: validation.StringLenBetween(1, 255), }, - "client_policy": { - Type: schema.TypeList, - Optional: true, - MinItems: 0, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "tls": { - Type: schema.TypeList, - Optional: true, - MinItems: 0, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enforce": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - - "ports": { - Type: schema.TypeSet, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeInt}, - Set: schema.HashInt, - }, - - "validation": { - Type: schema.TypeList, - Required: true, - MinItems: 1, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "trust": { - Type: schema.TypeList, - Required: true, - MinItems: 1, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "acm": { - Type: schema.TypeList, - Optional: true, - MinItems: 0, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "certificate_authority_arns": { - Type: schema.TypeSet, - Required: true, - Elem: &schema.Schema{Type: schema.TypeString}, - Set: schema.HashString, - }, - }, - }, - }, - - "file": { - Type: schema.TypeList, - Optional: true, - MinItems: 0, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "certificate_chain": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validation.StringLenBetween(1, 255), - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, - }, + "client_policy": appmeshVirtualNodeClientPolicySchema(), }, }, }, @@ -171,6 +87,18 @@ func resourceAwsAppmeshVirtualNode() *schema.Resource { Set: appmeshVirtualNodeBackendHash, }, + "backend_defaults": { + Type: schema.TypeList, + Optional: true, + MinItems: 0, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "client_policy": appmeshVirtualNodeClientPolicySchema(), + }, + }, + }, + "listener": { Type: schema.TypeList, Optional: true, @@ -449,6 +377,136 @@ func resourceAwsAppmeshVirtualNode() *schema.Resource { } } +// appmeshVirtualNodeClientPolicySchema returns the schema for `client_policy` attributes. +func appmeshVirtualNodeClientPolicySchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Optional: true, + MinItems: 0, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "tls": { + Type: schema.TypeList, + Optional: true, + MinItems: 0, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enforce": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + + "ports": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeInt}, + Set: schema.HashInt, + }, + + "validation": { + Type: schema.TypeList, + Required: true, + MinItems: 1, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "trust": { + Type: schema.TypeList, + Required: true, + MinItems: 1, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "acm": { + Type: schema.TypeList, + Optional: true, + MinItems: 0, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "certificate_authority_arns": { + Type: schema.TypeSet, + Required: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: schema.HashString, + }, + }, + }, + }, + + "file": { + Type: schema.TypeList, + Optional: true, + MinItems: 0, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "certificate_chain": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringLenBetween(1, 255), + }, + }, + }, + }, + + // "sds": { + // Type: schema.TypeList, + // Optional: true, + // MinItems: 0, + // MaxItems: 1, + // Elem: &schema.Resource{ + // Schema: map[string]*schema.Schema{ + // "secret_name": { + // Type: schema.TypeString, + // Required: true, + // ValidateFunc: validation.StringLenBetween(1, 255), + // }, + + // "source": { + // Type: schema.TypeList, + // Required: true, + // MinItems: 1, + // MaxItems: 1, + // Elem: &schema.Resource{ + // Schema: map[string]*schema.Schema{ + // "unix_domain_socket": { + // Type: schema.TypeList, + // Required: true, + // MinItems: 1, + // MaxItems: 1, + // Elem: &schema.Resource{ + // Schema: map[string]*schema.Schema{ + // "path": { + // Type: schema.TypeString, + // Required: true, + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } +} + func resourceAwsAppmeshVirtualNodeCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).appmeshconn diff --git a/aws/structure.go b/aws/structure.go index a86b408935f..d270048abfe 100644 --- a/aws/structure.go +++ b/aws/structure.go @@ -4762,68 +4762,8 @@ func expandAppmeshVirtualNodeSpec(vSpec []interface{}) *appmesh.VirtualNodeSpec virtualService.VirtualServiceName = aws.String(vVirtualServiceName) } - if vClientPolicy, ok := mVirtualService["client_policy"].([]interface{}); ok && len(vClientPolicy) > 0 && vClientPolicy[0] != nil { - clientPolicy := &appmesh.ClientPolicy{} - - mClientPolicy := vClientPolicy[0].(map[string]interface{}) - - if vTls, ok := mClientPolicy["tls"].([]interface{}); ok && len(vTls) > 0 && vTls[0] != nil { - tls := &appmesh.ClientPolicyTls{} - - mTls := vTls[0].(map[string]interface{}) - - if vEnforce, ok := mTls["enforce"].(bool); ok { - tls.Enforce = aws.Bool(vEnforce) - } - - if vPorts, ok := mTls["ports"].(*schema.Set); ok && vPorts.Len() > 0 { - tls.Ports = expandInt64Set(vPorts) - } - - if vValidation, ok := mTls["validation"].([]interface{}); ok && len(vValidation) > 0 && vValidation[0] != nil { - validation := &appmesh.TlsValidationContext{} - - mValidation := vValidation[0].(map[string]interface{}) - - if vTrust, ok := mValidation["trust"].([]interface{}); ok && len(vTrust) > 0 && vTrust[0] != nil { - trust := &appmesh.TlsValidationContextTrust{} - - mTrust := vTrust[0].(map[string]interface{}) - - if vAcm, ok := mTrust["acm"].([]interface{}); ok && len(vAcm) > 0 && vAcm[0] != nil { - acm := &appmesh.TlsValidationContextAcmTrust{} - - mAcm := vAcm[0].(map[string]interface{}) - - if vCertificateAuthorityArns, ok := mAcm["certificate_authority_arns"].(*schema.Set); ok && vCertificateAuthorityArns.Len() > 0 { - acm.CertificateAuthorityArns = expandStringSet(vCertificateAuthorityArns) - } - - trust.Acm = acm - } - - if vFile, ok := mTrust["file"].([]interface{}); ok && len(vFile) > 0 && vFile[0] != nil { - file := &appmesh.TlsValidationContextFileTrust{} - - mFile := vFile[0].(map[string]interface{}) - - if vCertificateChain, ok := mFile["certificate_chain"].(string); ok && vCertificateChain != "" { - file.CertificateChain = aws.String(vCertificateChain) - } - - trust.File = file - } - - validation.Trust = trust - } - - tls.Validation = validation - } - - clientPolicy.Tls = tls - } - - virtualService.ClientPolicy = clientPolicy + if vClientPolicy, ok := mVirtualService["client_policy"].([]interface{}); ok { + virtualService.ClientPolicy = expandAppmeshClientPolicy(vClientPolicy) } backend.VirtualService = virtualService @@ -4835,6 +4775,18 @@ func expandAppmeshVirtualNodeSpec(vSpec []interface{}) *appmesh.VirtualNodeSpec spec.Backends = backends } + if vBackendDefaults, ok := mSpec["backend_defaults"].([]interface{}); ok && len(vBackendDefaults) > 0 && vBackendDefaults[0] != nil { + backendDefaults := &appmesh.BackendDefaults{} + + mBackendDefaults := vBackendDefaults[0].(map[string]interface{}) + + if vClientPolicy, ok := mBackendDefaults["client_policy"].([]interface{}); ok { + backendDefaults.ClientPolicy = expandAppmeshClientPolicy(vClientPolicy) + } + + spec.BackendDefaults = backendDefaults + } + if vListeners, ok := mSpec["listener"].([]interface{}); ok && len(vListeners) > 0 && vListeners[0] != nil { listeners := []*appmesh.Listener{} @@ -5034,52 +4986,10 @@ func flattenAppmeshVirtualNodeSpec(spec *appmesh.VirtualNodeSpec) []interface{} if virtualService := backend.VirtualService; virtualService != nil { mVirtualService := map[string]interface{}{ + "client_policy": flattenAppmeshClientPolicy(virtualService.ClientPolicy), "virtual_service_name": aws.StringValue(virtualService.VirtualServiceName), } - if clientPolicy := virtualService.ClientPolicy; clientPolicy != nil { - mClientPolicy := map[string]interface{}{} - - if tls := clientPolicy.Tls; tls != nil { - mTls := map[string]interface{}{ - "enforce": aws.BoolValue(tls.Enforce), - "ports": flattenIntSet(tls.Ports), - } - - if validation := tls.Validation; validation != nil { - mValidation := map[string]interface{}{} - - if trust := validation.Trust; trust != nil { - mTrust := map[string]interface{}{} - - if acm := trust.Acm; acm != nil { - mAcm := map[string]interface{}{ - "certificate_authority_arns": flattenStringSet(acm.CertificateAuthorityArns), - } - - mTrust["acm"] = []interface{}{mAcm} - } - - if file := trust.File; file != nil { - mFile := map[string]interface{}{ - "certificate_chain": aws.StringValue(file.CertificateChain), - } - - mTrust["file"] = []interface{}{mFile} - } - - mValidation["trust"] = []interface{}{mTrust} - } - - mTls["validation"] = []interface{}{mValidation} - } - - mClientPolicy["tls"] = []interface{}{mTls} - } - - mVirtualService["client_policy"] = []interface{}{mClientPolicy} - } - mBackend["virtual_service"] = []interface{}{mVirtualService} } @@ -5089,6 +4999,14 @@ func flattenAppmeshVirtualNodeSpec(spec *appmesh.VirtualNodeSpec) []interface{} mSpec["backend"] = schema.NewSet(appmeshVirtualNodeBackendHash, vBackends) } + if backendDefaults := spec.BackendDefaults; backendDefaults != nil { + mBackendDefaults := map[string]interface{}{ + "client_policy": flattenAppmeshClientPolicy(backendDefaults.ClientPolicy), + } + + mSpec["backend_defaults"] = []interface{}{mBackendDefaults} + } + if spec.Listeners != nil && spec.Listeners[0] != nil { // Per schema definition, set at most 1 Listener listener := spec.Listeners[0] @@ -5202,6 +5120,173 @@ func flattenAppmeshVirtualNodeSpec(spec *appmesh.VirtualNodeSpec) []interface{} return []interface{}{mSpec} } +func expandAppmeshClientPolicy(vClientPolicy []interface{}) *appmesh.ClientPolicy { + if len(vClientPolicy) == 0 || vClientPolicy[0] == nil { + return nil + } + + clientPolicy := &appmesh.ClientPolicy{} + + mClientPolicy := vClientPolicy[0].(map[string]interface{}) + + if vTls, ok := mClientPolicy["tls"].([]interface{}); ok && len(vTls) > 0 && vTls[0] != nil { + tls := &appmesh.ClientPolicyTls{} + + mTls := vTls[0].(map[string]interface{}) + + if vEnforce, ok := mTls["enforce"].(bool); ok { + tls.Enforce = aws.Bool(vEnforce) + } + + if vPorts, ok := mTls["ports"].(*schema.Set); ok && vPorts.Len() > 0 { + tls.Ports = expandInt64Set(vPorts) + } + + if vValidation, ok := mTls["validation"].([]interface{}); ok && len(vValidation) > 0 && vValidation[0] != nil { + validation := &appmesh.TlsValidationContext{} + + mValidation := vValidation[0].(map[string]interface{}) + + if vTrust, ok := mValidation["trust"].([]interface{}); ok && len(vTrust) > 0 && vTrust[0] != nil { + trust := &appmesh.TlsValidationContextTrust{} + + mTrust := vTrust[0].(map[string]interface{}) + + if vAcm, ok := mTrust["acm"].([]interface{}); ok && len(vAcm) > 0 && vAcm[0] != nil { + acm := &appmesh.TlsValidationContextAcmTrust{} + + mAcm := vAcm[0].(map[string]interface{}) + + if vCertificateAuthorityArns, ok := mAcm["certificate_authority_arns"].(*schema.Set); ok && vCertificateAuthorityArns.Len() > 0 { + acm.CertificateAuthorityArns = expandStringSet(vCertificateAuthorityArns) + } + + trust.Acm = acm + } + + if vFile, ok := mTrust["file"].([]interface{}); ok && len(vFile) > 0 && vFile[0] != nil { + file := &appmesh.TlsValidationContextFileTrust{} + + mFile := vFile[0].(map[string]interface{}) + + if vCertificateChain, ok := mFile["certificate_chain"].(string); ok && vCertificateChain != "" { + file.CertificateChain = aws.String(vCertificateChain) + } + + trust.File = file + } + + // if vSds, ok := mTrust["sds"].([]interface{}); ok && len(vSds) > 0 && vSds[0] != nil { + // sds := &appmesh.TlsValidationContextSdsTrust{} + + // mSds := vSds[0].(map[string]interface{}) + + // if vSecretName, ok := mSds["secret_name"].(string); ok && vSecretName != "" { + // sds.SecretName = aws.String(vSecretName) + // } + + // if vSource, ok := mSds["source"].([]interface{}); ok && len(vSource) > 0 && vSource[0] != nil { + // source := &appmesh.SdsSource{} + + // mSource := vSource[0].(map[string]interface{}) + + // if vUnixDomainSocket, ok := mSource["unix_domain_socket"].([]interface{}); ok && len(vUnixDomainSocket) > 0 && vUnixDomainSocket[0] != nil { + // unixDomainSocket := &appmesh.SdsUnixDomainSocketSource{} + + // mUnixDomainSocket := vUnixDomainSocket[0].(map[string]interface{}) + + // if vPath, ok := mUnixDomainSocket["path"].(string); ok && vPath != "" { + // unixDomainSocket.Path = aws.String(vPath) + // } + + // source.UnixDomainSocket = unixDomainSocket + // } + // } + + // trust.Sds = sds + // } + + validation.Trust = trust + } + + tls.Validation = validation + } + + clientPolicy.Tls = tls + } + + return clientPolicy +} + +func flattenAppmeshClientPolicy(clientPolicy *appmesh.ClientPolicy) []interface{} { + if clientPolicy == nil { + return []interface{}{} + } + + mClientPolicy := map[string]interface{}{} + + if tls := clientPolicy.Tls; tls != nil { + mTls := map[string]interface{}{ + "enforce": aws.BoolValue(tls.Enforce), + "ports": flattenIntSet(tls.Ports), + } + + if validation := tls.Validation; validation != nil { + mValidation := map[string]interface{}{} + + if trust := validation.Trust; trust != nil { + mTrust := map[string]interface{}{} + + if acm := trust.Acm; acm != nil { + mAcm := map[string]interface{}{ + "certificate_authority_arns": flattenStringSet(acm.CertificateAuthorityArns), + } + + mTrust["acm"] = []interface{}{mAcm} + } + + if file := trust.File; file != nil { + mFile := map[string]interface{}{ + "certificate_chain": aws.StringValue(file.CertificateChain), + } + + mTrust["file"] = []interface{}{mFile} + } + + // if sds := trust.Sds; sds != nil { + // mSds := map[string]interface{}{ + // "secret_name": aws.StringValue(sds.SecretName), + // } + + // if source := sds.Source; source != nil { + // mSource := map[string]interface{}{} + + // if unixDomainSocket := source.UnixDomainSocket; unixDomainSocket != nil { + // mUnixDomainSocket := map[string]interface{}{ + // "path": aws.StringValue(unixDomainSocket.Path), + // } + + // mSource["unix_domain_socket"] = []interface{}{mUnixDomainSocket} + // } + + // mSds["source"] = []interface{}{mSource} + // } + + // mTrust["sds"] = []interface{}{mSds} + // } + + mValidation["trust"] = []interface{}{mTrust} + } + + mTls["validation"] = []interface{}{mValidation} + } + + mClientPolicy["tls"] = []interface{}{mTls} + } + + return []interface{}{mClientPolicy} +} + func expandAppmeshVirtualServiceSpec(vSpec []interface{}) *appmesh.VirtualServiceSpec { spec := &appmesh.VirtualServiceSpec{} diff --git a/website/docs/r/appmesh_virtual_node.html.markdown b/website/docs/r/appmesh_virtual_node.html.markdown index a51e28e2c1e..05bce9fcb26 100644 --- a/website/docs/r/appmesh_virtual_node.html.markdown +++ b/website/docs/r/appmesh_virtual_node.html.markdown @@ -182,6 +182,7 @@ The following arguments are supported: The `spec` object supports the following: * `backend` - (Optional) The backends to which the virtual node is expected to send outbound traffic. +* `backend_defaults` - (Optional) The defaults for backends. * `listener` - (Optional) The listeners from which the virtual node is expected to receive inbound traffic. * `logging` - (Optional) The inbound and outbound access logging information for the virtual node. * `service_discovery` - (Optional) The service discovery information for the virtual node. @@ -222,6 +223,10 @@ The `file` object supports the following: * `certificate_chain` - (Required) The certificate trust chain for a certificate stored on the file system of the virtual node that the proxy is running on. +The `backend_defaults` object supports the following: + +* `client_policy` - (Optional) The default client policy for virtual service backends. See above for details. + The `listener` object supports the following: * `port_mapping` - (Required) The port mapping information for the listener. From 58e438178e8debf0a5aaeadeb1f58e03d6e40610 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 25 Mar 2020 16:40:39 -0400 Subject: [PATCH 07/21] r/aws_appmesh_virtual_node: Test spec.backend_defaults attribute. Acceptance test output: $ make testacc TEST=./aws TESTARGS='-run=TestAccAWSAppmesh/VirtualNode/backendDefaults' ==> Checking that code complies with gofmt requirements... GO111MODULE=off TF_ACC=1 go test ./aws -v -count 1 -parallel 20 -run=TestAccAWSAppmesh/VirtualNode/backendDefaults -timeout 120m === RUN TestAccAWSAppmesh === RUN TestAccAWSAppmesh/VirtualNode === RUN TestAccAWSAppmesh/VirtualNode/backendDefaults --- PASS: TestAccAWSAppmesh (41.99s) --- PASS: TestAccAWSAppmesh/VirtualNode (41.99s) --- PASS: TestAccAWSAppmesh/VirtualNode/backendDefaults (41.99s) PASS ok github.com/terraform-providers/terraform-provider-aws/aws 42.047s --- aws/resource_aws_appmesh_test.go | 1 + aws/resource_aws_appmesh_virtual_node_test.go | 180 ++++++++++++++++++ 2 files changed, 181 insertions(+) diff --git a/aws/resource_aws_appmesh_test.go b/aws/resource_aws_appmesh_test.go index 0a4f642fd36..2a6563acafe 100644 --- a/aws/resource_aws_appmesh_test.go +++ b/aws/resource_aws_appmesh_test.go @@ -21,6 +21,7 @@ func TestAccAWSAppmesh_serial(t *testing.T) { }, "VirtualNode": { "basic": testAccAwsAppmeshVirtualNode_basic, + "backendDefaults": testAccAwsAppmeshVirtualNode_backendDefaults, "clientPolicyAcm": testAccAwsAppmeshVirtualNode_clientPolicyAcm, "clientPolicyFile": testAccAwsAppmeshVirtualNode_clientPolicyFile, "cloudMapServiceDiscovery": testAccAwsAppmeshVirtualNode_cloudMapServiceDiscovery, diff --git a/aws/resource_aws_appmesh_virtual_node_test.go b/aws/resource_aws_appmesh_virtual_node_test.go index 872d0453cbc..87e1cc69868 100644 --- a/aws/resource_aws_appmesh_virtual_node_test.go +++ b/aws/resource_aws_appmesh_virtual_node_test.go @@ -100,6 +100,7 @@ func testAccAwsAppmeshVirtualNode_basic(t *testing.T) { testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.logging.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.#", "0"), @@ -200,6 +201,7 @@ func testAccAwsAppmeshVirtualNode_listenerHealthChecks(t *testing.T) { "virtual_service.#": "1", "virtual_service.0.virtual_service_name": "servicea.simpleapp.local", }), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.health_check.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.health_check.0.healthy_threshold", "3"), @@ -242,6 +244,7 @@ func testAccAwsAppmeshVirtualNode_listenerHealthChecks(t *testing.T) { "virtual_service.#": "1", "virtual_service.0.virtual_service_name": "serviced.simpleapp.local", }), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.health_check.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.health_check.0.healthy_threshold", "4"), @@ -392,6 +395,7 @@ func testAccAwsAppmeshVirtualNode_tls(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.backend.2622272660.virtual_service.client_policy.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.2622272660.virtual_service.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.2622272660.virtual_service.0.virtual_service_name", "servicea.simpleapp.local"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.health_check.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.port_mapping.#", "1"), @@ -426,6 +430,7 @@ func testAccAwsAppmeshVirtualNode_tls(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.backend.2622272660.virtual_service.client_policy.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.2622272660.virtual_service.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.2622272660.virtual_service.0.virtual_service_name", "servicea.simpleapp.local"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.#", "1"), testAccCheckAppmeshVirtualNodeTlsAcmCertificateArn(acmCertificateResourceName, "arn", &vn), resource.TestCheckResourceAttr(resourceName, "spec.0.logging.#", "0"), @@ -479,6 +484,46 @@ func testAccAwsAppmeshVirtualNode_clientPolicyFile(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.backend.906924271.virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.file.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.906924271.virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.file.0.certificate_chain", "/cert_chain.pem"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.906924271.virtual_service.0.virtual_service_name", "servicea.simpleapp.local"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.health_check.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.port_mapping.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.port_mapping.0.port", "8080"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.port_mapping.0.protocol", "http"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.tls.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.logging.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.0.hostname", "serviceb.simpleapp.local"), + resource.TestCheckResourceAttrSet(resourceName, "created_date"), + resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), + testAccCheckResourceAttrAccountID(resourceName, "resource_owner"), + testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh-preview", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), + ), + }, + { + Config: testAccAppmeshVirtualNodeConfig_clientPolicyFileUpdated(meshName, vnName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAppmeshVirtualNodeExists(resourceName, &vn), + resource.TestCheckResourceAttr(resourceName, "name", vnName), + resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), + testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), + resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.enforce", "true"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.ports.#", "2"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.ports.3638101695", "443"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.ports.860082431", "8443"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.validation.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.validation.0.trust.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.acm.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.file.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.file.0.certificate_chain", "/etc/ssl/certs/cert_chain.pem"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.sds.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.virtual_service_name", "servicea.simpleapp.local"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.health_check.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.port_mapping.#", "1"), @@ -535,6 +580,7 @@ func testAccAwsAppmeshVirtualNode_clientPolicyAcm(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "1"), testAccCheckAppmeshVirtualNodeClientPolicyAcmCertificateAuthorityArn(acmCAResourceName, "arn", &vn), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.health_check.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.port_mapping.#", "1"), @@ -607,6 +653,86 @@ func testAccAwsAppmeshVirtualNode_clientPolicyAcm(t *testing.T) { }) } +func testAccAwsAppmeshVirtualNode_backendDefaults(t *testing.T) { + var vn appmesh.VirtualNodeData + resourceName := "aws_appmesh_virtual_node.test" + meshName := acctest.RandomWithPrefix("tf-acc-test") + vnName := acctest.RandomWithPrefix("tf-acc-test") + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAppmeshVirtualNodeDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAppmeshVirtualNodeConfig_backendDefaults(meshName, vnName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAppmeshVirtualNodeExists(resourceName, &vn), + resource.TestCheckResourceAttr(resourceName, "name", vnName), + resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), + testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), + resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.0.client_policy.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.0.client_policy.0.tls.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.0.client_policy.0.tls.0.enforce", "true"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.0.client_policy.0.tls.0.ports.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.0.client_policy.0.tls.0.ports.860082431", "8443"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.0.client_policy.0.tls.0.validation.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.0.client_policy.0.tls.0.validation.0.trust.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.0.client_policy.0.tls.0.validation.0.trust.0.acm.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.0.client_policy.0.tls.0.validation.0.trust.0.file.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.0.client_policy.0.tls.0.validation.0.trust.0.file.0.certificate_chain", "/cert_chain.pem"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.logging.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.#", "0"), + resource.TestCheckResourceAttrSet(resourceName, "created_date"), + resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), + testAccCheckResourceAttrAccountID(resourceName, "resource_owner"), + testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh-preview", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), + ), + }, + { + Config: testAccAppmeshVirtualNodeConfig_backendDefaultsUpdated(meshName, vnName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAppmeshVirtualNodeExists(resourceName, &vn), + resource.TestCheckResourceAttr(resourceName, "name", vnName), + resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), + testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), + resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.0.client_policy.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.0.client_policy.0.tls.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.0.client_policy.0.tls.0.enforce", "true"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.0.client_policy.0.tls.0.ports.#", "2"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.0.client_policy.0.tls.0.ports.3638101695", "443"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.0.client_policy.0.tls.0.ports.860082431", "8443"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.0.client_policy.0.tls.0.validation.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.0.client_policy.0.tls.0.validation.0.trust.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.0.client_policy.0.tls.0.validation.0.trust.0.acm.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.0.client_policy.0.tls.0.validation.0.trust.0.file.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.0.client_policy.0.tls.0.validation.0.trust.0.file.0.certificate_chain", "/etc/ssl/certs/cert_chain.pem"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.logging.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.#", "0"), + resource.TestCheckResourceAttrSet(resourceName, "created_date"), + resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), + testAccCheckResourceAttrAccountID(resourceName, "resource_owner"), + testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh-preview", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), + ), + }, + { + ResourceName: resourceName, + ImportStateId: fmt.Sprintf("%s/%s", meshName, vnName), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testAccCheckAppmeshVirtualNodeDestroy(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).appmeshconn @@ -1116,3 +1242,57 @@ resource "aws_appmesh_virtual_node" "test" { } `, vnName) } + +func testAccAppmeshVirtualNodeConfig_backendDefaults(meshName, vnName string) string { + return testAccAppmeshVirtualNodeConfig_mesh(meshName) + fmt.Sprintf(` +resource "aws_appmesh_virtual_node" "test" { + name = %[1]q + mesh_name = "${aws_appmesh_mesh.test.id}" + + spec { + backend_defaults { + client_policy { + tls { + ports = [8443] + + validation { + trust { + file { + certificate_chain = "/cert_chain.pem" + } + } + } + } + } + } + } +} +`, vnName) +} + +func testAccAppmeshVirtualNodeConfig_backendDefaultsUpdated(meshName, vnName string) string { + return testAccAppmeshVirtualNodeConfig_mesh(meshName) + fmt.Sprintf(` +resource "aws_appmesh_virtual_node" "test" { + name = %[1]q + mesh_name = "${aws_appmesh_mesh.test.id}" + + spec { + backend_defaults { + client_policy { + tls { + ports = [443, 8443] + + validation { + trust { + file { + certificate_chain = "/etc/ssl/certs/cert_chain.pem" + } + } + } + } + } + } + } +} +`, vnName) +} From e7e836545a534b6bf76902d9e413da534ca709ae Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 26 Mar 2020 10:00:07 -0400 Subject: [PATCH 08/21] Remove artifacts of other preview features. --- aws/resource_aws_appmesh_virtual_node_test.go | 29 +++++-------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/aws/resource_aws_appmesh_virtual_node_test.go b/aws/resource_aws_appmesh_virtual_node_test.go index 87e1cc69868..d3b147a17d8 100644 --- a/aws/resource_aws_appmesh_virtual_node_test.go +++ b/aws/resource_aws_appmesh_virtual_node_test.go @@ -389,7 +389,6 @@ func testAccAwsAppmeshVirtualNode_tls(t *testing.T) { testAccCheckAppmeshVirtualNodeExists(resourceName, &vn), resource.TestCheckResourceAttr(resourceName, "name", vnName), resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), - testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.2622272660.virtual_service.client_policy.#", "0"), @@ -414,8 +413,7 @@ func testAccAwsAppmeshVirtualNode_tls(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.0.hostname", "serviceb.simpleapp.local"), resource.TestCheckResourceAttrSet(resourceName, "created_date"), resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), - testAccCheckResourceAttrAccountID(resourceName, "resource_owner"), - testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh-preview", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), + testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), ), }, { @@ -424,7 +422,6 @@ func testAccAwsAppmeshVirtualNode_tls(t *testing.T) { testAccCheckAppmeshVirtualNodeExists(resourceName, &vn), resource.TestCheckResourceAttr(resourceName, "name", vnName), resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), - testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.2622272660.virtual_service.client_policy.#", "0"), @@ -439,8 +436,8 @@ func testAccAwsAppmeshVirtualNode_tls(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.0.hostname", "serviceb.simpleapp.local"), resource.TestCheckResourceAttrSet(resourceName, "created_date"), resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), - testAccCheckResourceAttrAccountID(resourceName, "resource_owner"), - testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh-preview", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), + + testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), ), }, { @@ -470,7 +467,6 @@ func testAccAwsAppmeshVirtualNode_clientPolicyFile(t *testing.T) { testAccCheckAppmeshVirtualNodeExists(resourceName, &vn), resource.TestCheckResourceAttr(resourceName, "name", vnName), resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), - testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.906924271.virtual_service.0.client_policy.#", "1"), @@ -497,8 +493,7 @@ func testAccAwsAppmeshVirtualNode_clientPolicyFile(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.0.hostname", "serviceb.simpleapp.local"), resource.TestCheckResourceAttrSet(resourceName, "created_date"), resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), - testAccCheckResourceAttrAccountID(resourceName, "resource_owner"), - testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh-preview", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), + testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), ), }, { @@ -507,7 +502,6 @@ func testAccAwsAppmeshVirtualNode_clientPolicyFile(t *testing.T) { testAccCheckAppmeshVirtualNodeExists(resourceName, &vn), resource.TestCheckResourceAttr(resourceName, "name", vnName), resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), - testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.#", "1"), @@ -536,8 +530,7 @@ func testAccAwsAppmeshVirtualNode_clientPolicyFile(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.0.hostname", "serviceb.simpleapp.local"), resource.TestCheckResourceAttrSet(resourceName, "created_date"), resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), - testAccCheckResourceAttrAccountID(resourceName, "resource_owner"), - testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh-preview", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), + testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), ), }, { @@ -576,7 +569,6 @@ func testAccAwsAppmeshVirtualNode_clientPolicyAcm(t *testing.T) { testAccCheckAppmeshVirtualNodeExists(resourceName, &vn), resource.TestCheckResourceAttr(resourceName, "name", vnName), resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), - testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "1"), testAccCheckAppmeshVirtualNodeClientPolicyAcmCertificateAuthorityArn(acmCAResourceName, "arn", &vn), @@ -593,8 +585,7 @@ func testAccAwsAppmeshVirtualNode_clientPolicyAcm(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.0.hostname", "serviceb.simpleapp.local"), resource.TestCheckResourceAttrSet(resourceName, "created_date"), resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), - testAccCheckResourceAttrAccountID(resourceName, "resource_owner"), - testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh-preview", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), + testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), ), }, { @@ -670,7 +661,6 @@ func testAccAwsAppmeshVirtualNode_backendDefaults(t *testing.T) { testAccCheckAppmeshVirtualNodeExists(resourceName, &vn), resource.TestCheckResourceAttr(resourceName, "name", vnName), resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), - testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.#", "1"), @@ -689,8 +679,7 @@ func testAccAwsAppmeshVirtualNode_backendDefaults(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.#", "0"), resource.TestCheckResourceAttrSet(resourceName, "created_date"), resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), - testAccCheckResourceAttrAccountID(resourceName, "resource_owner"), - testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh-preview", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), + testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), ), }, { @@ -699,7 +688,6 @@ func testAccAwsAppmeshVirtualNode_backendDefaults(t *testing.T) { testAccCheckAppmeshVirtualNodeExists(resourceName, &vn), resource.TestCheckResourceAttr(resourceName, "name", vnName), resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), - testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.#", "1"), @@ -719,8 +707,7 @@ func testAccAwsAppmeshVirtualNode_backendDefaults(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.#", "0"), resource.TestCheckResourceAttrSet(resourceName, "created_date"), resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), - testAccCheckResourceAttrAccountID(resourceName, "resource_owner"), - testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh-preview", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), + testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), ), }, { From 1d18576200756d5cdaa4da4148b6859875760124 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 26 Mar 2020 10:45:13 -0400 Subject: [PATCH 09/21] Remove commented-out references to 'sds'. That features is not out of preview. --- aws/resource_aws_appmesh_virtual_node.go | 41 ------------------- aws/resource_aws_appmesh_virtual_node_test.go | 1 - 2 files changed, 42 deletions(-) diff --git a/aws/resource_aws_appmesh_virtual_node.go b/aws/resource_aws_appmesh_virtual_node.go index 38871bd948c..736fa467092 100644 --- a/aws/resource_aws_appmesh_virtual_node.go +++ b/aws/resource_aws_appmesh_virtual_node.go @@ -452,47 +452,6 @@ func appmeshVirtualNodeClientPolicySchema() *schema.Schema { }, }, }, - - // "sds": { - // Type: schema.TypeList, - // Optional: true, - // MinItems: 0, - // MaxItems: 1, - // Elem: &schema.Resource{ - // Schema: map[string]*schema.Schema{ - // "secret_name": { - // Type: schema.TypeString, - // Required: true, - // ValidateFunc: validation.StringLenBetween(1, 255), - // }, - - // "source": { - // Type: schema.TypeList, - // Required: true, - // MinItems: 1, - // MaxItems: 1, - // Elem: &schema.Resource{ - // Schema: map[string]*schema.Schema{ - // "unix_domain_socket": { - // Type: schema.TypeList, - // Required: true, - // MinItems: 1, - // MaxItems: 1, - // Elem: &schema.Resource{ - // Schema: map[string]*schema.Schema{ - // "path": { - // Type: schema.TypeString, - // Required: true, - // }, - // }, - // }, - // }, - // }, - // }, - // }, - // }, - // }, - // }, }, }, }, diff --git a/aws/resource_aws_appmesh_virtual_node_test.go b/aws/resource_aws_appmesh_virtual_node_test.go index d3b147a17d8..c4abec5de3c 100644 --- a/aws/resource_aws_appmesh_virtual_node_test.go +++ b/aws/resource_aws_appmesh_virtual_node_test.go @@ -515,7 +515,6 @@ func testAccAwsAppmeshVirtualNode_clientPolicyFile(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.acm.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.file.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.file.0.certificate_chain", "/etc/ssl/certs/cert_chain.pem"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.sds.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.virtual_service_name", "servicea.simpleapp.local"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.#", "1"), From 4668de1a82397598804a4a779b5ba4eceef16594 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 26 Mar 2020 12:29:09 -0400 Subject: [PATCH 10/21] Use multierror in test sweeper: $ TEST=./aws SWEEP=us-west-2 SWEEPARGS=-sweep-run=aws_appmesh_virtual_node make sweep WARNING: This will destroy infrastructure. Use only in development accounts. go test ./aws -v -sweep=us-west-2 -sweep-run=aws_appmesh_virtual_node -timeout 60m 2020/03/26 12:28:45 [DEBUG] Running Sweepers for region (us-west-2): 2020/03/26 12:28:45 [DEBUG] Running Sweeper (aws_appmesh_virtual_node) in region (us-west-2) 2020/03/26 12:28:45 [INFO] Building AWS auth structure 2020/03/26 12:28:45 [INFO] Setting AWS metadata API timeout to 100ms 2020/03/26 12:28:47 [INFO] Ignoring AWS metadata API endpoint at default location as it doesn't return any instance-id 2020/03/26 12:28:47 [INFO] AWS Auth provider used: "EnvProvider" 2020/03/26 12:28:47 [DEBUG] Trying to get account information via sts:GetCallerIdentity 2020/03/26 12:28:47 [DEBUG] Trying to get account information via sts:GetCallerIdentity 2020/03/26 12:28:48 Sweeper Tests ran successfully: - aws_appmesh_virtual_node ok github.com/terraform-providers/terraform-provider-aws/aws 2.607s --- aws/resource_aws_appmesh_virtual_node_test.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/aws/resource_aws_appmesh_virtual_node_test.go b/aws/resource_aws_appmesh_virtual_node_test.go index c4abec5de3c..16a4ef04bc3 100644 --- a/aws/resource_aws_appmesh_virtual_node_test.go +++ b/aws/resource_aws_appmesh_virtual_node_test.go @@ -28,6 +28,8 @@ func testSweepAppmeshVirtualNodes(region string) error { } conn := client.(*AWSClient).appmeshconn + var sweeperErrs *multierror.Error + err = conn.ListMeshesPages(&appmesh.ListMeshesInput{}, func(page *appmesh.ListMeshesOutput, isLast bool) bool { if page == nil { return !isLast @@ -55,7 +57,10 @@ func testSweepAppmeshVirtualNodes(region string) error { _, err := conn.DeleteVirtualNode(input) if err != nil { - log.Printf("[ERROR] Error deleting Appmesh Mesh (%s) Virtual Node (%s): %s", meshName, virtualNodeName, err) + sweeperErr := fmt.Errorf("error deleting Appmesh Mesh (%s) Virtual Node (%s): %w", meshName, virtualNodeName, err) + log.Printf("[ERROR] %s", sweeperErr) + sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) + continue } } @@ -77,7 +82,7 @@ func testSweepAppmeshVirtualNodes(region string) error { return fmt.Errorf("error retrieving Appmesh Virtual Nodes: %s", err) } - return nil + return sweeperErrs.ErrorOrNil() } func testAccAwsAppmeshVirtualNode_basic(t *testing.T) { From a357177259dbf3b10227ccce121779abd77da6dc Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 27 Mar 2020 17:59:42 -0400 Subject: [PATCH 11/21] Fix testAccAwsAppmeshVirtualNode_tls acceptance test. --- aws/resource_aws_acm_certificate_test.go | 12 ++--- aws/resource_aws_appmesh_virtual_node_test.go | 49 +++++++++++++------ 2 files changed, 39 insertions(+), 22 deletions(-) diff --git a/aws/resource_aws_acm_certificate_test.go b/aws/resource_aws_acm_certificate_test.go index 80c04cfa9ce..7fb6c57fa06 100644 --- a/aws/resource_aws_acm_certificate_test.go +++ b/aws/resource_aws_acm_certificate_test.go @@ -3,15 +3,15 @@ package aws import ( "fmt" "log" + "os" + "regexp" "strconv" "strings" "testing" - "os" - "regexp" - "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/acm" + "github.com/aws/aws-sdk-go/service/acmpca" "github.com/hashicorp/go-multierror" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" @@ -219,7 +219,7 @@ func TestAccAWSAcmCertificate_root(t *testing.T) { func TestAccAWSAcmCertificate_privateCert(t *testing.T) { certificateAuthorityResourceName := "aws_acmpca_certificate_authority.test" - resourceName := "aws_acm_certificate.cert" + resourceName := "aws_acm_certificate.test" rName := acctest.RandomWithPrefix("tf-acc-test") resource.ParallelTest(t, resource.TestCase{ @@ -230,8 +230,8 @@ func TestAccAWSAcmCertificate_privateCert(t *testing.T) { { Config: testAccAcmCertificateConfig_privateCert(rName), Check: resource.ComposeTestCheckFunc( - testAccMatchResourceAttrRegionalARN(resourceName, "arn", "acm", regexp.MustCompile("certificate/.+$")), - resource.TestCheckResourceAttr(resourceName, "domain_name", fmt.Sprintf("%s.terraformtesting.com", rName)), + testAccMatchResourceAttrRegionalARN(resourceName, "arn", "acm", regexp.MustCompile(`certificate/.+`)), + resource.TestCheckResourceAttr(resourceName, "domain_name", fmt.Sprintf("test.%s.com", rName)), resource.TestCheckResourceAttr(resourceName, "domain_validation_options.#", "0"), resource.TestCheckResourceAttr(resourceName, "status", acm.CertificateStatusFailed), // FailureReason: PCA_INVALID_STATE (PCA State: PENDING_CERTIFICATE) resource.TestCheckResourceAttr(resourceName, "subject_alternative_names.#", "0"), diff --git a/aws/resource_aws_appmesh_virtual_node_test.go b/aws/resource_aws_appmesh_virtual_node_test.go index 16a4ef04bc3..ad2fc09c3b5 100644 --- a/aws/resource_aws_appmesh_virtual_node_test.go +++ b/aws/resource_aws_appmesh_virtual_node_test.go @@ -378,8 +378,10 @@ func testAccAwsAppmeshVirtualNode_tags(t *testing.T) { func testAccAwsAppmeshVirtualNode_tls(t *testing.T) { var vn appmesh.VirtualNodeData + var ca acmpca.CertificateAuthority resourceName := "aws_appmesh_virtual_node.test" - acmCertificateResourceName := "aws_acm_certificate.cert" + acmCAResourceName := "aws_acmpca_certificate_authority.test" + acmCertificateResourceName := "aws_acm_certificate.test" meshName := acctest.RandomWithPrefix("tf-acc-test") vnName := acctest.RandomWithPrefix("tf-acc-test") @@ -388,8 +390,16 @@ func testAccAwsAppmeshVirtualNode_tls(t *testing.T) { Providers: testAccProviders, CheckDestroy: testAccCheckAppmeshVirtualNodeDestroy, Steps: []resource.TestStep{ + // We need to create and active the CA before issuing a certificate. { - Config: testAccAppmeshVirtualNodeConfig_tlsFile(meshName, vnName), + Config: testAccAwsAcmpcaCertificateAuthorityConfigType(meshName, acmpca.CertificateAuthorityTypeRoot), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsAcmpcaCertificateAuthorityExists(acmCAResourceName, &ca), + testAccCheckAwsAcmpcaCertificateAuthorityActivateCA(&ca), + ), + }, + { + Config: testAccAppmeshVirtualNodeConfig_tlsAcm(meshName, vnName), Check: resource.ComposeTestCheckFunc( testAccCheckAppmeshVirtualNodeExists(resourceName, &vn), resource.TestCheckResourceAttr(resourceName, "name", vnName), @@ -401,17 +411,7 @@ func testAccAwsAppmeshVirtualNode_tls(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.backend.2622272660.virtual_service.0.virtual_service_name", "servicea.simpleapp.local"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.health_check.#", "0"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.port_mapping.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.port_mapping.0.port", "8080"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.port_mapping.0.protocol", "http"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.tls.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.tls.0.certificate.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.tls.0.certificate.0.acm.#", "0"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.tls.0.certificate.0.file.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.tls.0.certificate.0.file.0.certificate_chain", "/cert_chain.pem"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.tls.0.certificate.0.file.0.private_key", "/key.pem"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.tls.0.mode", "PERMISSIVE"), + testAccCheckAppmeshVirtualNodeTlsAcmCertificateArn(acmCertificateResourceName, "arn", &vn), resource.TestCheckResourceAttr(resourceName, "spec.0.logging.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.#", "1"), @@ -423,6 +423,14 @@ func testAccAwsAppmeshVirtualNode_tls(t *testing.T) { }, { Config: testAccAppmeshVirtualNodeConfig_tlsAcm(meshName, vnName), + Check: resource.ComposeTestCheckFunc( + // CA must be DISABLED for deletion. + testAccCheckAwsAcmpcaCertificateAuthorityDisableCA(&ca), + ), + ExpectNonEmptyPlan: true, + }, + { + Config: testAccAppmeshVirtualNodeConfig_tlsFile(meshName, vnName), Check: resource.ComposeTestCheckFunc( testAccCheckAppmeshVirtualNodeExists(resourceName, &vn), resource.TestCheckResourceAttr(resourceName, "name", vnName), @@ -434,14 +442,23 @@ func testAccAwsAppmeshVirtualNode_tls(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.backend.2622272660.virtual_service.0.virtual_service_name", "servicea.simpleapp.local"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.#", "1"), - testAccCheckAppmeshVirtualNodeTlsAcmCertificateArn(acmCertificateResourceName, "arn", &vn), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.health_check.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.port_mapping.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.port_mapping.0.port", "8080"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.port_mapping.0.protocol", "http"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.tls.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.tls.0.certificate.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.tls.0.certificate.0.acm.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.tls.0.certificate.0.file.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.tls.0.certificate.0.file.0.certificate_chain", "/cert_chain.pem"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.tls.0.certificate.0.file.0.private_key", "/key.pem"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.tls.0.mode", "PERMISSIVE"), resource.TestCheckResourceAttr(resourceName, "spec.0.logging.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.0.hostname", "serviceb.simpleapp.local"), resource.TestCheckResourceAttrSet(resourceName, "created_date"), resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), - testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), ), }, @@ -1084,7 +1101,7 @@ resource "aws_appmesh_virtual_node" "test" { tls { certificate { acm { - certificate_arn = "${aws_acm_certificate.cert.arn}" + certificate_arn = "${aws_acm_certificate.test.arn}" } } From cfb3d7c292adb07b69c97e87617984a65dccfa0d Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 10 Jun 2020 17:06:34 -0400 Subject: [PATCH 12/21] Simplify certificate handling - Some TODOs. --- aws/resource_aws_acm_certificate_test.go | 12 ++-- ...e_aws_acmpca_certificate_authority_test.go | 37 +++------- aws/resource_aws_appmesh_virtual_node_test.go | 67 +++++++++++++++---- 3 files changed, 67 insertions(+), 49 deletions(-) diff --git a/aws/resource_aws_acm_certificate_test.go b/aws/resource_aws_acm_certificate_test.go index 7fb6c57fa06..80c04cfa9ce 100644 --- a/aws/resource_aws_acm_certificate_test.go +++ b/aws/resource_aws_acm_certificate_test.go @@ -3,15 +3,15 @@ package aws import ( "fmt" "log" - "os" - "regexp" "strconv" "strings" "testing" + "os" + "regexp" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/acm" - "github.com/aws/aws-sdk-go/service/acmpca" "github.com/hashicorp/go-multierror" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" @@ -219,7 +219,7 @@ func TestAccAWSAcmCertificate_root(t *testing.T) { func TestAccAWSAcmCertificate_privateCert(t *testing.T) { certificateAuthorityResourceName := "aws_acmpca_certificate_authority.test" - resourceName := "aws_acm_certificate.test" + resourceName := "aws_acm_certificate.cert" rName := acctest.RandomWithPrefix("tf-acc-test") resource.ParallelTest(t, resource.TestCase{ @@ -230,8 +230,8 @@ func TestAccAWSAcmCertificate_privateCert(t *testing.T) { { Config: testAccAcmCertificateConfig_privateCert(rName), Check: resource.ComposeTestCheckFunc( - testAccMatchResourceAttrRegionalARN(resourceName, "arn", "acm", regexp.MustCompile(`certificate/.+`)), - resource.TestCheckResourceAttr(resourceName, "domain_name", fmt.Sprintf("test.%s.com", rName)), + testAccMatchResourceAttrRegionalARN(resourceName, "arn", "acm", regexp.MustCompile("certificate/.+$")), + resource.TestCheckResourceAttr(resourceName, "domain_name", fmt.Sprintf("%s.terraformtesting.com", rName)), resource.TestCheckResourceAttr(resourceName, "domain_validation_options.#", "0"), resource.TestCheckResourceAttr(resourceName, "status", acm.CertificateStatusFailed), // FailureReason: PCA_INVALID_STATE (PCA State: PENDING_CERTIFICATE) resource.TestCheckResourceAttr(resourceName, "subject_alternative_names.#", "0"), diff --git a/aws/resource_aws_acmpca_certificate_authority_test.go b/aws/resource_aws_acmpca_certificate_authority_test.go index 6a25806c812..7487fe7b15a 100644 --- a/aws/resource_aws_acmpca_certificate_authority_test.go +++ b/aws/resource_aws_acmpca_certificate_authority_test.go @@ -41,45 +41,24 @@ func testSweepAcmpcaCertificateAuthorities(region string) error { return nil } - var sweeperErrs *multierror.Error - for _, certificateAuthority := range certificateAuthorities { arn := aws.StringValue(certificateAuthority.Arn) - - if aws.StringValue(certificateAuthority.Status) == acmpca.CertificateAuthorityStatusActive { - log.Printf("[INFO] Disabling ACMPCA Certificate Authority: %s", arn) - _, err := conn.UpdateCertificateAuthority(&acmpca.UpdateCertificateAuthorityInput{ - CertificateAuthorityArn: aws.String(arn), - Status: aws.String(acmpca.CertificateAuthorityStatusDisabled), - }) - if isAWSErr(err, acmpca.ErrCodeResourceNotFoundException, "") { - continue - } - if err != nil { - sweeperErr := fmt.Errorf("error disabling ACMPCA Certificate Authority (%s): %w", arn, err) - log.Printf("[ERROR] %s", sweeperErr) - sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) - continue - } - } - log.Printf("[INFO] Deleting ACMPCA Certificate Authority: %s", arn) - _, err := conn.DeleteCertificateAuthority(&acmpca.DeleteCertificateAuthorityInput{ + input := &acmpca.DeleteCertificateAuthorityInput{ CertificateAuthorityArn: aws.String(arn), PermanentDeletionTimeInDays: aws.Int64(int64(7)), - }) - if isAWSErr(err, acmpca.ErrCodeResourceNotFoundException, "") { - continue } + + _, err := conn.DeleteCertificateAuthority(input) if err != nil { - sweeperErr := fmt.Errorf("error deleting ACMPCA Certificate Authority (%s): %w", arn, err) - log.Printf("[ERROR] %s", sweeperErr) - sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) - continue + if isAWSErr(err, acmpca.ErrCodeResourceNotFoundException, "") { + continue + } + log.Printf("[ERROR] Failed to delete ACMPCA Certificate Authority (%s): %s", arn, err) } } - return sweeperErrs.ErrorOrNil() + return nil } func TestAccAwsAcmpcaCertificateAuthority_basic(t *testing.T) { diff --git a/aws/resource_aws_appmesh_virtual_node_test.go b/aws/resource_aws_appmesh_virtual_node_test.go index ad2fc09c3b5..91fbbae79da 100644 --- a/aws/resource_aws_appmesh_virtual_node_test.go +++ b/aws/resource_aws_appmesh_virtual_node_test.go @@ -392,10 +392,11 @@ func testAccAwsAppmeshVirtualNode_tls(t *testing.T) { Steps: []resource.TestStep{ // We need to create and active the CA before issuing a certificate. { - Config: testAccAwsAcmpcaCertificateAuthorityConfigType(meshName, acmpca.CertificateAuthorityTypeRoot), + Config: testAccAppmeshVirtualNodeConfigRootCA(vnName), Check: resource.ComposeTestCheckFunc( testAccCheckAwsAcmpcaCertificateAuthorityExists(acmCAResourceName, &ca), - testAccCheckAwsAcmpcaCertificateAuthorityActivateCA(&ca), + // TODO + //testAccCheckAwsAcmpcaCertificateAuthorityActivateCA(&ca), ), }, { @@ -423,9 +424,10 @@ func testAccAwsAppmeshVirtualNode_tls(t *testing.T) { }, { Config: testAccAppmeshVirtualNodeConfig_tlsAcm(meshName, vnName), - Check: resource.ComposeTestCheckFunc( - // CA must be DISABLED for deletion. - testAccCheckAwsAcmpcaCertificateAuthorityDisableCA(&ca), + Check: resource.ComposeTestCheckFunc( + // CA must be DISABLED for deletion. + // TODO + //testAccCheckAwsAcmpcaCertificateAuthorityDisableCA(&ca), ), ExpectNonEmptyPlan: true, }, @@ -578,10 +580,11 @@ func testAccAwsAppmeshVirtualNode_clientPolicyAcm(t *testing.T) { CheckDestroy: testAccCheckAppmeshVirtualNodeDestroy, Steps: []resource.TestStep{ { - Config: testAccAwsAcmpcaCertificateAuthorityConfigType(meshName, acmpca.CertificateAuthorityTypeRoot), + Config: testAccAppmeshVirtualNodeConfigRootCA(vnName), Check: resource.ComposeTestCheckFunc( testAccCheckAwsAcmpcaCertificateAuthorityExists(acmCAResourceName, &ca), - testAccCheckAwsAcmpcaCertificateAuthorityActivateCA(&ca), + // TODO + //testAccCheckAwsAcmpcaCertificateAuthorityActivateCA(&ca), ), }, { @@ -649,9 +652,10 @@ func testAccAwsAppmeshVirtualNode_clientPolicyAcm(t *testing.T) { }, { Config: testAccAppmeshVirtualNodeConfig_clientPolicyAcm(meshName, vnName), - Check: resource.ComposeTestCheckFunc( - // CA must be DISABLED for deletion. - testAccCheckAwsAcmpcaCertificateAuthorityDisableCA(&ca), + Check: resource.ComposeTestCheckFunc( + // CA must be DISABLED for deletion. + // TODO + //testAccCheckAwsAcmpcaCertificateAuthorityDisableCA(&ca), ), ExpectNonEmptyPlan: true, }, @@ -850,6 +854,33 @@ resource "aws_appmesh_mesh" "test" { `, rName) } +func testAccAppmeshVirtualNodeConfigRootCA(rName string) string { + return fmt.Sprintf(` +resource "aws_acmpca_certificate_authority" "test" { + permanent_deletion_time_in_days = 7 + type = "ROOT" + + certificate_authority_configuration { + key_algorithm = "RSA_4096" + signing_algorithm = "SHA512WITHRSA" + + subject { + common_name = "%[1]s.com" + } + } +} +`, rName) +} + +func testAccAppmeshVirtualNodeConfigPrivateCert(rName string) string { + return fmt.Sprintf(` +resource "aws_acm_certificate" "test" { + domain_name = "test.%[1]s.com" + certificate_authority_arn = "${aws_acmpca_certificate_authority.test.arn}" +} +`, rName) +} + func testAccAppmeshVirtualNodeConfig_basic(meshName, vnName string) string { return testAccAppmeshVirtualNodeConfig_mesh(meshName) + fmt.Sprintf(` resource "aws_appmesh_virtual_node" "test" { @@ -1080,7 +1111,11 @@ resource "aws_appmesh_virtual_node" "test" { } func testAccAppmeshVirtualNodeConfig_tlsAcm(meshName, vnName string) string { - return testAccAcmCertificateConfig_privateCert(meshName) + testAccAppmeshVirtualNodeConfig_mesh(meshName) + fmt.Sprintf(` + return composeConfig( + testAccAppmeshVirtualNodeConfigRootCA(vnName), + testAccAppmeshVirtualNodeConfigPrivateCert(vnName), + testAccAppmeshVirtualNodeConfig_mesh(meshName), + fmt.Sprintf(` resource "aws_appmesh_virtual_node" "test" { name = %[1]q mesh_name = "${aws_appmesh_mesh.test.id}" @@ -1116,7 +1151,7 @@ resource "aws_appmesh_virtual_node" "test" { } } } -`, vnName) +`, vnName)) } func testAccAppmeshVirtualNodeConfig_clientPolicyFile(meshName, vnName string) string { @@ -1208,7 +1243,11 @@ resource "aws_appmesh_virtual_node" "test" { } func testAccAppmeshVirtualNodeConfig_clientPolicyAcm(meshName, vnName string) string { - return testAccAwsAcmpcaCertificateAuthorityConfigType(meshName, acmpca.CertificateAuthorityTypeRoot) + testAccAppmeshVirtualNodeConfig_mesh(meshName) + fmt.Sprintf(` + return composeConfig( + testAccAppmeshVirtualNodeConfigRootCA(vnName), + testAccAppmeshVirtualNodeConfigPrivateCert(vnName), + testAccAppmeshVirtualNodeConfig_mesh(meshName), + fmt.Sprintf(` resource "aws_appmesh_virtual_node" "test" { name = %[1]q mesh_name = "${aws_appmesh_mesh.test.id}" @@ -1248,7 +1287,7 @@ resource "aws_appmesh_virtual_node" "test" { } } } -`, vnName) +`, vnName)) } func testAccAppmeshVirtualNodeConfig_backendDefaults(meshName, vnName string) string { From b2b05cfb9188f8446f0646bbc536e155004212c9 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 8 Jun 2020 18:07:27 -0400 Subject: [PATCH 13/21] r/aws_acmpca_certificate_authority: Test CA activation. Acceptance test output: $ make testacc TEST=./aws/ TESTARGS='-run=TestAccAwsAcmpcaCertificateAuthority_Enabled' ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./aws/ -v -count 1 -parallel 20 -run=TestAccAwsAcmpcaCertificateAuthority_Enabled -timeout 120m === RUN TestAccAwsAcmpcaCertificateAuthority_Enabled === PAUSE TestAccAwsAcmpcaCertificateAuthority_Enabled === CONT TestAccAwsAcmpcaCertificateAuthority_Enabled --- PASS: TestAccAwsAcmpcaCertificateAuthority_Enabled (69.95s) PASS ok github.com/terraform-providers/terraform-provider-aws/aws 69.989s Add 'TestAccAwsAcmpcaCertificateAuthority_disappears'. Acceptance test output: $ make testacc TEST=./aws/ TESTARGS='-run=TestAccAwsAcmpcaCertificateAuthority_disappears' ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./aws/ -v -count 1 -parallel 20 -run=TestAccAwsAcmpcaCertificateAuthority_disappears -timeout 120m === RUN TestAccAwsAcmpcaCertificateAuthority_disappears === PAUSE TestAccAwsAcmpcaCertificateAuthority_disappears === CONT TestAccAwsAcmpcaCertificateAuthority_disappears --- PASS: TestAccAwsAcmpcaCertificateAuthority_disappears (25.10s) PASS ok github.com/terraform-providers/terraform-provider-aws/aws 25.138s --- ...source_aws_acmpca_certificate_authority.go | 5 ++- ...e_aws_acmpca_certificate_authority_test.go | 37 +++++++++++++++---- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/aws/resource_aws_acmpca_certificate_authority.go b/aws/resource_aws_acmpca_certificate_authority.go index a2ea02cfae9..2ab42469d82 100644 --- a/aws/resource_aws_acmpca_certificate_authority.go +++ b/aws/resource_aws_acmpca_certificate_authority.go @@ -410,7 +410,10 @@ func resourceAwsAcmpcaCertificateAuthorityRead(d *schema.ResourceData, meta inte tags, err := keyvaluetags.AcmpcaListTags(conn, d.Id()) if err != nil { - return fmt.Errorf("error listing tags for ACMPCA Certificate Authority (%s): %s", d.Id(), err) + if !isAWSErr(err, acmpca.ErrCodeInvalidStateException, "") { + // InvalidStateException: The certificate authority is in the DELETED state and must be restored to complete this action. + return fmt.Errorf("error listing tags for ACMPCA Certificate Authority (%s): %s", d.Id(), err) + } } if err := d.Set("tags", tags.IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { diff --git a/aws/resource_aws_acmpca_certificate_authority_test.go b/aws/resource_aws_acmpca_certificate_authority_test.go index 7487fe7b15a..6a25806c812 100644 --- a/aws/resource_aws_acmpca_certificate_authority_test.go +++ b/aws/resource_aws_acmpca_certificate_authority_test.go @@ -41,24 +41,45 @@ func testSweepAcmpcaCertificateAuthorities(region string) error { return nil } + var sweeperErrs *multierror.Error + for _, certificateAuthority := range certificateAuthorities { arn := aws.StringValue(certificateAuthority.Arn) + + if aws.StringValue(certificateAuthority.Status) == acmpca.CertificateAuthorityStatusActive { + log.Printf("[INFO] Disabling ACMPCA Certificate Authority: %s", arn) + _, err := conn.UpdateCertificateAuthority(&acmpca.UpdateCertificateAuthorityInput{ + CertificateAuthorityArn: aws.String(arn), + Status: aws.String(acmpca.CertificateAuthorityStatusDisabled), + }) + if isAWSErr(err, acmpca.ErrCodeResourceNotFoundException, "") { + continue + } + if err != nil { + sweeperErr := fmt.Errorf("error disabling ACMPCA Certificate Authority (%s): %w", arn, err) + log.Printf("[ERROR] %s", sweeperErr) + sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) + continue + } + } + log.Printf("[INFO] Deleting ACMPCA Certificate Authority: %s", arn) - input := &acmpca.DeleteCertificateAuthorityInput{ + _, err := conn.DeleteCertificateAuthority(&acmpca.DeleteCertificateAuthorityInput{ CertificateAuthorityArn: aws.String(arn), PermanentDeletionTimeInDays: aws.Int64(int64(7)), + }) + if isAWSErr(err, acmpca.ErrCodeResourceNotFoundException, "") { + continue } - - _, err := conn.DeleteCertificateAuthority(input) if err != nil { - if isAWSErr(err, acmpca.ErrCodeResourceNotFoundException, "") { - continue - } - log.Printf("[ERROR] Failed to delete ACMPCA Certificate Authority (%s): %s", arn, err) + sweeperErr := fmt.Errorf("error deleting ACMPCA Certificate Authority (%s): %w", arn, err) + log.Printf("[ERROR] %s", sweeperErr) + sweeperErrs = multierror.Append(sweeperErrs, sweeperErr) + continue } } - return nil + return sweeperErrs.ErrorOrNil() } func TestAccAwsAcmpcaCertificateAuthority_basic(t *testing.T) { From 78fac6715d700bcc5398fa2861c1da4f5c94e203 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 10 Jun 2020 17:40:46 -0400 Subject: [PATCH 14/21] Address TODOs. --- ...e_aws_acmpca_certificate_authority_test.go | 13 ++++++++++++ aws/resource_aws_appmesh_virtual_node_test.go | 20 ++++++++----------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/aws/resource_aws_acmpca_certificate_authority_test.go b/aws/resource_aws_acmpca_certificate_authority_test.go index 6a25806c812..9002ca59657 100644 --- a/aws/resource_aws_acmpca_certificate_authority_test.go +++ b/aws/resource_aws_acmpca_certificate_authority_test.go @@ -577,6 +577,19 @@ func testAccCheckAwsAcmpcaCertificateAuthorityActivateCA(certificateAuthority *a } } +func testAccCheckAwsAcmpcaCertificateAuthorityDisableCA(certificateAuthority *acmpca.CertificateAuthority) resource.TestCheckFunc { + return func(s *terraform.State) error { + conn := testAccProvider.Meta().(*AWSClient).acmpcaconn + + _, err := conn.UpdateCertificateAuthority(&acmpca.UpdateCertificateAuthorityInput{ + CertificateAuthorityArn: certificateAuthority.Arn, + Status: aws.String(acmpca.CertificateAuthorityStatusDisabled), + }) + + return err + } +} + func listAcmpcaCertificateAuthorities(conn *acmpca.ACMPCA) ([]*acmpca.CertificateAuthority, error) { certificateAuthorities := []*acmpca.CertificateAuthority{} input := &acmpca.ListCertificateAuthoritiesInput{} diff --git a/aws/resource_aws_appmesh_virtual_node_test.go b/aws/resource_aws_appmesh_virtual_node_test.go index 91fbbae79da..47c51fc6f81 100644 --- a/aws/resource_aws_appmesh_virtual_node_test.go +++ b/aws/resource_aws_appmesh_virtual_node_test.go @@ -395,8 +395,7 @@ func testAccAwsAppmeshVirtualNode_tls(t *testing.T) { Config: testAccAppmeshVirtualNodeConfigRootCA(vnName), Check: resource.ComposeTestCheckFunc( testAccCheckAwsAcmpcaCertificateAuthorityExists(acmCAResourceName, &ca), - // TODO - //testAccCheckAwsAcmpcaCertificateAuthorityActivateCA(&ca), + testAccCheckAwsAcmpcaCertificateAuthorityActivateCA(&ca), ), }, { @@ -424,10 +423,9 @@ func testAccAwsAppmeshVirtualNode_tls(t *testing.T) { }, { Config: testAccAppmeshVirtualNodeConfig_tlsAcm(meshName, vnName), - Check: resource.ComposeTestCheckFunc( - // CA must be DISABLED for deletion. - // TODO - //testAccCheckAwsAcmpcaCertificateAuthorityDisableCA(&ca), + Check: resource.ComposeTestCheckFunc( + // CA must be DISABLED for deletion. + testAccCheckAwsAcmpcaCertificateAuthorityDisableCA(&ca), ), ExpectNonEmptyPlan: true, }, @@ -583,8 +581,7 @@ func testAccAwsAppmeshVirtualNode_clientPolicyAcm(t *testing.T) { Config: testAccAppmeshVirtualNodeConfigRootCA(vnName), Check: resource.ComposeTestCheckFunc( testAccCheckAwsAcmpcaCertificateAuthorityExists(acmCAResourceName, &ca), - // TODO - //testAccCheckAwsAcmpcaCertificateAuthorityActivateCA(&ca), + testAccCheckAwsAcmpcaCertificateAuthorityActivateCA(&ca), ), }, { @@ -652,10 +649,9 @@ func testAccAwsAppmeshVirtualNode_clientPolicyAcm(t *testing.T) { }, { Config: testAccAppmeshVirtualNodeConfig_clientPolicyAcm(meshName, vnName), - Check: resource.ComposeTestCheckFunc( - // CA must be DISABLED for deletion. - // TODO - //testAccCheckAwsAcmpcaCertificateAuthorityDisableCA(&ca), + Check: resource.ComposeTestCheckFunc( + // CA must be DISABLED for deletion. + testAccCheckAwsAcmpcaCertificateAuthorityDisableCA(&ca), ), ExpectNonEmptyPlan: true, }, From 7849c500649b3e345bc6da9d1c2b9cb1d9193831 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 10 Jun 2020 17:44:17 -0400 Subject: [PATCH 15/21] 'flattenIntList' -> 'flattenInt64List' to match corresponding 'expand' function. --- aws/structure.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/aws/structure.go b/aws/structure.go index d270048abfe..95887c3058f 100644 --- a/aws/structure.go +++ b/aws/structure.go @@ -1075,7 +1075,7 @@ func flattenCaseInsensitiveStringSet(list []*string) *schema.Set { // Takes list of pointers to int64s. Expand to an array // of raw ints and returns a []interface{} // to keep compatibility w/ schema.NewSet -func flattenIntList(list []*int64) []interface{} { +func flattenInt64List(list []*int64) []interface{} { vs := make([]interface{}, 0, len(list)) for _, v := range list { vs = append(vs, int(aws.Int64Value(v))) @@ -1083,8 +1083,8 @@ func flattenIntList(list []*int64) []interface{} { return vs } -func flattenIntSet(list []*int64) *schema.Set { - return schema.NewSet(schema.HashInt, flattenIntList(list)) +func flattenInt64Set(list []*int64) *schema.Set { + return schema.NewSet(schema.HashInt, flattenInt64List(list)) } //Flattens an array of private ip addresses into a []string, where the elements returned are the IP strings e.g. "192.168.0.0" @@ -5228,7 +5228,7 @@ func flattenAppmeshClientPolicy(clientPolicy *appmesh.ClientPolicy) []interface{ if tls := clientPolicy.Tls; tls != nil { mTls := map[string]interface{}{ "enforce": aws.BoolValue(tls.Enforce), - "ports": flattenIntSet(tls.Ports), + "ports": flattenInt64Set(tls.Ports), } if validation := tls.Validation; validation != nil { From a5387f7bc7f8cb27fff7bead0f0fe746e3d8bc36 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 10 Jun 2020 17:53:19 -0400 Subject: [PATCH 16/21] Correct listener index in acceptance tests. --- aws/resource_aws_appmesh_virtual_node_test.go | 62 +++++++++---------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/aws/resource_aws_appmesh_virtual_node_test.go b/aws/resource_aws_appmesh_virtual_node_test.go index 47c51fc6f81..c66e87cafae 100644 --- a/aws/resource_aws_appmesh_virtual_node_test.go +++ b/aws/resource_aws_appmesh_virtual_node_test.go @@ -442,17 +442,17 @@ func testAccAwsAppmeshVirtualNode_tls(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.backend.2622272660.virtual_service.0.virtual_service_name", "servicea.simpleapp.local"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.health_check.#", "0"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.port_mapping.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.port_mapping.0.port", "8080"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.port_mapping.0.protocol", "http"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.tls.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.tls.0.certificate.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.tls.0.certificate.0.acm.#", "0"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.tls.0.certificate.0.file.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.tls.0.certificate.0.file.0.certificate_chain", "/cert_chain.pem"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.tls.0.certificate.0.file.0.private_key", "/key.pem"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.180467016.tls.0.mode", "PERMISSIVE"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.health_check.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.0.port", "8080"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.0.protocol", "http"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.tls.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.tls.0.certificate.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.tls.0.certificate.0.acm.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.tls.0.certificate.0.file.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.tls.0.certificate.0.file.0.certificate_chain", "/cert_chain.pem"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.tls.0.certificate.0.file.0.private_key", "/key.pem"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.tls.0.mode", "PERMISSIVE"), resource.TestCheckResourceAttr(resourceName, "spec.0.logging.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.#", "1"), @@ -504,11 +504,11 @@ func testAccAwsAppmeshVirtualNode_clientPolicyFile(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.backend.906924271.virtual_service.0.virtual_service_name", "servicea.simpleapp.local"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.health_check.#", "0"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.port_mapping.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.port_mapping.0.port", "8080"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.port_mapping.0.protocol", "http"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.tls.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.health_check.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.0.port", "8080"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.0.protocol", "http"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.tls.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.logging.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.#", "1"), @@ -540,11 +540,11 @@ func testAccAwsAppmeshVirtualNode_clientPolicyFile(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.virtual_service_name", "servicea.simpleapp.local"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.health_check.#", "0"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.port_mapping.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.port_mapping.0.port", "8080"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.port_mapping.0.protocol", "http"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.tls.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.health_check.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.0.port", "8080"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.0.protocol", "http"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.tls.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.logging.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.#", "1"), @@ -595,11 +595,11 @@ func testAccAwsAppmeshVirtualNode_clientPolicyAcm(t *testing.T) { testAccCheckAppmeshVirtualNodeClientPolicyAcmCertificateAuthorityArn(acmCAResourceName, "arn", &vn), resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.health_check.#", "0"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.port_mapping.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.port_mapping.0.port", "8080"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.port_mapping.0.protocol", "http"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.tls.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.health_check.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.0.port", "8080"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.0.protocol", "http"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.tls.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.logging.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.#", "1"), @@ -632,11 +632,11 @@ func testAccAwsAppmeshVirtualNode_clientPolicyAcm(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.sds.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.virtual_service_name", "servicea.simpleapp.local"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.health_check.#", "0"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.port_mapping.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.port_mapping.0.port", "8080"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.port_mapping.0.protocol", "http"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.2279702354.tls.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.health_check.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.0.port", "8080"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.0.protocol", "http"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.tls.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.logging.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.#", "1"), From 2acf980db954b4e1a8ad8e51af0eca2919c5cf00 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Mon, 15 Jun 2020 18:18:04 -0400 Subject: [PATCH 17/21] Use 'TestCheckTypeSetElemNestedAttrs'. --- aws/resource_aws_appmesh_virtual_node_test.go | 114 ++++++++++-------- 1 file changed, 63 insertions(+), 51 deletions(-) diff --git a/aws/resource_aws_appmesh_virtual_node_test.go b/aws/resource_aws_appmesh_virtual_node_test.go index c66e87cafae..0c74aa3a395 100644 --- a/aws/resource_aws_appmesh_virtual_node_test.go +++ b/aws/resource_aws_appmesh_virtual_node_test.go @@ -24,7 +24,7 @@ func init() { func testSweepAppmeshVirtualNodes(region string) error { client, err := sharedClientForRegion(region) if err != nil { - return fmt.Errorf("error getting client: %s", err) + return fmt.Errorf("error getting client: %w", err) } conn := client.(*AWSClient).appmeshconn @@ -79,7 +79,7 @@ func testSweepAppmeshVirtualNodes(region string) error { log.Printf("[WARN] Skipping Appmesh Virtual Node sweep for %s: %s", region, err) return nil } - return fmt.Errorf("error retrieving Appmesh Virtual Nodes: %s", err) + return fmt.Errorf("error retrieving Appmesh Virtual Nodes: %w", err) } return sweeperErrs.ErrorOrNil() @@ -202,8 +202,8 @@ func testAccAwsAppmeshVirtualNode_listenerHealthChecks(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "1"), tfawsresource.TestCheckTypeSetElemNestedAttrs(resourceName, "spec.0.backend.*", map[string]string{ - "virtual_service.client_policy.#": "0", "virtual_service.#": "1", + "virtual_service.0.client_policy.#": "0", "virtual_service.0.virtual_service_name": "servicea.simpleapp.local", }), resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.#", "0"), @@ -240,13 +240,13 @@ func testAccAwsAppmeshVirtualNode_listenerHealthChecks(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "2"), tfawsresource.TestCheckTypeSetElemNestedAttrs(resourceName, "spec.0.backend.*", map[string]string{ - "virtual_service.client_policy.#": "0", "virtual_service.#": "1", + "virtual_service.0.client_policy.#": "0", "virtual_service.0.virtual_service_name": "servicec.simpleapp.local", }), tfawsresource.TestCheckTypeSetElemNestedAttrs(resourceName, "spec.0.backend.*", map[string]string{ - "virtual_service.client_policy.#": "0", "virtual_service.#": "1", + "virtual_service.0.client_policy.#": "0", "virtual_service.0.virtual_service_name": "serviced.simpleapp.local", }), resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.#", "0"), @@ -390,7 +390,7 @@ func testAccAwsAppmeshVirtualNode_tls(t *testing.T) { Providers: testAccProviders, CheckDestroy: testAccCheckAppmeshVirtualNodeDestroy, Steps: []resource.TestStep{ - // We need to create and active the CA before issuing a certificate. + // We need to create and activate the CA before issuing a certificate. { Config: testAccAppmeshVirtualNodeConfigRootCA(vnName), Check: resource.ComposeTestCheckFunc( @@ -406,9 +406,11 @@ func testAccAwsAppmeshVirtualNode_tls(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.2622272660.virtual_service.client_policy.#", "0"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.2622272660.virtual_service.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.2622272660.virtual_service.0.virtual_service_name", "servicea.simpleapp.local"), + tfawsresource.TestCheckTypeSetElemNestedAttrs(resourceName, "spec.0.backend.*", map[string]string{ + "virtual_service.#": "1", + "virtual_service.0.client_policy.#": "0", + "virtual_service.0.virtual_service_name": "servicea.simpleapp.local", + }), resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.#", "1"), testAccCheckAppmeshVirtualNodeTlsAcmCertificateArn(acmCertificateResourceName, "arn", &vn), @@ -437,9 +439,11 @@ func testAccAwsAppmeshVirtualNode_tls(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.2622272660.virtual_service.client_policy.#", "0"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.2622272660.virtual_service.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.2622272660.virtual_service.0.virtual_service_name", "servicea.simpleapp.local"), + tfawsresource.TestCheckTypeSetElemNestedAttrs(resourceName, "spec.0.backend.*", map[string]string{ + "virtual_service.#": "1", + "virtual_service.0.client_policy.#": "0", + "virtual_service.0.virtual_service_name": "servicea.simpleapp.local", + }), resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.health_check.#", "0"), @@ -491,17 +495,20 @@ func testAccAwsAppmeshVirtualNode_clientPolicyFile(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.906924271.virtual_service.0.client_policy.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.906924271.virtual_service.0.client_policy.0.tls.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.906924271.virtual_service.0.client_policy.0.tls.0.enforce", "true"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.906924271.virtual_service.0.client_policy.0.tls.0.ports.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.906924271.virtual_service.0.client_policy.0.tls.0.ports.860082431", "8443"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.906924271.virtual_service.0.client_policy.0.tls.0.validation.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.906924271.virtual_service.0.client_policy.0.tls.0.validation.0.trust.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.906924271.virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.acm.#", "0"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.906924271.virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.file.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.906924271.virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.file.0.certificate_chain", "/cert_chain.pem"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.906924271.virtual_service.0.virtual_service_name", "servicea.simpleapp.local"), + tfawsresource.TestCheckTypeSetElemNestedAttrs(resourceName, "spec.0.backend.*", map[string]string{ + "virtual_service.#": "1", + "virtual_service.0.client_policy.#": "1", + "virtual_service.0.client_policy.0.tls.#": "1", + "virtual_service.0.client_policy.0.tls.0.enforce": "true", + "virtual_service.0.client_policy.0.tls.0.ports.#": "1", + "virtual_service.0.client_policy.0.tls.0.ports.860082431": "8443", + "virtual_service.0.client_policy.0.tls.0.validation.#": "1", + "virtual_service.0.client_policy.0.tls.0.validation.0.trust.#": "1", + "virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.acm.#": "0", + "virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.file.#": "1", + "virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.file.0.certificate_chain": "/cert_chain.pem", + "virtual_service.0.virtual_service_name": "servicea.simpleapp.local", + }), resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.health_check.#", "0"), @@ -526,18 +533,21 @@ func testAccAwsAppmeshVirtualNode_clientPolicyFile(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.enforce", "true"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.ports.#", "2"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.ports.3638101695", "443"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.ports.860082431", "8443"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.validation.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.validation.0.trust.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.acm.#", "0"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.file.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.file.0.certificate_chain", "/etc/ssl/certs/cert_chain.pem"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.virtual_service_name", "servicea.simpleapp.local"), + tfawsresource.TestCheckTypeSetElemNestedAttrs(resourceName, "spec.0.backend.*", map[string]string{ + "virtual_service.#": "1", + "virtual_service.0.client_policy.#": "1", + "virtual_service.0.client_policy.0.tls.#": "1", + "virtual_service.0.client_policy.0.tls.0.enforce": "true", + "virtual_service.0.client_policy.0.tls.0.ports.#": "2", + "virtual_service.0.client_policy.0.tls.0.ports.3638101695": "443", + "virtual_service.0.client_policy.0.tls.0.ports.860082431": "8443", + "virtual_service.0.client_policy.0.tls.0.validation.#": "1", + "virtual_service.0.client_policy.0.tls.0.validation.0.trust.#": "1", + "virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.acm.#": "0", + "virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.file.#": "1", + "virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.file.0.certificate_chain": "/etc/ssl/certs/cert_chain.pem", + "virtual_service.0.virtual_service_name": "servicea.simpleapp.local", + }), resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.health_check.#", "0"), @@ -618,19 +628,21 @@ func testAccAwsAppmeshVirtualNode_clientPolicyAcm(t *testing.T) { testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.enforce", "true"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.ports.#", "2"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.ports.3638101695", "443"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.ports.860082431", "8443"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.validation.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.validation.0.trust.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.acm.#", "0"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.file.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.file.0.certificate_chain", "/etc/ssl/certs/cert_chain.pem"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.sds.#", "0"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.3920410102.virtual_service.0.virtual_service_name", "servicea.simpleapp.local"), + tfawsresource.TestCheckTypeSetElemNestedAttrs(resourceName, "spec.0.backend.*", map[string]string{ + "virtual_service.#": "1", + "virtual_service.0.client_policy.#": "1", + "virtual_service.0.client_policy.0.tls.#": "1", + "virtual_service.0.client_policy.0.tls.0.enforce": "true", + "virtual_service.0.client_policy.0.tls.0.ports.#": "2", + "virtual_service.0.client_policy.0.tls.0.ports.3638101695": "443", + "virtual_service.0.client_policy.0.tls.0.ports.860082431": "8443", + "virtual_service.0.client_policy.0.tls.0.validation.#": "1", + "virtual_service.0.client_policy.0.tls.0.validation.0.trust.#": "1", + "virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.acm.#": "0", + "virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.file.#": "1", + "virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.file.0.certificate_chain": "/etc/ssl/certs/cert_chain.pem", + "virtual_service.0.virtual_service_name": "servicea.simpleapp.local", + }), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.health_check.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.#", "1"), @@ -689,7 +701,7 @@ func testAccAwsAppmeshVirtualNode_backendDefaults(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.0.client_policy.0.tls.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.0.client_policy.0.tls.0.enforce", "true"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.0.client_policy.0.tls.0.ports.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.0.client_policy.0.tls.0.ports.860082431", "8443"), + tfawsresource.TestCheckTypeSetElemAttr(resourceName, "spec.0.backend_defaults.0.client_policy.0.tls.0.ports.*", "8443"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.0.client_policy.0.tls.0.validation.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.0.client_policy.0.tls.0.validation.0.trust.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.0.client_policy.0.tls.0.validation.0.trust.0.acm.#", "0"), @@ -716,8 +728,8 @@ func testAccAwsAppmeshVirtualNode_backendDefaults(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.0.client_policy.0.tls.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.0.client_policy.0.tls.0.enforce", "true"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.0.client_policy.0.tls.0.ports.#", "2"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.0.client_policy.0.tls.0.ports.3638101695", "443"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.0.client_policy.0.tls.0.ports.860082431", "8443"), + tfawsresource.TestCheckTypeSetElemAttr(resourceName, "spec.0.backend_defaults.0.client_policy.0.tls.0.ports.*", "443"), + tfawsresource.TestCheckTypeSetElemAttr(resourceName, "spec.0.backend_defaults.0.client_policy.0.tls.0.ports.*", "8443"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.0.client_policy.0.tls.0.validation.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.0.client_policy.0.tls.0.validation.0.trust.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.0.client_policy.0.tls.0.validation.0.trust.0.acm.#", "0"), From f31af933cd814bdd4b151e4b066bcef902652a64 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Sun, 26 Jul 2020 16:57:56 -0400 Subject: [PATCH 18/21] r/aws_appmesh_virtual_node: Fix 'testAccAwsAppmeshVirtualNode_clientPolicyAcm'. --- ...source_aws_acmpca_certificate_authority.go | 5 +--- aws/resource_aws_appmesh_virtual_node_test.go | 30 +++++++++++++------ 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/aws/resource_aws_acmpca_certificate_authority.go b/aws/resource_aws_acmpca_certificate_authority.go index 2ab42469d82..a2ea02cfae9 100644 --- a/aws/resource_aws_acmpca_certificate_authority.go +++ b/aws/resource_aws_acmpca_certificate_authority.go @@ -410,10 +410,7 @@ func resourceAwsAcmpcaCertificateAuthorityRead(d *schema.ResourceData, meta inte tags, err := keyvaluetags.AcmpcaListTags(conn, d.Id()) if err != nil { - if !isAWSErr(err, acmpca.ErrCodeInvalidStateException, "") { - // InvalidStateException: The certificate authority is in the DELETED state and must be restored to complete this action. - return fmt.Errorf("error listing tags for ACMPCA Certificate Authority (%s): %s", d.Id(), err) - } + return fmt.Errorf("error listing tags for ACMPCA Certificate Authority (%s): %s", d.Id(), err) } if err := d.Set("tags", tags.IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { diff --git a/aws/resource_aws_appmesh_virtual_node_test.go b/aws/resource_aws_appmesh_virtual_node_test.go index 0c74aa3a395..ad62a4713ed 100644 --- a/aws/resource_aws_appmesh_virtual_node_test.go +++ b/aws/resource_aws_appmesh_virtual_node_test.go @@ -8,6 +8,7 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/acmpca" "github.com/aws/aws-sdk-go/service/appmesh" + "github.com/hashicorp/go-multierror" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" @@ -423,6 +424,12 @@ func testAccAwsAppmeshVirtualNode_tls(t *testing.T) { testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), ), }, + { + ResourceName: resourceName, + ImportStateId: fmt.Sprintf("%s/%s", meshName, vnName), + ImportState: true, + ImportStateVerify: true, + }, { Config: testAccAppmeshVirtualNodeConfig_tlsAcm(meshName, vnName), Check: resource.ComposeTestCheckFunc( @@ -619,13 +626,26 @@ func testAccAwsAppmeshVirtualNode_clientPolicyAcm(t *testing.T) { testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), ), }, + { + ResourceName: resourceName, + ImportStateId: fmt.Sprintf("%s/%s", meshName, vnName), + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAppmeshVirtualNodeConfig_clientPolicyAcm(meshName, vnName), + Check: resource.ComposeTestCheckFunc( + // CA must be DISABLED for deletion. + testAccCheckAwsAcmpcaCertificateAuthorityDisableCA(&ca), + ), + ExpectNonEmptyPlan: true, + }, { Config: testAccAppmeshVirtualNodeConfig_clientPolicyFileUpdated(meshName, vnName), Check: resource.ComposeTestCheckFunc( testAccCheckAppmeshVirtualNodeExists(resourceName, &vn), resource.TestCheckResourceAttr(resourceName, "name", vnName), resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), - testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "1"), tfawsresource.TestCheckTypeSetElemNestedAttrs(resourceName, "spec.0.backend.*", map[string]string{ @@ -659,14 +679,6 @@ func testAccAwsAppmeshVirtualNode_clientPolicyAcm(t *testing.T) { testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh-preview", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), ), }, - { - Config: testAccAppmeshVirtualNodeConfig_clientPolicyAcm(meshName, vnName), - Check: resource.ComposeTestCheckFunc( - // CA must be DISABLED for deletion. - testAccCheckAwsAcmpcaCertificateAuthorityDisableCA(&ca), - ), - ExpectNonEmptyPlan: true, - }, { ResourceName: resourceName, ImportStateId: fmt.Sprintf("%s/%s", meshName, vnName), From fb6ad397b655c9d8670ec7f1b0aeaa199714faa3 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 18 Sep 2020 15:13:58 -0400 Subject: [PATCH 19/21] r/aws_appmesh_virtual_node: Delete 'appmeshVirtualNodeBackendHash'. --- aws/resource_aws_appmesh_virtual_node.go | 59 +------------------ ...source_aws_appmesh_virtual_node_migrate.go | 11 ++-- ...e_aws_appmesh_virtual_node_migrate_test.go | 12 ++-- aws/structure.go | 2 +- 4 files changed, 14 insertions(+), 70 deletions(-) diff --git a/aws/resource_aws_appmesh_virtual_node.go b/aws/resource_aws_appmesh_virtual_node.go index 736fa467092..74fe9f9f824 100644 --- a/aws/resource_aws_appmesh_virtual_node.go +++ b/aws/resource_aws_appmesh_virtual_node.go @@ -1,7 +1,6 @@ package aws import ( - "bytes" "fmt" "log" "strings" @@ -11,7 +10,6 @@ import ( "github.com/aws/aws-sdk-go/service/appmesh" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" - "github.com/terraform-providers/terraform-provider-aws/aws/internal/hashcode" "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" ) @@ -84,7 +82,6 @@ func resourceAwsAppmeshVirtualNode() *schema.Resource { }, }, }, - Set: appmeshVirtualNodeBackendHash, }, "backend_defaults": { @@ -242,13 +239,9 @@ func resourceAwsAppmeshVirtualNode() *schema.Resource { }, "mode": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validation.StringInSlice([]string{ - appmesh.ListenerTlsModeDisabled, - appmesh.ListenerTlsModePermissive, - appmesh.ListenerTlsModeStrict, - }, false), + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice(appmesh.ListenerTlsMode_Values(), false), }, }, }, @@ -620,49 +613,3 @@ func resourceAwsAppmeshVirtualNodeImport(d *schema.ResourceData, meta interface{ return []*schema.ResourceData{d}, nil } - -func appmeshVirtualNodeBackendHash(vBackend interface{}) int { - var buf bytes.Buffer - mBackend := vBackend.(map[string]interface{}) - if vVirtualService, ok := mBackend["virtual_service"].([]interface{}); ok && len(vVirtualService) > 0 && vVirtualService[0] != nil { - mVirtualService := vVirtualService[0].(map[string]interface{}) - if v, ok := mVirtualService["virtual_service_name"].(string); ok { - buf.WriteString(fmt.Sprintf("%s-", v)) - } - if vClientPolicy, ok := mVirtualService["client_policy"].([]interface{}); ok && len(vClientPolicy) > 0 && vClientPolicy[0] != nil { - mClientPolicy := vClientPolicy[0].(map[string]interface{}) - if vTls, ok := mClientPolicy["tls"].([]interface{}); ok && len(vTls) > 0 && vTls[0] != nil { - mTls := vTls[0].(map[string]interface{}) - if v, ok := mTls["enforce"].(bool); ok { - buf.WriteString(fmt.Sprintf("%t-", v)) - } - if v, ok := mTls["ports"].(*schema.Set); ok && v.Len() > 0 { - for _, port := range v.List() { - buf.WriteString(fmt.Sprintf("%d-", port.(int))) - } - } - if vValidation, ok := mTls["validation"].([]interface{}); ok && len(vValidation) > 0 && vValidation[0] != nil { - mValidation := vValidation[0].(map[string]interface{}) - if vTrust, ok := mValidation["trust"].([]interface{}); ok && len(vTrust) > 0 && vTrust[0] != nil { - mTrust := vTrust[0].(map[string]interface{}) - if vAcm, ok := mTrust["acm"].([]interface{}); ok && len(vAcm) > 0 && vAcm[0] != nil { - mAcm := vAcm[0].(map[string]interface{}) - if v, ok := mAcm["certificate_authority_arns"].(*schema.Set); ok && v.Len() > 0 { - for _, arn := range v.List() { - buf.WriteString(fmt.Sprintf("%s-", arn.(string))) - } - } - } - if vFile, ok := mTrust["file"].([]interface{}); ok && len(vFile) > 0 && vFile[0] != nil { - mFile := vFile[0].(map[string]interface{}) - if v, ok := mFile["certificate_chain"].(string); ok { - buf.WriteString(fmt.Sprintf("%s-", v)) - } - } - } - } - } - } - } - return hashcode.String(buf.String()) -} diff --git a/aws/resource_aws_appmesh_virtual_node_migrate.go b/aws/resource_aws_appmesh_virtual_node_migrate.go index 2619070f713..5df2ad4ccaa 100644 --- a/aws/resource_aws_appmesh_virtual_node_migrate.go +++ b/aws/resource_aws_appmesh_virtual_node_migrate.go @@ -27,16 +27,13 @@ func migrateAppmeshVirtualNodeStateV0toV1(is *terraform.InstanceState) (*terrafo log.Printf("[DEBUG] Attributes before migration: %#v", is.Attributes) is.Attributes["spec.0.backend.#"] = is.Attributes["spec.0.backends.#"] delete(is.Attributes, "spec.0.backends.#") + i := 0 for k, v := range is.Attributes { if strings.HasPrefix(k, "spec.0.backends.") { - hash := appmeshVirtualNodeBackendHash(map[string]interface{}{ - "virtual_service": []interface{}{map[string]interface{}{ - "virtual_service_name": v, - }}, - }) - is.Attributes[fmt.Sprintf("spec.0.backend.%d.virtual_service.#", hash)] = "1" - is.Attributes[fmt.Sprintf("spec.0.backend.%d.virtual_service.0.virtual_service_name", hash)] = v + is.Attributes[fmt.Sprintf("spec.0.backend.%d.virtual_service.#", i)] = "1" + is.Attributes[fmt.Sprintf("spec.0.backend.%d.virtual_service.0.virtual_service_name", i)] = v delete(is.Attributes, k) + i++ } } diff --git a/aws/resource_aws_appmesh_virtual_node_migrate_test.go b/aws/resource_aws_appmesh_virtual_node_migrate_test.go index 959ad31bb79..7ad2573905d 100644 --- a/aws/resource_aws_appmesh_virtual_node_migrate_test.go +++ b/aws/resource_aws_appmesh_virtual_node_migrate_test.go @@ -34,12 +34,12 @@ func TestAWSAppmeshVirtualNodeMigrateState(t *testing.T) { "spec.0.service_discovery.0.dns.0.service_name": "serviceb.simpleapp.local", }, Expected: map[string]string{ - "spec.0.backend.#": "1", - "spec.0.backend.2622272660.virtual_service.#": "1", - "spec.0.backend.2622272660.virtual_service.0.virtual_service_name": "servicea.simpleapp.local", - "spec.0.service_discovery.#": "1", - "spec.0.service_discovery.0.dns.#": "1", - "spec.0.service_discovery.0.dns.0.hostname": "serviceb.simpleapp.local", + "spec.0.backend.#": "1", + "spec.0.backend.0.virtual_service.#": "1", + "spec.0.backend.0.virtual_service.0.virtual_service_name": "servicea.simpleapp.local", + "spec.0.service_discovery.#": "1", + "spec.0.service_discovery.0.dns.#": "1", + "spec.0.service_discovery.0.dns.0.hostname": "serviceb.simpleapp.local", }, }, } diff --git a/aws/structure.go b/aws/structure.go index 95887c3058f..66167076138 100644 --- a/aws/structure.go +++ b/aws/structure.go @@ -4996,7 +4996,7 @@ func flattenAppmeshVirtualNodeSpec(spec *appmesh.VirtualNodeSpec) []interface{} vBackends = append(vBackends, mBackend) } - mSpec["backend"] = schema.NewSet(appmeshVirtualNodeBackendHash, vBackends) + mSpec["backend"] = vBackends } if backendDefaults := spec.BackendDefaults; backendDefaults != nil { From 9b8caf6c27c6e2df000ee61d3de4d2aa78d44572 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Fri, 18 Sep 2020 15:14:44 -0400 Subject: [PATCH 20/21] r/aws_appmesh_virtual_node: Tidy up acceptance tests. --- ...e_aws_acmpca_certificate_authority_test.go | 13 -- aws/resource_aws_appmesh_virtual_node_test.go | 157 +++++++----------- 2 files changed, 62 insertions(+), 108 deletions(-) diff --git a/aws/resource_aws_acmpca_certificate_authority_test.go b/aws/resource_aws_acmpca_certificate_authority_test.go index 9002ca59657..6a25806c812 100644 --- a/aws/resource_aws_acmpca_certificate_authority_test.go +++ b/aws/resource_aws_acmpca_certificate_authority_test.go @@ -577,19 +577,6 @@ func testAccCheckAwsAcmpcaCertificateAuthorityActivateCA(certificateAuthority *a } } -func testAccCheckAwsAcmpcaCertificateAuthorityDisableCA(certificateAuthority *acmpca.CertificateAuthority) resource.TestCheckFunc { - return func(s *terraform.State) error { - conn := testAccProvider.Meta().(*AWSClient).acmpcaconn - - _, err := conn.UpdateCertificateAuthority(&acmpca.UpdateCertificateAuthorityInput{ - CertificateAuthorityArn: certificateAuthority.Arn, - Status: aws.String(acmpca.CertificateAuthorityStatusDisabled), - }) - - return err - } -} - func listAcmpcaCertificateAuthorities(conn *acmpca.ACMPCA) ([]*acmpca.CertificateAuthority, error) { certificateAuthorities := []*acmpca.CertificateAuthority{} input := &acmpca.ListCertificateAuthoritiesInput{} diff --git a/aws/resource_aws_appmesh_virtual_node_test.go b/aws/resource_aws_appmesh_virtual_node_test.go index ad62a4713ed..15c875ff21f 100644 --- a/aws/resource_aws_appmesh_virtual_node_test.go +++ b/aws/resource_aws_appmesh_virtual_node_test.go @@ -391,20 +391,13 @@ func testAccAwsAppmeshVirtualNode_tls(t *testing.T) { Providers: testAccProviders, CheckDestroy: testAccCheckAppmeshVirtualNodeDestroy, Steps: []resource.TestStep{ - // We need to create and activate the CA before issuing a certificate. { - Config: testAccAppmeshVirtualNodeConfigRootCA(vnName), - Check: resource.ComposeTestCheckFunc( - testAccCheckAwsAcmpcaCertificateAuthorityExists(acmCAResourceName, &ca), - testAccCheckAwsAcmpcaCertificateAuthorityActivateCA(&ca), - ), - }, - { - Config: testAccAppmeshVirtualNodeConfig_tlsAcm(meshName, vnName), + Config: testAccAppmeshVirtualNodeConfig_tlsFile(meshName, vnName), Check: resource.ComposeTestCheckFunc( testAccCheckAppmeshVirtualNodeExists(resourceName, &vn), resource.TestCheckResourceAttr(resourceName, "name", vnName), resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), + testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "1"), tfawsresource.TestCheckTypeSetElemNestedAttrs(resourceName, "spec.0.backend.*", map[string]string{ @@ -414,13 +407,24 @@ func testAccAwsAppmeshVirtualNode_tls(t *testing.T) { }), resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.#", "1"), - testAccCheckAppmeshVirtualNodeTlsAcmCertificateArn(acmCertificateResourceName, "arn", &vn), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.health_check.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.0.port", "8080"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.0.protocol", "http"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.tls.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.tls.0.certificate.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.tls.0.certificate.0.acm.#", "0"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.tls.0.certificate.0.file.#", "1"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.tls.0.certificate.0.file.0.certificate_chain", "/cert_chain.pem"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.tls.0.certificate.0.file.0.private_key", "/key.pem"), + resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.tls.0.mode", "PERMISSIVE"), resource.TestCheckResourceAttr(resourceName, "spec.0.logging.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.0.hostname", "serviceb.simpleapp.local"), resource.TestCheckResourceAttrSet(resourceName, "created_date"), resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), + testAccCheckResourceAttrAccountID(resourceName, "resource_owner"), testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), ), }, @@ -430,20 +434,21 @@ func testAccAwsAppmeshVirtualNode_tls(t *testing.T) { ImportState: true, ImportStateVerify: true, }, + // We need to create and activate the CA before issuing a certificate. { - Config: testAccAppmeshVirtualNodeConfig_tlsAcm(meshName, vnName), + Config: testAccAppmeshVirtualNodeConfigRootCA(vnName), Check: resource.ComposeTestCheckFunc( - // CA must be DISABLED for deletion. - testAccCheckAwsAcmpcaCertificateAuthorityDisableCA(&ca), + testAccCheckAwsAcmpcaCertificateAuthorityExists(acmCAResourceName, &ca), + testAccCheckAwsAcmpcaCertificateAuthorityActivateCA(&ca), ), - ExpectNonEmptyPlan: true, }, { - Config: testAccAppmeshVirtualNodeConfig_tlsFile(meshName, vnName), + Config: testAccAppmeshVirtualNodeConfig_tlsAcm(meshName, vnName), Check: resource.ComposeTestCheckFunc( testAccCheckAppmeshVirtualNodeExists(resourceName, &vn), resource.TestCheckResourceAttr(resourceName, "name", vnName), resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), + testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "1"), tfawsresource.TestCheckTypeSetElemNestedAttrs(resourceName, "spec.0.backend.*", map[string]string{ @@ -453,23 +458,14 @@ func testAccAwsAppmeshVirtualNode_tls(t *testing.T) { }), resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.listener.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.health_check.#", "0"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.0.port", "8080"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.0.protocol", "http"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.tls.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.tls.0.certificate.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.tls.0.certificate.0.acm.#", "0"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.tls.0.certificate.0.file.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.tls.0.certificate.0.file.0.certificate_chain", "/cert_chain.pem"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.tls.0.certificate.0.file.0.private_key", "/key.pem"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.tls.0.mode", "PERMISSIVE"), + testAccCheckAppmeshVirtualNodeTlsAcmCertificateArn(acmCertificateResourceName, "arn", &vn), resource.TestCheckResourceAttr(resourceName, "spec.0.logging.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.0.hostname", "serviceb.simpleapp.local"), resource.TestCheckResourceAttrSet(resourceName, "created_date"), resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), + testAccCheckResourceAttrAccountID(resourceName, "resource_owner"), testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), ), }, @@ -479,6 +475,14 @@ func testAccAwsAppmeshVirtualNode_tls(t *testing.T) { ImportState: true, ImportStateVerify: true, }, + { + Config: testAccAppmeshVirtualNodeConfig_tlsAcm(meshName, vnName), + Check: resource.ComposeTestCheckFunc( + // CA must be DISABLED for deletion. + testAccCheckAwsAcmpcaCertificateAuthorityDisableCA(&ca), + ), + ExpectNonEmptyPlan: true, + }, }, }) } @@ -500,6 +504,7 @@ func testAccAwsAppmeshVirtualNode_clientPolicyFile(t *testing.T) { testAccCheckAppmeshVirtualNodeExists(resourceName, &vn), resource.TestCheckResourceAttr(resourceName, "name", vnName), resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), + testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "1"), tfawsresource.TestCheckTypeSetElemNestedAttrs(resourceName, "spec.0.backend.*", map[string]string{ @@ -508,7 +513,6 @@ func testAccAwsAppmeshVirtualNode_clientPolicyFile(t *testing.T) { "virtual_service.0.client_policy.0.tls.#": "1", "virtual_service.0.client_policy.0.tls.0.enforce": "true", "virtual_service.0.client_policy.0.tls.0.ports.#": "1", - "virtual_service.0.client_policy.0.tls.0.ports.860082431": "8443", "virtual_service.0.client_policy.0.tls.0.validation.#": "1", "virtual_service.0.client_policy.0.tls.0.validation.0.trust.#": "1", "virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.acm.#": "0", @@ -529,6 +533,7 @@ func testAccAwsAppmeshVirtualNode_clientPolicyFile(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.0.hostname", "serviceb.simpleapp.local"), resource.TestCheckResourceAttrSet(resourceName, "created_date"), resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), + testAccCheckResourceAttrAccountID(resourceName, "resource_owner"), testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), ), }, @@ -538,6 +543,7 @@ func testAccAwsAppmeshVirtualNode_clientPolicyFile(t *testing.T) { testAccCheckAppmeshVirtualNodeExists(resourceName, &vn), resource.TestCheckResourceAttr(resourceName, "name", vnName), resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), + testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "1"), tfawsresource.TestCheckTypeSetElemNestedAttrs(resourceName, "spec.0.backend.*", map[string]string{ @@ -546,8 +552,6 @@ func testAccAwsAppmeshVirtualNode_clientPolicyFile(t *testing.T) { "virtual_service.0.client_policy.0.tls.#": "1", "virtual_service.0.client_policy.0.tls.0.enforce": "true", "virtual_service.0.client_policy.0.tls.0.ports.#": "2", - "virtual_service.0.client_policy.0.tls.0.ports.3638101695": "443", - "virtual_service.0.client_policy.0.tls.0.ports.860082431": "8443", "virtual_service.0.client_policy.0.tls.0.validation.#": "1", "virtual_service.0.client_policy.0.tls.0.validation.0.trust.#": "1", "virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.acm.#": "0", @@ -568,6 +572,7 @@ func testAccAwsAppmeshVirtualNode_clientPolicyFile(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.0.hostname", "serviceb.simpleapp.local"), resource.TestCheckResourceAttrSet(resourceName, "created_date"), resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), + testAccCheckResourceAttrAccountID(resourceName, "resource_owner"), testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), ), }, @@ -594,6 +599,7 @@ func testAccAwsAppmeshVirtualNode_clientPolicyAcm(t *testing.T) { Providers: testAccProviders, CheckDestroy: testAccCheckAppmeshVirtualNodeDestroy, Steps: []resource.TestStep{ + // We need to create and activate the CA before issuing a certificate. { Config: testAccAppmeshVirtualNodeConfigRootCA(vnName), Check: resource.ComposeTestCheckFunc( @@ -607,6 +613,7 @@ func testAccAwsAppmeshVirtualNode_clientPolicyAcm(t *testing.T) { testAccCheckAppmeshVirtualNodeExists(resourceName, &vn), resource.TestCheckResourceAttr(resourceName, "name", vnName), resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), + testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "1"), testAccCheckAppmeshVirtualNodeClientPolicyAcmCertificateAuthorityArn(acmCAResourceName, "arn", &vn), @@ -623,6 +630,7 @@ func testAccAwsAppmeshVirtualNode_clientPolicyAcm(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.0.hostname", "serviceb.simpleapp.local"), resource.TestCheckResourceAttrSet(resourceName, "created_date"), resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), + testAccCheckResourceAttrAccountID(resourceName, "resource_owner"), testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), ), }, @@ -640,51 +648,6 @@ func testAccAwsAppmeshVirtualNode_clientPolicyAcm(t *testing.T) { ), ExpectNonEmptyPlan: true, }, - { - Config: testAccAppmeshVirtualNodeConfig_clientPolicyFileUpdated(meshName, vnName), - Check: resource.ComposeTestCheckFunc( - testAccCheckAppmeshVirtualNodeExists(resourceName, &vn), - resource.TestCheckResourceAttr(resourceName, "name", vnName), - resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), - resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "1"), - tfawsresource.TestCheckTypeSetElemNestedAttrs(resourceName, "spec.0.backend.*", map[string]string{ - "virtual_service.#": "1", - "virtual_service.0.client_policy.#": "1", - "virtual_service.0.client_policy.0.tls.#": "1", - "virtual_service.0.client_policy.0.tls.0.enforce": "true", - "virtual_service.0.client_policy.0.tls.0.ports.#": "2", - "virtual_service.0.client_policy.0.tls.0.ports.3638101695": "443", - "virtual_service.0.client_policy.0.tls.0.ports.860082431": "8443", - "virtual_service.0.client_policy.0.tls.0.validation.#": "1", - "virtual_service.0.client_policy.0.tls.0.validation.0.trust.#": "1", - "virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.acm.#": "0", - "virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.file.#": "1", - "virtual_service.0.client_policy.0.tls.0.validation.0.trust.0.file.0.certificate_chain": "/etc/ssl/certs/cert_chain.pem", - "virtual_service.0.virtual_service_name": "servicea.simpleapp.local", - }), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.health_check.#", "0"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.0.port", "8080"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.port_mapping.0.protocol", "http"), - resource.TestCheckResourceAttr(resourceName, "spec.0.listener.0.tls.#", "0"), - resource.TestCheckResourceAttr(resourceName, "spec.0.logging.#", "0"), - resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.#", "1"), - resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.0.dns.0.hostname", "serviceb.simpleapp.local"), - resource.TestCheckResourceAttrSet(resourceName, "created_date"), - resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), - testAccCheckResourceAttrAccountID(resourceName, "resource_owner"), - testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh-preview", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), - ), - }, - { - ResourceName: resourceName, - ImportStateId: fmt.Sprintf("%s/%s", meshName, vnName), - ImportState: true, - ImportStateVerify: true, - }, }, }) } @@ -706,6 +669,7 @@ func testAccAwsAppmeshVirtualNode_backendDefaults(t *testing.T) { testAccCheckAppmeshVirtualNodeExists(resourceName, &vn), resource.TestCheckResourceAttr(resourceName, "name", vnName), resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), + testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.#", "1"), @@ -724,6 +688,7 @@ func testAccAwsAppmeshVirtualNode_backendDefaults(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.#", "0"), resource.TestCheckResourceAttrSet(resourceName, "created_date"), resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), + testAccCheckResourceAttrAccountID(resourceName, "resource_owner"), testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), ), }, @@ -733,6 +698,7 @@ func testAccAwsAppmeshVirtualNode_backendDefaults(t *testing.T) { testAccCheckAppmeshVirtualNodeExists(resourceName, &vn), resource.TestCheckResourceAttr(resourceName, "name", vnName), resource.TestCheckResourceAttr(resourceName, "mesh_name", meshName), + testAccCheckResourceAttrAccountID(resourceName, "mesh_owner"), resource.TestCheckResourceAttr(resourceName, "spec.#", "1"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend.#", "0"), resource.TestCheckResourceAttr(resourceName, "spec.0.backend_defaults.#", "1"), @@ -752,6 +718,7 @@ func testAccAwsAppmeshVirtualNode_backendDefaults(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "spec.0.service_discovery.#", "0"), resource.TestCheckResourceAttrSet(resourceName, "created_date"), resource.TestCheckResourceAttrSet(resourceName, "last_updated_date"), + testAccCheckResourceAttrAccountID(resourceName, "resource_owner"), testAccCheckResourceAttrRegionalARN(resourceName, "arn", "appmesh", fmt.Sprintf("mesh/%s/virtualNode/%s", meshName, vnName)), ), }, @@ -882,7 +849,7 @@ resource "aws_acmpca_certificate_authority" "test" { certificate_authority_configuration { key_algorithm = "RSA_4096" - signing_algorithm = "SHA512WITHRSA" + signing_algorithm = "SHA512WITHRSA" subject { common_name = "%[1]s.com" @@ -896,7 +863,7 @@ func testAccAppmeshVirtualNodeConfigPrivateCert(rName string) string { return fmt.Sprintf(` resource "aws_acm_certificate" "test" { domain_name = "test.%[1]s.com" - certificate_authority_arn = "${aws_acmpca_certificate_authority.test.arn}" + certificate_authority_arn = aws_acmpca_certificate_authority.test.arn } `, rName) } @@ -1090,10 +1057,10 @@ resource "aws_appmesh_virtual_node" "test" { } func testAccAppmeshVirtualNodeConfig_tlsFile(meshName, vnName string) string { - return testAccAppmeshVirtualNodeConfig_mesh(meshName) + fmt.Sprintf(` + return composeConfig(testAccAppmeshVirtualNodeConfig_mesh(meshName), fmt.Sprintf(` resource "aws_appmesh_virtual_node" "test" { name = %[1]q - mesh_name = "${aws_appmesh_mesh.test.id}" + mesh_name = aws_appmesh_mesh.test.id spec { backend { @@ -1127,7 +1094,7 @@ resource "aws_appmesh_virtual_node" "test" { } } } -`, vnName) +`, vnName)) } func testAccAppmeshVirtualNodeConfig_tlsAcm(meshName, vnName string) string { @@ -1138,7 +1105,7 @@ func testAccAppmeshVirtualNodeConfig_tlsAcm(meshName, vnName string) string { fmt.Sprintf(` resource "aws_appmesh_virtual_node" "test" { name = %[1]q - mesh_name = "${aws_appmesh_mesh.test.id}" + mesh_name = aws_appmesh_mesh.test.id spec { backend { @@ -1156,7 +1123,7 @@ resource "aws_appmesh_virtual_node" "test" { tls { certificate { acm { - certificate_arn = "${aws_acm_certificate.test.arn}" + certificate_arn = aws_acm_certificate.test.arn } } @@ -1175,10 +1142,10 @@ resource "aws_appmesh_virtual_node" "test" { } func testAccAppmeshVirtualNodeConfig_clientPolicyFile(meshName, vnName string) string { - return testAccAppmeshVirtualNodeConfig_mesh(meshName) + fmt.Sprintf(` + return composeConfig(testAccAppmeshVirtualNodeConfig_mesh(meshName), fmt.Sprintf(` resource "aws_appmesh_virtual_node" "test" { name = %[1]q - mesh_name = "${aws_appmesh_mesh.test.id}" + mesh_name = aws_appmesh_mesh.test.id spec { backend { @@ -1215,14 +1182,14 @@ resource "aws_appmesh_virtual_node" "test" { } } } -`, vnName) +`, vnName)) } func testAccAppmeshVirtualNodeConfig_clientPolicyFileUpdated(meshName, vnName string) string { - return testAccAppmeshVirtualNodeConfig_mesh(meshName) + fmt.Sprintf(` + return composeConfig(testAccAppmeshVirtualNodeConfig_mesh(meshName), fmt.Sprintf(` resource "aws_appmesh_virtual_node" "test" { name = %[1]q - mesh_name = "${aws_appmesh_mesh.test.id}" + mesh_name = aws_appmesh_mesh.test.id spec { backend { @@ -1259,7 +1226,7 @@ resource "aws_appmesh_virtual_node" "test" { } } } -`, vnName) +`, vnName)) } func testAccAppmeshVirtualNodeConfig_clientPolicyAcm(meshName, vnName string) string { @@ -1270,7 +1237,7 @@ func testAccAppmeshVirtualNodeConfig_clientPolicyAcm(meshName, vnName string) st fmt.Sprintf(` resource "aws_appmesh_virtual_node" "test" { name = %[1]q - mesh_name = "${aws_appmesh_mesh.test.id}" + mesh_name = aws_appmesh_mesh.test.id spec { backend { @@ -1284,7 +1251,7 @@ resource "aws_appmesh_virtual_node" "test" { validation { trust { acm { - certificate_authority_arns = ["${aws_acmpca_certificate_authority.test.arn}"] + certificate_authority_arns = [aws_acmpca_certificate_authority.test.arn] } } } @@ -1311,10 +1278,10 @@ resource "aws_appmesh_virtual_node" "test" { } func testAccAppmeshVirtualNodeConfig_backendDefaults(meshName, vnName string) string { - return testAccAppmeshVirtualNodeConfig_mesh(meshName) + fmt.Sprintf(` + return composeConfig(testAccAppmeshVirtualNodeConfig_mesh(meshName), fmt.Sprintf(` resource "aws_appmesh_virtual_node" "test" { name = %[1]q - mesh_name = "${aws_appmesh_mesh.test.id}" + mesh_name = aws_appmesh_mesh.test.id spec { backend_defaults { @@ -1334,14 +1301,14 @@ resource "aws_appmesh_virtual_node" "test" { } } } -`, vnName) +`, vnName)) } func testAccAppmeshVirtualNodeConfig_backendDefaultsUpdated(meshName, vnName string) string { - return testAccAppmeshVirtualNodeConfig_mesh(meshName) + fmt.Sprintf(` + return composeConfig(testAccAppmeshVirtualNodeConfig_mesh(meshName), fmt.Sprintf(` resource "aws_appmesh_virtual_node" "test" { name = %[1]q - mesh_name = "${aws_appmesh_mesh.test.id}" + mesh_name = aws_appmesh_mesh.test.id spec { backend_defaults { @@ -1361,5 +1328,5 @@ resource "aws_appmesh_virtual_node" "test" { } } } -`, vnName) +`, vnName)) } From 1a02e79618c97f1e09eea8cad2f71f0a0b3ac3b7 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 24 Sep 2020 16:20:49 -0400 Subject: [PATCH 21/21] r/aws_acmpca_certificate_authority: Add 'testAccCheckAwsAcmpcaCertificateAuthorityDisableCA'. --- ...esource_aws_acmpca_certificate_authority_test.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/aws/resource_aws_acmpca_certificate_authority_test.go b/aws/resource_aws_acmpca_certificate_authority_test.go index 6a25806c812..9002ca59657 100644 --- a/aws/resource_aws_acmpca_certificate_authority_test.go +++ b/aws/resource_aws_acmpca_certificate_authority_test.go @@ -577,6 +577,19 @@ func testAccCheckAwsAcmpcaCertificateAuthorityActivateCA(certificateAuthority *a } } +func testAccCheckAwsAcmpcaCertificateAuthorityDisableCA(certificateAuthority *acmpca.CertificateAuthority) resource.TestCheckFunc { + return func(s *terraform.State) error { + conn := testAccProvider.Meta().(*AWSClient).acmpcaconn + + _, err := conn.UpdateCertificateAuthority(&acmpca.UpdateCertificateAuthorityInput{ + CertificateAuthorityArn: certificateAuthority.Arn, + Status: aws.String(acmpca.CertificateAuthorityStatusDisabled), + }) + + return err + } +} + func listAcmpcaCertificateAuthorities(conn *acmpca.ACMPCA) ([]*acmpca.CertificateAuthority, error) { certificateAuthorities := []*acmpca.CertificateAuthority{} input := &acmpca.ListCertificateAuthoritiesInput{}