Skip to content

Commit

Permalink
Merge pull request #36309 from dgr237/main
Browse files Browse the repository at this point in the history
b-aws_ecs-fix-service-connect-bug-when-empty-block-supplied
  • Loading branch information
ewbankkit authored Mar 12, 2024
2 parents 4c41c4e + 33289f5 commit d8d4dd5
Show file tree
Hide file tree
Showing 3 changed files with 222 additions and 4 deletions.
7 changes: 7 additions & 0 deletions .changelog/36309.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
```release-note:bug
resource/aws_ecs_service: Fix `panic: interface conversion: interface {} is nil, not map[string]interface {}` when `service_connect_configuration.service.timeout` is empty
```

```release-note:bug
resource/aws_ecs_service: `service_connect_configuration.service.tls.issuer_cert_authority.aws_pca_authority_arn` is Required
```
18 changes: 14 additions & 4 deletions internal/service/ecs/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ func ResourceService() *schema.Resource {
Schema: map[string]*schema.Schema{
"aws_pca_authority_arn": {
Type: schema.TypeString,
Optional: true,
Required: true,
ValidateFunc: verify.ValidARN,
},
},
Expand Down Expand Up @@ -1510,7 +1510,11 @@ func expandTimeout(timeout []interface{}) *ecs.TimeoutConfiguration {
if len(timeout) == 0 {
return nil
}
raw := timeout[0].(map[string]interface{})

raw, ok := timeout[0].(map[string]interface{})
if !ok {
return nil
}
timeoutConfig := &ecs.TimeoutConfiguration{}
if v, ok := raw["idle_timeout_seconds"].(int); ok {
timeoutConfig.IdleTimeoutSeconds = aws.Int64(int64(v))
Expand All @@ -1526,7 +1530,10 @@ func expandTLS(tls []interface{}) *ecs.ServiceConnectTlsConfiguration {
return nil
}

raw := tls[0].(map[string]interface{})
raw, ok := tls[0].(map[string]interface{})
if !ok {
return nil
}
tlsConfig := &ecs.ServiceConnectTlsConfiguration{}
if v, ok := raw["issuer_cert_authority"].([]interface{}); ok && len(v) > 0 {
tlsConfig.IssuerCertificateAuthority = expandIssuerCertAuthority(v)
Expand All @@ -1545,7 +1552,10 @@ func expandIssuerCertAuthority(pca []interface{}) *ecs.ServiceConnectTlsCertific
return nil
}

raw := pca[0].(map[string]interface{})
raw, ok := pca[0].(map[string]interface{})
if !ok {
return nil
}
config := &ecs.ServiceConnectTlsCertificateAuthority{}

if v, ok := raw["aws_pca_authority_arn"].(string); ok && v != "" {
Expand Down
201 changes: 201 additions & 0 deletions internal/service/ecs/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1370,6 +1370,29 @@ func TestAccECSService_ServiceConnect_full(t *testing.T) {
})
}

func TestAccECSService_ServiceConnect_tls_with_empty_timeout(t *testing.T) {
ctx := acctest.Context(t)
var service ecs.Service
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resourceName := "aws_ecs_service.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(ctx, t) },
ErrorCheck: acctest.ErrorCheck(t, names.ECSServiceID),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckServiceDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccServiceConfig_serviceConnect_tls_with_empty_timeout_block(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckServiceExists(ctx, resourceName, &service),
resource.TestCheckResourceAttr(resourceName, "service_connect_configuration.#", "1"),
),
},
},
})
}

