diff --git a/.changelog/39427.txt b/.changelog/39427.txt new file mode 100644 index 000000000000..ec52e1ab1110 --- /dev/null +++ b/.changelog/39427.txt @@ -0,0 +1,3 @@ +```release-note:bug +resource/aws_vpc_dhcp_options: Fix a bug causing a panic crash when an option is absent +``` \ No newline at end of file diff --git a/internal/service/ec2/vpc_dhcp_options.go b/internal/service/ec2/vpc_dhcp_options.go index 3fb2d9c96846..3e6e16fa02b7 100644 --- a/internal/service/ec2/vpc_dhcp_options.go +++ b/internal/service/ec2/vpc_dhcp_options.go @@ -255,27 +255,33 @@ func newDHCPOptionsMap(tfToApi map[string]string) *dhcpOptionsMap { // dhcpConfigurationsToResourceData sets Terraform ResourceData from a list of AWS API DHCP configurations. func (m *dhcpOptionsMap) dhcpConfigurationsToResourceData(dhcpConfigurations []awstypes.DhcpConfiguration, d *schema.ResourceData) error { - for v := range m.tfToApi { - d.Set(v, nil) + // Clear existing values + for tfName := range m.tfToApi { + d.Set(tfName, nil) } for _, dhcpConfiguration := range dhcpConfigurations { apiName := aws.ToString(dhcpConfiguration.Key) - if tfName, ok := m.apiToTf[apiName]; ok { - switch v := d.Get(tfName).(type) { - case string: - d.Set(tfName, dhcpConfiguration.Values[0].Value) - case []interface{}: - var values []*string - for _, v := range dhcpConfiguration.Values { - values = append(values, v.Value) + tfName, ok := m.apiToTf[apiName] + if !ok { + return fmt.Errorf("unsupported DHCP option: %s", apiName) + } + + currentValue := d.Get(tfName) + + switch currentValue.(type) { + case string: + d.Set(tfName, dhcpConfiguration.Values[0].Value) + case []interface{}: + var values []string + for _, v := range dhcpConfiguration.Values { + if v.Value != nil { + values = append(values, aws.ToString(v.Value)) } - d.Set(tfName, values) - default: - return fmt.Errorf("Attribute (%s) is of unsupported type: %T", tfName, v) } - } else { - return fmt.Errorf("Unsupported DHCP option: %s", apiName) + d.Set(tfName, values) + default: + return fmt.Errorf("attribute (%s) is of unsupported type: %T", tfName, currentValue) } } @@ -287,7 +293,8 @@ func (m *dhcpOptionsMap) resourceDataToDHCPConfigurations(d *schema.ResourceData var output []awstypes.NewDhcpConfiguration for tfName, apiName := range m.tfToApi { - switch v := d.Get(tfName).(type) { + value := d.Get(tfName) + switch v := value.(type) { case string: if v != "" { output = append(output, awstypes.NewDhcpConfiguration{ @@ -297,10 +304,9 @@ func (m *dhcpOptionsMap) resourceDataToDHCPConfigurations(d *schema.ResourceData } case []interface{}: var values []string - for _, v := range v { - v := v.(string) - if v != "" { - values = append(values, v) + for _, item := range v { + if str, ok := item.(string); ok && str != "" { + values = append(values, str) } } if len(values) > 0 { @@ -310,7 +316,7 @@ func (m *dhcpOptionsMap) resourceDataToDHCPConfigurations(d *schema.ResourceData }) } default: - return nil, fmt.Errorf("Attribute (%s) is of unsupported type: %T", tfName, v) + return nil, fmt.Errorf("attribute (%s) is of unsupported type: %T", tfName, value) } }