Skip to content

Commit

Permalink
provider/aws: Support refresh of EC2 instance user_data.
Browse files Browse the repository at this point in the history
Make sure to hash base64 decoded value since user_data might be given
either raw bytes or base64 value.

This helps #1887 somewhat
as now you can:

1) Update user_data in AWS console.
2) Respectively update user_data in terraform code.
3) Just refresh terraform state and it should not report any changes.
  • Loading branch information
modax authored and catsby committed Oct 12, 2016
1 parent 961c8f9 commit 7385fa9
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 6 deletions.
28 changes: 26 additions & 2 deletions builtin/providers/aws/resource_aws_instance.go
Expand Up @@ -98,8 +98,7 @@ func resourceAwsInstance() *schema.Resource {
StateFunc: func(v interface{}) string {
switch v.(type) {
case string:
hash := sha1.Sum([]byte(v.(string)))
return hex.EncodeToString(hash[:])
return userDataHashSum(v.(string))
default:
return ""
}
Expand Down Expand Up @@ -583,6 +582,18 @@ func resourceAwsInstanceRead(d *schema.ResourceData, meta interface{}) error {
}
d.Set("disable_api_termination", attr.DisableApiTermination.Value)
}
{
attr, err := conn.DescribeInstanceAttribute(&ec2.DescribeInstanceAttributeInput{
Attribute: aws.String(ec2.InstanceAttributeNameUserData),
InstanceId: aws.String(d.Id()),
})
if err != nil {
return err
}
if attr.UserData.Value != nil {
d.Set("user_data", userDataHashSum(*attr.UserData.Value))
}
}

return nil
}
Expand Down Expand Up @@ -1166,3 +1177,16 @@ func iamInstanceProfileArnToName(ip *ec2.IamInstanceProfile) string {
parts := strings.Split(*ip.Arn, "/")
return parts[len(parts)-1]
}

func userDataHashSum(user_data string) string {
// Check whether the user_data is not Base64 encoded.
// Always calculate hash of base64 decoded value since we
// check against double-encoding when setting it
v, base64DecodeError := base64.StdEncoding.DecodeString(user_data)
if base64DecodeError != nil {
v = []byte(user_data)
}

hash := sha1.Sum(v)
return hex.EncodeToString(hash[:])
}
8 changes: 4 additions & 4 deletions builtin/providers/aws/resource_aws_instance_test.go
Expand Up @@ -39,7 +39,7 @@ func TestAccAWSInstance_basic(t *testing.T) {
// we'll import as VPC security groups, which is fine. We verify
// VPC security group import in other tests
IDRefreshName: "aws_instance.foo",
IDRefreshIgnore: []string{"user_data", "security_groups", "vpc_security_group_ids"},
IDRefreshIgnore: []string{"security_groups", "vpc_security_group_ids"},

Providers: testAccProviders,
CheckDestroy: testAccCheckInstanceDestroy,
Expand Down Expand Up @@ -195,7 +195,7 @@ func TestAccAWSInstance_blockDevices(t *testing.T) {
PreCheck: func() { testAccPreCheck(t) },
IDRefreshName: "aws_instance.foo",
IDRefreshIgnore: []string{
"ephemeral_block_device", "user_data", "security_groups", "vpc_security_groups"},
"ephemeral_block_device", "security_groups", "vpc_security_groups"},
Providers: testAccProviders,
CheckDestroy: testAccCheckInstanceDestroy,
Steps: []resource.TestStep{
Expand Down Expand Up @@ -346,7 +346,7 @@ func TestAccAWSInstance_vpc(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
IDRefreshName: "aws_instance.foo",
IDRefreshIgnore: []string{"associate_public_ip_address", "user_data"},
IDRefreshIgnore: []string{"associate_public_ip_address"},
Providers: testAccProviders,
CheckDestroy: testAccCheckInstanceDestroy,
Steps: []resource.TestStep{
Expand All @@ -358,7 +358,7 @@ func TestAccAWSInstance_vpc(t *testing.T) {
resource.TestCheckResourceAttr(
"aws_instance.foo",
"user_data",
"2fad308761514d9d73c3c7fdc877607e06cf950d"),
"562a3e32810edf6ff09994f050f12e799452379d"),
),
},
},
Expand Down

0 comments on commit 7385fa9

Please sign in to comment.