Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add aws_ecs_task_definition.proxy_configuration #8780

Merged
merged 7 commits into from
Jun 20, 2019
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions aws/resource_aws_ecs_task_definition.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,37 @@ func resourceAwsEcsTaskDefinition() *schema.Resource {
}, false),
},

"proxy_configuration": {
bflad marked this conversation as resolved.
Show resolved Hide resolved
Type: schema.TypeList,
MaxItems: 1,
Optional: true,
ForceNew: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"container_name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"properties": {
Type: schema.TypeMap,
Elem: &schema.Schema{Type: schema.TypeString},
Optional: true,
ForceNew: true,
},
"type": {
bflad marked this conversation as resolved.
Show resolved Hide resolved
Type: schema.TypeString,
Default: ecs.ProxyConfigurationTypeAppmesh,
Optional: true,
ForceNew: true,
ValidateFunc: validation.StringInSlice([]string{
ecs.ProxyConfigurationTypeAppmesh,
}, false),
},
},
},
},

"tags": tagsSchema(),
},
}
Expand Down Expand Up @@ -321,6 +352,34 @@ func resourceAwsEcsTaskDefinitionCreate(d *schema.ResourceData, meta interface{}
input.RequiresCompatibilities = expandStringList(v.(*schema.Set).List())
}

proxyConfigs := d.Get("proxy_configuration").([]interface{})
if len(proxyConfigs) > 0 {
proxyConfig := proxyConfigs[0]
configMap := proxyConfig.(map[string]interface{})

containerName := configMap["container_name"].(string)
proxyType := configMap["type"].(string)

rawProperties := configMap["properties"].(map[string]interface{})

properties := make([]*ecs.KeyValuePair, len(rawProperties))
i := 0
for name, value := range rawProperties {
properties[i] = &ecs.KeyValuePair{
Name: aws.String(name),
Value: aws.String(value.(string)),
}
i++
}

var ecsProxyConfig ecs.ProxyConfiguration
ecsProxyConfig.ContainerName = aws.String(containerName)
ecsProxyConfig.Type = aws.String(proxyType)
ecsProxyConfig.Properties = properties

input.ProxyConfiguration = &ecsProxyConfig
}

log.Printf("[DEBUG] Registering ECS task definition: %s", input)
out, err := conn.RegisterTaskDefinition(&input)
if err != nil {
Expand Down Expand Up @@ -396,6 +455,10 @@ func resourceAwsEcsTaskDefinitionRead(d *schema.ResourceData, meta interface{})
return err
}

if err := d.Set("proxy_configuration", flattenProxyConfiguration(taskDefinition.ProxyConfiguration)); err != nil {
return err
SebastianC marked this conversation as resolved.
Show resolved Hide resolved
}

return nil
}

Expand All @@ -413,6 +476,28 @@ func flattenPlacementConstraints(pcs []*ecs.TaskDefinitionPlacementConstraint) [
return results
}

func flattenProxyConfiguration(pc *ecs.ProxyConfiguration) []map[string]interface{} {
if pc == nil {
return nil
}

meshProperties := make(map[string]string)
if pc.Properties != nil {
for _, prop := range pc.Properties {
meshProperties[*prop.Name] = *prop.Value
SebastianC marked this conversation as resolved.
Show resolved Hide resolved
}
}

config := make(map[string]interface{})
config["container_name"] = *pc.ContainerName
SebastianC marked this conversation as resolved.
Show resolved Hide resolved
config["type"] = *pc.Type
SebastianC marked this conversation as resolved.
Show resolved Hide resolved
config["properties"] = meshProperties

return []map[string]interface{}{
config,
}
}

func resourceAwsEcsTaskDefinitionUpdate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).ecsconn

Expand Down
130 changes: 129 additions & 1 deletion aws/resource_aws_ecs_task_definition_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,135 @@ func TestAccAWSEcsTaskDefinition_Tags(t *testing.T) {
})
}

