github.com/recobe182/terraform@v0.8.5-0.20170117231232-49ab22a935b7/builtin/providers/aws/resource_aws_ecs_task_definition.go (about) 1 package aws 2 3 import ( 4 "bytes" 5 "crypto/sha1" 6 "encoding/hex" 7 "fmt" 8 "log" 9 "strings" 10 11 "github.com/aws/aws-sdk-go/aws" 12 "github.com/aws/aws-sdk-go/service/ecs" 13 "github.com/hashicorp/terraform/helper/hashcode" 14 "github.com/hashicorp/terraform/helper/schema" 15 ) 16 17 func resourceAwsEcsTaskDefinition() *schema.Resource { 18 return &schema.Resource{ 19 Create: resourceAwsEcsTaskDefinitionCreate, 20 Read: resourceAwsEcsTaskDefinitionRead, 21 Delete: resourceAwsEcsTaskDefinitionDelete, 22 23 Schema: map[string]*schema.Schema{ 24 "arn": { 25 Type: schema.TypeString, 26 Computed: true, 27 }, 28 29 "family": { 30 Type: schema.TypeString, 31 Required: true, 32 ForceNew: true, 33 }, 34 35 "revision": { 36 Type: schema.TypeInt, 37 Computed: true, 38 }, 39 40 "container_definitions": { 41 Type: schema.TypeString, 42 Required: true, 43 ForceNew: true, 44 StateFunc: func(v interface{}) string { 45 hash := sha1.Sum([]byte(v.(string))) 46 return hex.EncodeToString(hash[:]) 47 }, 48 }, 49 50 "task_role_arn": { 51 Type: schema.TypeString, 52 Optional: true, 53 ForceNew: true, 54 }, 55 56 "network_mode": { 57 Type: schema.TypeString, 58 Optional: true, 59 Computed: true, 60 ForceNew: true, 61 ValidateFunc: validateAwsEcsTaskDefinitionNetworkMode, 62 }, 63 64 "volume": { 65 Type: schema.TypeSet, 66 Optional: true, 67 ForceNew: true, 68 Elem: &schema.Resource{ 69 Schema: map[string]*schema.Schema{ 70 "name": { 71 Type: schema.TypeString, 72 Required: true, 73 }, 74 75 "host_path": { 76 Type: schema.TypeString, 77 Optional: true, 78 }, 79 }, 80 }, 81 Set: resourceAwsEcsTaskDefinitionVolumeHash, 82 }, 83 84 "placement_constraints": { 85 Type: schema.TypeSet, 86 Optional: true, 87 ForceNew: true, 88 MaxItems: 10, 89 Elem: &schema.Resource{ 90 Schema: map[string]*schema.Schema{ 91 "type": { 92 Type: schema.TypeString, 93 ForceNew: true, 94 Required: true, 95 }, 96 "expression": { 97 Type: schema.TypeString, 98 ForceNew: true, 99 Required: true, 100 }, 101 }, 102 }, 103 }, 104 }, 105 } 106 } 107 108 func validateAwsEcsTaskDefinitionNetworkMode(v interface{}, k string) (ws []string, errors []error) { 109 value := strings.ToLower(v.(string)) 110 validTypes := map[string]struct{}{ 111 "bridge": {}, 112 "host": {}, 113 "none": {}, 114 } 115 116 if _, ok := validTypes[value]; !ok { 117 errors = append(errors, fmt.Errorf("ECS Task Definition network_mode %q is invalid, must be `bridge`, `host` or `none`", value)) 118 } 119 return 120 } 121 122 func resourceAwsEcsTaskDefinitionCreate(d *schema.ResourceData, meta interface{}) error { 123 conn := meta.(*AWSClient).ecsconn 124 125 rawDefinitions := d.Get("container_definitions").(string) 126 definitions, err := expandEcsContainerDefinitions(rawDefinitions) 127 if err != nil { 128 return err 129 } 130 131 input := ecs.RegisterTaskDefinitionInput{ 132 ContainerDefinitions: definitions, 133 Family: aws.String(d.Get("family").(string)), 134 } 135 136 if v, ok := d.GetOk("task_role_arn"); ok { 137 input.TaskRoleArn = aws.String(v.(string)) 138 } 139 140 if v, ok := d.GetOk("network_mode"); ok { 141 input.NetworkMode = aws.String(v.(string)) 142 } 143 144 if v, ok := d.GetOk("volume"); ok { 145 volumes, err := expandEcsVolumes(v.(*schema.Set).List()) 146 if err != nil { 147 return err 148 } 149 input.Volumes = volumes 150 } 151 152 constraints := d.Get("placement_constraints").(*schema.Set).List() 153 if len(constraints) > 0 { 154 var pc []*ecs.TaskDefinitionPlacementConstraint 155 for _, raw := range constraints { 156 p := raw.(map[string]interface{}) 157 pc = append(pc, &ecs.TaskDefinitionPlacementConstraint{ 158 Type: aws.String(p["type"].(string)), 159 Expression: aws.String(p["expression"].(string)), 160 }) 161 } 162 input.PlacementConstraints = pc 163 } 164 165 log.Printf("[DEBUG] Registering ECS task definition: %s", input) 166 out, err := conn.RegisterTaskDefinition(&input) 167 if err != nil { 168 return err 169 } 170 171 taskDefinition := *out.TaskDefinition 172 173 log.Printf("[DEBUG] ECS task definition registered: %q (rev. %d)", 174 *taskDefinition.TaskDefinitionArn, *taskDefinition.Revision) 175 176 d.SetId(*taskDefinition.Family) 177 d.Set("arn", taskDefinition.TaskDefinitionArn) 178 179 return resourceAwsEcsTaskDefinitionRead(d, meta) 180 } 181 182 func resourceAwsEcsTaskDefinitionRead(d *schema.ResourceData, meta interface{}) error { 183 conn := meta.(*AWSClient).ecsconn 184 185 log.Printf("[DEBUG] Reading task definition %s", d.Id()) 186 out, err := conn.DescribeTaskDefinition(&ecs.DescribeTaskDefinitionInput{ 187 TaskDefinition: aws.String(d.Get("arn").(string)), 188 }) 189 if err != nil { 190 return err 191 } 192 log.Printf("[DEBUG] Received task definition %s", out) 193 194 taskDefinition := out.TaskDefinition 195 196 d.SetId(*taskDefinition.Family) 197 d.Set("arn", taskDefinition.TaskDefinitionArn) 198 d.Set("family", taskDefinition.Family) 199 d.Set("revision", taskDefinition.Revision) 200 d.Set("container_definitions", taskDefinition.ContainerDefinitions) 201 d.Set("task_role_arn", taskDefinition.TaskRoleArn) 202 d.Set("network_mode", taskDefinition.NetworkMode) 203 d.Set("volumes", flattenEcsVolumes(taskDefinition.Volumes)) 204 if err := d.Set("placement_constraints", flattenPlacementConstraints(taskDefinition.PlacementConstraints)); err != nil { 205 log.Printf("[ERR] Error setting placement_constraints for (%s): %s", d.Id(), err) 206 } 207 208 return nil 209 } 210 211 func flattenPlacementConstraints(pcs []*ecs.TaskDefinitionPlacementConstraint) []map[string]interface{} { 212 if len(pcs) == 0 { 213 return nil 214 } 215 results := make([]map[string]interface{}, 0) 216 for _, pc := range pcs { 217 c := make(map[string]interface{}) 218 c["type"] = *pc.Type 219 c["expression"] = *pc.Expression 220 results = append(results, c) 221 } 222 return results 223 } 224 225 func resourceAwsEcsTaskDefinitionDelete(d *schema.ResourceData, meta interface{}) error { 226 conn := meta.(*AWSClient).ecsconn 227 228 _, err := conn.DeregisterTaskDefinition(&ecs.DeregisterTaskDefinitionInput{ 229 TaskDefinition: aws.String(d.Get("arn").(string)), 230 }) 231 if err != nil { 232 return err 233 } 234 235 log.Printf("[DEBUG] Task definition %q deregistered.", d.Get("arn").(string)) 236 237 return nil 238 } 239 240 func resourceAwsEcsTaskDefinitionVolumeHash(v interface{}) int { 241 var buf bytes.Buffer 242 m := v.(map[string]interface{}) 243 buf.WriteString(fmt.Sprintf("%s-", m["name"].(string))) 244 buf.WriteString(fmt.Sprintf("%s-", m["host_path"].(string))) 245 246 return hashcode.String(buf.String()) 247 }