func TestAccECSService_ServiceConnect_ingressPortOverride(t *testing.T) {
ctx := acctest.Context(t)
var service ecs.Service
Expand Down Expand Up @@ -4416,6 +4439,184 @@ data "aws_caller_identity" "current" {}
`, rName)
}

func testAccServiceConfig_serviceConnect_tls_with_empty_timeout_block(rName string) string {
return fmt.Sprintf(`
resource "aws_kms_key" "test" {
description = %[1]q
deletion_window_in_days = 7
policy = data.aws_iam_policy_document.test.json
}
data "aws_iam_policy_document" "test" {
policy_id = "KMSPolicy"
statement {
sid = "Root User Permissions"
effect = "Allow"
principals {
type = "AWS"
identifiers = [
"arn:${data.aws_partition.current.partition}:iam::${data.aws_caller_identity.current.account_id}:root"]
}
actions = [
"kms:*"]
resources = ["*"]
}
statement {
sid = "EC2 kms permissions"
effect = "Allow"
principals {
type = "AWS"
identifiers = [aws_iam_role.test.arn]
}
actions = [
"kms:Encrypt",
"kms:Decrypt",
"kms:GenerateDataKey",
"kms:GenerateDataKeyPair"]
resources = ["*"]
}
}
resource "aws_iam_role" "test" {
name = %[1]q
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "ecs.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
managed_policy_arns = ["arn:${data.aws_partition.current.partition}:iam::aws:policy/service-role/AmazonECSInfrastructureRolePolicyForServiceConnectTransportLayerSecurity"]
}
resource "aws_service_discovery_http_namespace" "test" {
name = %[1]q
}
resource "aws_ecs_cluster" "test" {
name = %[1]q
}
resource "aws_ecs_task_definition" "test" {
family = %[1]q
network_mode = "bridge"
container_definitions = <<DEFINITION
[
{
"cpu": 128,
"essential": true,
"image": "mongo:latest",
"memory": 128,
"name": "mongodb",
"portMappings": [
{
"hostPort": 0,
"appProtocol": "http",
"containerPort": 27017,
"name": "tf-test",
"protocol": "tcp"
}
]
}
]
DEFINITION
}
resource "aws_ecs_service" "test" {
name = %[1]q
cluster = aws_ecs_cluster.test.id
task_definition = aws_ecs_task_definition.test.arn
desired_count = 1
service_connect_configuration {
enabled = true
namespace = aws_service_discovery_http_namespace.test.arn
log_configuration {
log_driver = "json-file"
options = {
key = "value"
}
}
service {
client_alias {
dns_name = "example.com"
port = 8080
}
discovery_name = "test"
ingress_port_override = 8443
port_name = "tf-test"
tls {
issuer_cert_authority {
aws_pca_authority_arn = aws_acmpca_certificate_authority.test.arn
}
kms_key = aws_kms_key.test.arn
role_arn = aws_iam_role.test.arn
}
timeout {
}
}
}
}
resource "aws_acmpca_certificate_authority_certificate" "test" {
certificate_authority_arn = aws_acmpca_certificate_authority.test.arn
certificate = aws_acmpca_certificate.test.certificate
certificate_chain = aws_acmpca_certificate.test.certificate_chain
}
resource "aws_acmpca_certificate" "test" {
certificate_authority_arn = aws_acmpca_certificate_authority.test.arn
certificate_signing_request = aws_acmpca_certificate_authority.test.certificate_signing_request
signing_algorithm = "SHA512WITHRSA"
template_arn = "arn:${data.aws_partition.current.partition}:acm-pca:::template/RootCACertificate/V1"
validity {
type = "YEARS"
value = 1
}
}
resource "aws_acmpca_certificate_authority" "test" {
permanent_deletion_time_in_days = 7
type = "ROOT"
usage_mode = "SHORT_LIVED_CERTIFICATE"
certificate_authority_configuration {
key_algorithm = "RSA_4096"
signing_algorithm = "SHA512WITHRSA"
subject {
common_name = %[1]q
}
}
tags = {
AmazonECSManaged = "true"
}
}
data "aws_partition" "current" {}
data "aws_caller_identity" "current" {}
`, rName)
}

func testAccServiceConfig_serviceConnectIngressPortOverride(rName string) string {
return acctest.ConfigCompose(acctest.ConfigVPCWithSubnets(rName, 2), fmt.Sprintf(`
resource "aws_security_group" "test" {
Expand Down

0 comments on commit d8d4dd5

Please sign in to comment.