Skip to content

Commit

Permalink
resource/aws_ecs_task_definition: Prevent API ordering differences in…
Browse files Browse the repository at this point in the history
… `container_definitions` environment variables during updates (#11463)

Output from acceptance testing:

```
--- PASS: TestAccAWSEcsTaskDefinition_arrays (18.99s)
--- PASS: TestAccAWSEcsTaskDefinition_basic (31.95s)
--- PASS: TestAccAWSEcsTaskDefinition_changeVolumesForcesNewResource (32.13s)
--- PASS: TestAccAWSEcsTaskDefinition_constraint (19.21s)
--- PASS: TestAccAWSEcsTaskDefinition_ExecutionRole (20.29s)
--- PASS: TestAccAWSEcsTaskDefinition_Fargate (25.76s)
--- PASS: TestAccAWSEcsTaskDefinition_Inactive (37.80s)
--- PASS: TestAccAWSEcsTaskDefinition_inferenceAccelerator (19.31s)
--- PASS: TestAccAWSEcsTaskDefinition_ProxyConfiguration (31.52s)
--- PASS: TestAccAWSEcsTaskDefinition_Tags (52.97s)
--- PASS: TestAccAWSEcsTaskDefinition_withDockerVolume (19.42s)
--- PASS: TestAccAWSEcsTaskDefinition_withDockerVolumeMinimalConfig (19.41s)
--- PASS: TestAccAWSEcsTaskDefinition_withEcsService (76.30s)
--- PASS: TestAccAWSEcsTaskDefinition_withEFSVolume (32.52s)
--- PASS: TestAccAWSEcsTaskDefinition_withEFSVolumeMinimal (32.26s)
--- PASS: TestAccAWSEcsTaskDefinition_withIPCMode (20.19s)
--- PASS: TestAccAWSEcsTaskDefinition_withNetworkMode (20.36s)
--- PASS: TestAccAWSEcsTaskDefinition_withPidMode (29.78s)
--- PASS: TestAccAWSEcsTaskDefinition_withScratchVolume (18.39s)
--- PASS: TestAccAWSEcsTaskDefinition_withTaskRoleArn (20.21s)
--- PASS: TestAccAWSEcsTaskDefinition_withTaskScopedDockerVolume (18.99s)
```
  • Loading branch information
jbergknoff-rival committed Jun 24, 2020
1 parent 08b415c commit 0be34d4
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 6 deletions.
16 changes: 11 additions & 5 deletions aws/ecs_task_definition_equivalency.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ func EcsContainerDefinitionsAreEquivalent(def1, def2 string, isAWSVPC bool) (boo
type containerDefinitions []*ecs.ContainerDefinition

func (cd containerDefinitions) Reduce(isAWSVPC bool) error {
// Deal with fields which may be re-ordered in the API
cd.OrderEnvironmentVariables()

for i, def := range cd {
// Deal with special fields which have defaults
if def.Cpu != nil && *def.Cpu == 0 {
Expand All @@ -76,11 +79,6 @@ func (cd containerDefinitions) Reduce(isAWSVPC bool) error {
}
}

// Deal with fields which may be re-ordered in the API
sort.Slice(def.Environment, func(i, j int) bool {
return aws.StringValue(def.Environment[i].Name) < aws.StringValue(def.Environment[j].Name)
})

// Create a mutable copy
defCopy, err := copystructure.Copy(def)
if err != nil {
Expand All @@ -103,3 +101,11 @@ func (cd containerDefinitions) Reduce(isAWSVPC bool) error {
}
return nil
}

func (cd containerDefinitions) OrderEnvironmentVariables() {
for _, def := range cd {
sort.Slice(def.Environment, func(i, j int) bool {
return aws.StringValue(def.Environment[i].Name) < aws.StringValue(def.Environment[j].Name)
})
}
}
13 changes: 12 additions & 1 deletion aws/resource_aws_ecs_task_definition.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,13 @@ func resourceAwsEcsTaskDefinition() *schema.Resource {
Required: true,
ForceNew: true,
StateFunc: func(v interface{}) string {
json, _ := structure.NormalizeJsonString(v)
// Sort the lists of environment variables as they are serialized to state, so we won't get
// spurious reorderings in plans (diff is suppressed if the environment variables haven't changed,
// but they still show in the plan if some other property changes).
orderedCDs, _ := expandEcsContainerDefinitions(v.(string))
containerDefinitions(orderedCDs).OrderEnvironmentVariables()
unnormalizedJson, _ := flattenEcsContainerDefinitions(orderedCDs)
json, _ := structure.NormalizeJsonString(unnormalizedJson)
return json
},
DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
Expand Down Expand Up @@ -512,6 +518,11 @@ func resourceAwsEcsTaskDefinitionRead(d *schema.ResourceData, meta interface{})
d.Set("family", taskDefinition.Family)
d.Set("revision", taskDefinition.Revision)

// Sort the lists of environment variables as they come in, so we won't get spurious reorderings in plans
// (diff is suppressed if the environment variables haven't changed, but they still show in the plan if
// some other property changes).
containerDefinitions(taskDefinition.ContainerDefinitions).OrderEnvironmentVariables()

defs, err := flattenEcsContainerDefinitions(taskDefinition.ContainerDefinitions)
if err != nil {
return err
Expand Down

0 comments on commit 0be34d4

Please sign in to comment.