func TestAccAWSEcsTaskDefinition_ProxyConfiguration(t *testing.T) {
var taskDefinition ecs.TaskDefinition
rName := acctest.RandomWithPrefix("tf-acc-test")
resourceName := "aws_ecs_task_definition.test"

containerName := "web"
proxyType := "APPMESH"
ignoredUid := "1337"
ignoredGid := "999"
appPorts := "80"
proxyIngressPort := "15000"
proxyEgressPort := "15001"
egressIgnoredPorts := "5500"
egressIgnoredIPs := "169.254.170.2,169.254.169.254"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSEcsTaskDefinitionDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSEcsTaskDefinitionConfigProxyConfiguration(rName, containerName, proxyType, ignoredUid, ignoredGid, appPorts, proxyIngressPort, proxyEgressPort, egressIgnoredPorts, egressIgnoredIPs),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSEcsTaskDefinitionExists(resourceName, &taskDefinition),
testAccCheckAWSEcsTaskDefinitionProxyConfiguration(&taskDefinition, containerName, proxyType, ignoredUid, ignoredGid, appPorts, proxyIngressPort, proxyEgressPort, egressIgnoredPorts, egressIgnoredIPs),
),
},
SebastianC marked this conversation as resolved.
Show resolved Hide resolved
},
})
}

func testAccAWSEcsTaskDefinitionConfigProxyConfiguration(rName string, containerName string, proxyType string,
ignoredUid string, ignoredGid string, appPorts string, proxyIngressPort string, proxyEgressPort string,
egressIgnoredPorts string, egressIgnoredIPs string) string {

return fmt.Sprintf(`
resource "aws_ecs_cluster" "test" {
name = %q
}

resource "aws_ecs_task_definition" "test" {
family = %q
network_mode = "awsvpc"

proxy_configuration {
type = %q
container_name = %q
properties = {
IgnoredUID = %q
IgnoredGID = %q
AppPorts = %q
ProxyIngressPort = %q
ProxyEgressPort = %q
EgressIgnoredPorts = %q
EgressIgnoredIPs = %q
}
}

container_definitions = <<DEFINITION
[
{
"cpu": 128,
"essential": true,
"image": "nginx:latest",
"memory": 128,
"name": %q
}
]
DEFINITION

}
`, rName, rName, proxyType, containerName, ignoredUid, ignoredGid, appPorts, proxyIngressPort, proxyEgressPort, egressIgnoredPorts, egressIgnoredIPs, containerName)
}

func testAccCheckAWSEcsTaskDefinitionProxyConfiguration(after *ecs.TaskDefinition, containerName string, proxyType string,
ignoredUid string, ignoredGid string, appPorts string, proxyIngressPort string, proxyEgressPort string,
egressIgnoredPorts string, egressIgnoredIPs string) resource.TestCheckFunc {
return func(s *terraform.State) error {
if *after.ProxyConfiguration.Type != proxyType {
return fmt.Errorf("Expected (%s) ProxyConfiguration.Type, got (%s)", proxyType, *after.ProxyConfiguration.Type)
}

if *after.ProxyConfiguration.ContainerName != containerName {
return fmt.Errorf("Expected (%s) ProxyConfiguration.ContainerName, got (%s)", containerName, *after.ProxyConfiguration.ContainerName)
}

properties := after.ProxyConfiguration.Properties
expectedProperties := []string{"IgnoredUID", "IgnoredGID", "AppPorts", "ProxyIngressPort", "ProxyEgressPort", "EgressIgnoredPorts", "EgressIgnoredIPs"}
if len(properties) != len(expectedProperties) {
return fmt.Errorf("Expected (%d) ProxyConfiguration.Property count, got (%d)", len(expectedProperties), len(properties))
}

propertyLookups := make(map[string]string)
for _, property := range properties {
propertyLookups[*property.Name] = *property.Value
}

if propertyLookups["IgnoredUID"] != ignoredUid {
return fmt.Errorf("Expected (%s) ProxyConfiguration.Properties.IgnoredUID, got (%s)", ignoredUid, propertyLookups["IgnoredUID"])
}

if propertyLookups["IgnoredGID"] != ignoredGid {
return fmt.Errorf("Expected (%s) ProxyConfiguration.Properties.IgnoredGID, got (%s)", ignoredGid, propertyLookups["IgnoredGID"])
}

if propertyLookups["AppPorts"] != appPorts {
return fmt.Errorf("Expected (%s) ProxyConfiguration.Properties.AppPorts, got (%s)", appPorts, propertyLookups["AppPorts"])
}

if propertyLookups["ProxyIngressPort"] != proxyIngressPort {
return fmt.Errorf("Expected (%s) ProxyConfiguration.Properties.ProxyIngressPort, got (%s)", proxyIngressPort, propertyLookups["ProxyIngressPort"])
}

if propertyLookups["ProxyEgressPort"] != proxyEgressPort {
return fmt.Errorf("Expected (%s) ProxyConfiguration.Properties.ProxyEgressPort, got (%s)", proxyEgressPort, propertyLookups["ProxyEgressPort"])
}

if propertyLookups["EgressIgnoredPorts"] != egressIgnoredPorts {
return fmt.Errorf("Expected (%s) ProxyConfiguration.Properties.EgressIgnoredPorts, got (%s)", egressIgnoredPorts, propertyLookups["EgressIgnoredPorts"])
}

if propertyLookups["EgressIgnoredIPs"] != egressIgnoredIPs {
return fmt.Errorf("Expected (%s) ProxyConfiguration.Properties.EgressIgnoredIPs, got (%s)", egressIgnoredIPs, propertyLookups["EgressIgnoredIPs"])
}

return nil
}
}

