provider/aws: Support refresh of EC2 instance user_data.
Make sure to hash base64 decoded value since user_data might be given either raw bytes or base64 value. This helps https://github.com/hashicorp/terraform/issues/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.
This commit is contained in:
parent
961c8f9d97
commit
7385fa9eac
|
@ -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 ""
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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[:])
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
@ -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{
|
||||
|
@ -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{
|
||||
|
@ -358,7 +358,7 @@ func TestAccAWSInstance_vpc(t *testing.T) {
|
|||
resource.TestCheckResourceAttr(
|
||||
"aws_instance.foo",
|
||||
"user_data",
|
||||
"2fad308761514d9d73c3c7fdc877607e06cf950d"),
|
||||
"562a3e32810edf6ff09994f050f12e799452379d"),
|
||||
),
|
||||
},
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue