Add aws_ecs_container_definition data source
this datasource allows terraform to work with externally modified state, e.g. when you're using an ECS service which is continously updated by your CI via the AWS CLI. right now you'd have to wrap terraform into a shell script which looks up the current image digest, so running terraform won't change the updated service. using the aws_ecs_container_definition data source you can now leverage terraform, removing the wrapper entirely.
This commit is contained in:
parent
fe540b408f
commit
90889632e0
|
@ -0,0 +1,98 @@
|
||||||
|
package aws
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
"github.com/aws/aws-sdk-go/service/ecs"
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
func dataSourceAwsEcsContainerDefinition() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Read: dataSourceAwsEcsContainerDefinitionRead,
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"task_definition": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
"container_name": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Required: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
// Computed values.
|
||||||
|
"image": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"image_digest": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"cpu": &schema.Schema{
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"memory": &schema.Schema{
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"disable_networking": &schema.Schema{
|
||||||
|
Type: schema.TypeBool,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"docker_labels": &schema.Schema{
|
||||||
|
Type: schema.TypeMap,
|
||||||
|
Computed: true,
|
||||||
|
Elem: schema.TypeString,
|
||||||
|
},
|
||||||
|
"environment": &schema.Schema{
|
||||||
|
Type: schema.TypeMap,
|
||||||
|
Computed: true,
|
||||||
|
Elem: schema.TypeString,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func dataSourceAwsEcsContainerDefinitionRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
conn := meta.(*AWSClient).ecsconn
|
||||||
|
|
||||||
|
desc, err := conn.DescribeTaskDefinition(&ecs.DescribeTaskDefinitionInput{
|
||||||
|
TaskDefinition: aws.String(d.Get("task_definition").(string)),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
taskDefinition := *desc.TaskDefinition
|
||||||
|
for _, def := range taskDefinition.ContainerDefinitions {
|
||||||
|
if aws.StringValue(def.Name) != d.Get("container_name").(string) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetId(fmt.Sprintf("%s/%s", aws.StringValue(taskDefinition.TaskDefinitionArn), d.Get("container_name").(string)))
|
||||||
|
d.Set("image", aws.StringValue(def.Image))
|
||||||
|
d.Set("image_digest", strings.Split(aws.StringValue(def.Image), ":")[1])
|
||||||
|
d.Set("cpu", aws.Int64Value(def.Cpu))
|
||||||
|
d.Set("memory", aws.Int64Value(def.Memory))
|
||||||
|
d.Set("disable_networking", aws.BoolValue(def.DisableNetworking))
|
||||||
|
d.Set("docker_labels", aws.StringValueMap(def.DockerLabels))
|
||||||
|
|
||||||
|
var environment = map[string]string{}
|
||||||
|
for _, keyValuePair := range def.Environment {
|
||||||
|
environment[aws.StringValue(keyValuePair.Name)] = aws.StringValue(keyValuePair.Value)
|
||||||
|
}
|
||||||
|
d.Set("environment", environment)
|
||||||
|
}
|
||||||
|
|
||||||
|
if d.Id() == "" {
|
||||||
|
return fmt.Errorf("container with name %q not found in task definition %q", d.Get("container_name").(string), d.Get("task_definition").(string))
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
package aws
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccAWSAmiDataSource_ecsContainerDefinition(t *testing.T) {
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccCheckAwsEcsContainerDefinitionDataSourceConfig,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
resource.TestCheckResourceAttr("data.aws_ecs_container_definition.mongo", "image", "mongo:latest"),
|
||||||
|
resource.TestCheckResourceAttr("data.aws_ecs_container_definition.mongo", "memory", "128"),
|
||||||
|
resource.TestCheckResourceAttr("data.aws_ecs_container_definition.mongo", "cpu", "128"),
|
||||||
|
resource.TestCheckResourceAttr("data.aws_ecs_container_definition.mongo", "environment.SECRET", "KEY"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const testAccCheckAwsEcsContainerDefinitionDataSourceConfig = `
|
||||||
|
resource "aws_ecs_cluster" "default" {
|
||||||
|
name = "terraformecstest1"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_ecs_task_definition" "mongo" {
|
||||||
|
family = "mongodb"
|
||||||
|
container_definitions = <<DEFINITION
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"cpu": 128,
|
||||||
|
"environment": [{
|
||||||
|
"name": "SECRET",
|
||||||
|
"value": "KEY"
|
||||||
|
}],
|
||||||
|
"essential": true,
|
||||||
|
"image": "mongo:latest",
|
||||||
|
"memory": 128,
|
||||||
|
"name": "mongodb"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
DEFINITION
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_ecs_service" "mongo" {
|
||||||
|
name = "mongodb"
|
||||||
|
cluster = "${aws_ecs_cluster.default.id}"
|
||||||
|
task_definition = "${aws_ecs_task_definition.mongo.arn}"
|
||||||
|
desired_count = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
data "aws_ecs_container_definition" "mongo" {
|
||||||
|
task_definition = "${aws_ecs_task_definition.mongo.id}"
|
||||||
|
container_name = "mongodb"
|
||||||
|
}
|
||||||
|
`
|
|
@ -111,10 +111,11 @@ func Provider() terraform.ResourceProvider {
|
||||||
},
|
},
|
||||||
|
|
||||||
DataSourcesMap: map[string]*schema.Resource{
|
DataSourcesMap: map[string]*schema.Resource{
|
||||||
"aws_ami": dataSourceAwsAmi(),
|
"aws_ami": dataSourceAwsAmi(),
|
||||||
"aws_availability_zones": dataSourceAwsAvailabilityZones(),
|
"aws_availability_zones": dataSourceAwsAvailabilityZones(),
|
||||||
"aws_iam_policy_document": dataSourceAwsIamPolicyDocument(),
|
"aws_iam_policy_document": dataSourceAwsIamPolicyDocument(),
|
||||||
"aws_s3_bucket_object": dataSourceAwsS3BucketObject(),
|
"aws_s3_bucket_object": dataSourceAwsS3BucketObject(),
|
||||||
|
"aws_ecs_container_definition": dataSourceAwsEcsContainerDefinition(),
|
||||||
},
|
},
|
||||||
|
|
||||||
ResourcesMap: map[string]*schema.Resource{
|
ResourcesMap: map[string]*schema.Resource{
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
---
|
||||||
|
layout: "aws"
|
||||||
|
page_title: "AWS: aws_ecs_container_definition"
|
||||||
|
sidebar_current: "docs-aws-datasource-ecs-container-definition"
|
||||||
|
description: |-
|
||||||
|
Provides details about a single container within an ecs task definition
|
||||||
|
---
|
||||||
|
|
||||||
|
# aws\_ecs\_container\_definition
|
||||||
|
|
||||||
|
The Availability Zones data source allows access to the list of AWS
|
||||||
|
Availability Zones which can be accessed by an AWS account within the region
|
||||||
|
configured in the provider.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
data "aws_ecs_container_definition" "ecs-mongo" {
|
||||||
|
task_definition = "${aws_ecs_task_definition.mongo.id}"
|
||||||
|
container_name = "mongodb"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
The following arguments are supported:
|
||||||
|
|
||||||
|
* `task_definition` - (Required) The ARN of the task definition which contains the container
|
||||||
|
* `container_name` - (Required) The name of the container definition
|
||||||
|
|
||||||
|
## Attributes Reference
|
||||||
|
|
||||||
|
The following attributes are exported:
|
||||||
|
|
||||||
|
* `image` - The docker image in use, including the digest
|
||||||
|
* `image_digest` - The digest of the docker image in use
|
||||||
|
* `cpu` - The CPU limit for this container definition
|
||||||
|
* `memory` - The memory limit for this container definition
|
||||||
|
* `environment` - The environment in use
|
||||||
|
* `disable_networking` - Indicator if networking is disabled
|
||||||
|
* `docker_labels` - Set docker labels
|
|
@ -16,6 +16,9 @@
|
||||||
<li<%= sidebar_current("docs-aws-datasource-ami") %>>
|
<li<%= sidebar_current("docs-aws-datasource-ami") %>>
|
||||||
<a href="/docs/providers/aws/d/ami.html">aws_ami</a>
|
<a href="/docs/providers/aws/d/ami.html">aws_ami</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li<%= sidebar_current("docs-aws-datasource-ecs-container-definition") %>>
|
||||||
|
<a href="/docs/providers/aws/d/ecs_container_definition.html">aws_ecs_container_definition</a>
|
||||||
|
</li>
|
||||||
<li<%= sidebar_current("docs-aws-datasource-availability-zones") %>>
|
<li<%= sidebar_current("docs-aws-datasource-availability-zones") %>>
|
||||||
<a href="/docs/providers/aws/d/availability_zones.html">aws_availability_zones</a>
|
<a href="/docs/providers/aws/d/availability_zones.html">aws_availability_zones</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
Loading…
Reference in New Issue