func testAccCheckEcsTaskDefinitionRecreated(t *testing.T,
before, after *ecs.TaskDefinition) resource.TestCheckFunc {
return func(s *terraform.State) error {
Expand Down Expand Up @@ -585,7 +714,6 @@ func testAccCheckAWSEcsTaskDefinitionExists(name string, def *ecs.TaskDefinition
if err != nil {
return err
}

*def = *out.TaskDefinition

return nil
Expand Down
27 changes: 27 additions & 0 deletions website/docs/r/ecs_task_definition.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,27 @@ contains only a small subset of the available parameters.
]
```

### With AppMesh Proxy

```hcl
resource "aws_ecs_task_definition" "service" {
family = "service"
container_definitions = "${file("task-definitions/service.json")}"

proxy_configuration {
type = "APPMESH"
container_name = "applicationContainerName"
properties = {
IgnoredUID = "1337"
SebastianC marked this conversation as resolved.
Show resolved Hide resolved
AppPorts = "8080"
ProxyIngressPort = 15000
ProxyEgressPort = 15001
EgressIgnoredIPs = "169.254.170.2,169.254.169.254"
}
}
}
```

## Argument Reference

### Top-Level Arguments
Expand All @@ -89,6 +110,7 @@ official [Developer Guide](https://docs.aws.amazon.com/AmazonECS/latest/develope
* `cpu` - (Optional) The number of cpu units used by the task. If the `requires_compatibilities` is `FARGATE` this field is required.
* `memory` - (Optional) The amount (in MiB) of memory used by the task. If the `requires_compatibilities` is `FARGATE` this field is required.
* `requires_compatibilities` - (Optional) A set of launch types required by the task. The valid values are `EC2` and `FARGATE`.
* `proxy_configuration` - (Optional) The [proxy configuration](#proxy-configuration-arguments) details for the App Mesh proxy.
* `tags` - (Optional) Key-value mapping of resource tags

#### Volume Block Arguments
Expand Down Expand Up @@ -134,6 +156,11 @@ For more information, see [Cluster Query Language in the Amazon EC2 Container
Service Developer
Guide](http://docs.aws.amazon.com/AmazonECS/latest/developerguide/cluster-query-language.html).

#### Proxy Configuration Arguments

* `type` - (Optional) The proxy type. The only supported value is `APPMESH`.
SebastianC marked this conversation as resolved.
Show resolved Hide resolved
* `container_name` - (Required) The name of the container that will serve as the App Mesh proxy.
* `properties` - (Required) The set of network configuration parameters to provide the Container Network Interface (CNI) plugin, specified a key-value mapping.

## Attributes Reference

Expand Down