mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-10 23:55:34 -06:00
Previously in Update we would only set req.CustomJson if a non-empty value was provided in the config. It seems that the Opsworks API considers a null CustomJson to mean "do not change" rather than "set to empty", so we need to explicitly set the empty string in the request body in order to successfully remove an already-configured custom JSON.
643 lines
18 KiB
Go
643 lines
18 KiB
Go
package aws
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"strconv"
|
|
|
|
"github.com/hashicorp/terraform/helper/hashcode"
|
|
"github.com/hashicorp/terraform/helper/schema"
|
|
|
|
"github.com/aws/aws-sdk-go/aws"
|
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
"github.com/aws/aws-sdk-go/service/opsworks"
|
|
)
|
|
|
|
// OpsWorks has a single concept of "layer" which represents several different
|
|
// layer types. The differences between these are in some extra properties that
|
|
// get packed into an "Attributes" map, but in the OpsWorks UI these are presented
|
|
// as first-class options, and so Terraform prefers to expose them this way and
|
|
// hide the implementation detail that they are all packed into a single type
|
|
// in the underlying API.
|
|
//
|
|
// This file contains utilities that are shared between all of the concrete
|
|
// layer resource types, which have names matching aws_opsworks_*_layer .
|
|
|
|
type opsworksLayerTypeAttribute struct {
|
|
AttrName string
|
|
Type schema.ValueType
|
|
Default interface{}
|
|
Required bool
|
|
WriteOnly bool
|
|
}
|
|
|
|
type opsworksLayerType struct {
|
|
TypeName string
|
|
DefaultLayerName string
|
|
Attributes map[string]*opsworksLayerTypeAttribute
|
|
CustomShortName bool
|
|
}
|
|
|
|
var (
|
|
opsworksTrueString = "1"
|
|
opsworksFalseString = "0"
|
|
)
|
|
|
|
func (lt *opsworksLayerType) SchemaResource() *schema.Resource {
|
|
resourceSchema := map[string]*schema.Schema{
|
|
"id": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Computed: true,
|
|
},
|
|
|
|
"auto_assign_elastic_ips": &schema.Schema{
|
|
Type: schema.TypeBool,
|
|
Optional: true,
|
|
Default: false,
|
|
},
|
|
|
|
"auto_assign_public_ips": &schema.Schema{
|
|
Type: schema.TypeBool,
|
|
Optional: true,
|
|
Default: false,
|
|
},
|
|
|
|
"custom_instance_profile_arn": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Optional: true,
|
|
},
|
|
|
|
"elastic_load_balancer": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Optional: true,
|
|
},
|
|
|
|
"custom_setup_recipes": &schema.Schema{
|
|
Type: schema.TypeList,
|
|
Optional: true,
|
|
Elem: &schema.Schema{Type: schema.TypeString},
|
|
},
|
|
|
|
"custom_configure_recipes": &schema.Schema{
|
|
Type: schema.TypeList,
|
|
Optional: true,
|
|
Elem: &schema.Schema{Type: schema.TypeString},
|
|
},
|
|
|
|
"custom_deploy_recipes": &schema.Schema{
|
|
Type: schema.TypeList,
|
|
Optional: true,
|
|
Elem: &schema.Schema{Type: schema.TypeString},
|
|
},
|
|
|
|
"custom_undeploy_recipes": &schema.Schema{
|
|
Type: schema.TypeList,
|
|
Optional: true,
|
|
Elem: &schema.Schema{Type: schema.TypeString},
|
|
},
|
|
|
|
"custom_shutdown_recipes": &schema.Schema{
|
|
Type: schema.TypeList,
|
|
Optional: true,
|
|
Elem: &schema.Schema{Type: schema.TypeString},
|
|
},
|
|
|
|
"custom_security_group_ids": &schema.Schema{
|
|
Type: schema.TypeSet,
|
|
Optional: true,
|
|
Elem: &schema.Schema{Type: schema.TypeString},
|
|
Set: schema.HashString,
|
|
},
|
|
|
|
"custom_json": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
StateFunc: normalizeJson,
|
|
Optional: true,
|
|
},
|
|
|
|
"auto_healing": &schema.Schema{
|
|
Type: schema.TypeBool,
|
|
Optional: true,
|
|
Default: true,
|
|
},
|
|
|
|
"install_updates_on_boot": &schema.Schema{
|
|
Type: schema.TypeBool,
|
|
Optional: true,
|
|
Default: true,
|
|
},
|
|
|
|
"instance_shutdown_timeout": &schema.Schema{
|
|
Type: schema.TypeInt,
|
|
Optional: true,
|
|
Default: 120,
|
|
},
|
|
|
|
"drain_elb_on_shutdown": &schema.Schema{
|
|
Type: schema.TypeBool,
|
|
Optional: true,
|
|
Default: true,
|
|
},
|
|
|
|
"system_packages": &schema.Schema{
|
|
Type: schema.TypeSet,
|
|
Optional: true,
|
|
Elem: &schema.Schema{Type: schema.TypeString},
|
|
Set: schema.HashString,
|
|
},
|
|
|
|
"stack_id": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
ForceNew: true,
|
|
Required: true,
|
|
},
|
|
|
|
"use_ebs_optimized_instances": &schema.Schema{
|
|
Type: schema.TypeBool,
|
|
Optional: true,
|
|
Default: false,
|
|
},
|
|
|
|
"ebs_volume": &schema.Schema{
|
|
Type: schema.TypeSet,
|
|
Optional: true,
|
|
Elem: &schema.Resource{
|
|
Schema: map[string]*schema.Schema{
|
|
|
|
"iops": &schema.Schema{
|
|
Type: schema.TypeInt,
|
|
Optional: true,
|
|
Default: 0,
|
|
},
|
|
|
|
"mount_point": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Required: true,
|
|
},
|
|
|
|
"number_of_disks": &schema.Schema{
|
|
Type: schema.TypeInt,
|
|
Required: true,
|
|
},
|
|
|
|
"raid_level": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Optional: true,
|
|
Default: "",
|
|
},
|
|
|
|
"size": &schema.Schema{
|
|
Type: schema.TypeInt,
|
|
Required: true,
|
|
},
|
|
|
|
"type": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Optional: true,
|
|
Default: "standard",
|
|
},
|
|
},
|
|
},
|
|
Set: func(v interface{}) int {
|
|
m := v.(map[string]interface{})
|
|
return hashcode.String(m["mount_point"].(string))
|
|
},
|
|
},
|
|
}
|
|
|
|
if lt.CustomShortName {
|
|
resourceSchema["short_name"] = &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Required: true,
|
|
}
|
|
}
|
|
|
|
if lt.DefaultLayerName != "" {
|
|
resourceSchema["name"] = &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Optional: true,
|
|
Default: lt.DefaultLayerName,
|
|
}
|
|
} else {
|
|
resourceSchema["name"] = &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Required: true,
|
|
}
|
|
}
|
|
|
|
for key, def := range lt.Attributes {
|
|
resourceSchema[key] = &schema.Schema{
|
|
Type: def.Type,
|
|
Default: def.Default,
|
|
Required: def.Required,
|
|
Optional: !def.Required,
|
|
}
|
|
}
|
|
|
|
return &schema.Resource{
|
|
Read: func(d *schema.ResourceData, meta interface{}) error {
|
|
client := meta.(*AWSClient).opsworksconn
|
|
return lt.Read(d, client)
|
|
},
|
|
Create: func(d *schema.ResourceData, meta interface{}) error {
|
|
client := meta.(*AWSClient).opsworksconn
|
|
return lt.Create(d, client)
|
|
},
|
|
Update: func(d *schema.ResourceData, meta interface{}) error {
|
|
client := meta.(*AWSClient).opsworksconn
|
|
return lt.Update(d, client)
|
|
},
|
|
Delete: func(d *schema.ResourceData, meta interface{}) error {
|
|
client := meta.(*AWSClient).opsworksconn
|
|
return lt.Delete(d, client)
|
|
},
|
|
|
|
Schema: resourceSchema,
|
|
}
|
|
}
|
|
|
|
func (lt *opsworksLayerType) Read(d *schema.ResourceData, client *opsworks.OpsWorks) error {
|
|
|
|
req := &opsworks.DescribeLayersInput{
|
|
LayerIds: []*string{
|
|
aws.String(d.Id()),
|
|
},
|
|
}
|
|
|
|
log.Printf("[DEBUG] Reading OpsWorks layer: %s", d.Id())
|
|
|
|
resp, err := client.DescribeLayers(req)
|
|
if err != nil {
|
|
if awserr, ok := err.(awserr.Error); ok {
|
|
if awserr.Code() == "ResourceNotFoundException" {
|
|
d.SetId("")
|
|
return nil
|
|
}
|
|
}
|
|
return err
|
|
}
|
|
|
|
layer := resp.Layers[0]
|
|
d.Set("id", layer.LayerId)
|
|
d.Set("auto_assign_elastic_ips", layer.AutoAssignElasticIps)
|
|
d.Set("auto_assign_public_ips", layer.AutoAssignPublicIps)
|
|
d.Set("custom_instance_profile_arn", layer.CustomInstanceProfileArn)
|
|
d.Set("custom_security_group_ids", flattenStringList(layer.CustomSecurityGroupIds))
|
|
d.Set("auto_healing", layer.EnableAutoHealing)
|
|
d.Set("install_updates_on_boot", layer.InstallUpdatesOnBoot)
|
|
d.Set("name", layer.Name)
|
|
d.Set("system_packages", flattenStringList(layer.Packages))
|
|
d.Set("stack_id", layer.StackId)
|
|
d.Set("use_ebs_optimized_instances", layer.UseEbsOptimizedInstances)
|
|
|
|
if lt.CustomShortName {
|
|
d.Set("short_name", layer.Shortname)
|
|
}
|
|
|
|
if v := layer.CustomJson; v == nil {
|
|
if err := d.Set("custom_json", ""); err != nil {
|
|
return err
|
|
}
|
|
} else if err := d.Set("custom_json", normalizeJson(*v)); err != nil {
|
|
return err
|
|
}
|
|
|
|
lt.SetAttributeMap(d, layer.Attributes)
|
|
lt.SetLifecycleEventConfiguration(d, layer.LifecycleEventConfiguration)
|
|
lt.SetCustomRecipes(d, layer.CustomRecipes)
|
|
lt.SetVolumeConfigurations(d, layer.VolumeConfigurations)
|
|
|
|
/* get ELB */
|
|
ebsRequest := &opsworks.DescribeElasticLoadBalancersInput{
|
|
LayerIds: []*string{
|
|
aws.String(d.Id()),
|
|
},
|
|
}
|
|
loadBalancers, err := client.DescribeElasticLoadBalancers(ebsRequest)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if loadBalancers.ElasticLoadBalancers == nil || len(loadBalancers.ElasticLoadBalancers) == 0 {
|
|
d.Set("elastic_load_balancer", "")
|
|
} else {
|
|
loadBalancer := loadBalancers.ElasticLoadBalancers[0]
|
|
if loadBalancer != nil {
|
|
d.Set("elastic_load_balancer", loadBalancer.ElasticLoadBalancerName)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (lt *opsworksLayerType) Create(d *schema.ResourceData, client *opsworks.OpsWorks) error {
|
|
|
|
req := &opsworks.CreateLayerInput{
|
|
AutoAssignElasticIps: aws.Bool(d.Get("auto_assign_elastic_ips").(bool)),
|
|
AutoAssignPublicIps: aws.Bool(d.Get("auto_assign_public_ips").(bool)),
|
|
CustomInstanceProfileArn: aws.String(d.Get("custom_instance_profile_arn").(string)),
|
|
CustomRecipes: lt.CustomRecipes(d),
|
|
CustomSecurityGroupIds: expandStringSet(d.Get("custom_security_group_ids").(*schema.Set)),
|
|
EnableAutoHealing: aws.Bool(d.Get("auto_healing").(bool)),
|
|
InstallUpdatesOnBoot: aws.Bool(d.Get("install_updates_on_boot").(bool)),
|
|
LifecycleEventConfiguration: lt.LifecycleEventConfiguration(d),
|
|
Name: aws.String(d.Get("name").(string)),
|
|
Packages: expandStringSet(d.Get("system_packages").(*schema.Set)),
|
|
Type: aws.String(lt.TypeName),
|
|
StackId: aws.String(d.Get("stack_id").(string)),
|
|
UseEbsOptimizedInstances: aws.Bool(d.Get("use_ebs_optimized_instances").(bool)),
|
|
Attributes: lt.AttributeMap(d),
|
|
VolumeConfigurations: lt.VolumeConfigurations(d),
|
|
}
|
|
|
|
if lt.CustomShortName {
|
|
req.Shortname = aws.String(d.Get("short_name").(string))
|
|
} else {
|
|
req.Shortname = aws.String(lt.TypeName)
|
|
}
|
|
|
|
req.CustomJson = aws.String(d.Get("custom_json").(string))
|
|
|
|
log.Printf("[DEBUG] Creating OpsWorks layer: %s", d.Id())
|
|
|
|
resp, err := client.CreateLayer(req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
layerId := *resp.LayerId
|
|
d.SetId(layerId)
|
|
d.Set("id", layerId)
|
|
|
|
loadBalancer := aws.String(d.Get("elastic_load_balancer").(string))
|
|
if loadBalancer != nil && *loadBalancer != "" {
|
|
log.Printf("[DEBUG] Attaching load balancer: %s", *loadBalancer)
|
|
_, err := client.AttachElasticLoadBalancer(&opsworks.AttachElasticLoadBalancerInput{
|
|
ElasticLoadBalancerName: loadBalancer,
|
|
LayerId: &layerId,
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return lt.Read(d, client)
|
|
}
|
|
|
|
func (lt *opsworksLayerType) Update(d *schema.ResourceData, client *opsworks.OpsWorks) error {
|
|
|
|
req := &opsworks.UpdateLayerInput{
|
|
LayerId: aws.String(d.Id()),
|
|
AutoAssignElasticIps: aws.Bool(d.Get("auto_assign_elastic_ips").(bool)),
|
|
AutoAssignPublicIps: aws.Bool(d.Get("auto_assign_public_ips").(bool)),
|
|
CustomInstanceProfileArn: aws.String(d.Get("custom_instance_profile_arn").(string)),
|
|
CustomRecipes: lt.CustomRecipes(d),
|
|
CustomSecurityGroupIds: expandStringSet(d.Get("custom_security_group_ids").(*schema.Set)),
|
|
EnableAutoHealing: aws.Bool(d.Get("auto_healing").(bool)),
|
|
InstallUpdatesOnBoot: aws.Bool(d.Get("install_updates_on_boot").(bool)),
|
|
LifecycleEventConfiguration: lt.LifecycleEventConfiguration(d),
|
|
Name: aws.String(d.Get("name").(string)),
|
|
Packages: expandStringSet(d.Get("system_packages").(*schema.Set)),
|
|
UseEbsOptimizedInstances: aws.Bool(d.Get("use_ebs_optimized_instances").(bool)),
|
|
Attributes: lt.AttributeMap(d),
|
|
VolumeConfigurations: lt.VolumeConfigurations(d),
|
|
}
|
|
|
|
if lt.CustomShortName {
|
|
req.Shortname = aws.String(d.Get("short_name").(string))
|
|
} else {
|
|
req.Shortname = aws.String(lt.TypeName)
|
|
}
|
|
|
|
req.CustomJson = aws.String(d.Get("custom_json").(string))
|
|
|
|
log.Printf("[DEBUG] Updating OpsWorks layer: %s", d.Id())
|
|
|
|
if d.HasChange("elastic_load_balancer") {
|
|
lbo, lbn := d.GetChange("elastic_load_balancer")
|
|
|
|
loadBalancerOld := aws.String(lbo.(string))
|
|
loadBalancerNew := aws.String(lbn.(string))
|
|
|
|
if loadBalancerOld != nil && *loadBalancerOld != "" {
|
|
log.Printf("[DEBUG] Dettaching load balancer: %s", *loadBalancerOld)
|
|
_, err := client.DetachElasticLoadBalancer(&opsworks.DetachElasticLoadBalancerInput{
|
|
ElasticLoadBalancerName: loadBalancerOld,
|
|
LayerId: aws.String(d.Id()),
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
if loadBalancerNew != nil && *loadBalancerNew != "" {
|
|
log.Printf("[DEBUG] Attaching load balancer: %s", *loadBalancerNew)
|
|
_, err := client.AttachElasticLoadBalancer(&opsworks.AttachElasticLoadBalancerInput{
|
|
ElasticLoadBalancerName: loadBalancerNew,
|
|
LayerId: aws.String(d.Id()),
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
|
|
_, err := client.UpdateLayer(req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return lt.Read(d, client)
|
|
}
|
|
|
|
func (lt *opsworksLayerType) Delete(d *schema.ResourceData, client *opsworks.OpsWorks) error {
|
|
req := &opsworks.DeleteLayerInput{
|
|
LayerId: aws.String(d.Id()),
|
|
}
|
|
|
|
log.Printf("[DEBUG] Deleting OpsWorks layer: %s", d.Id())
|
|
|
|
_, err := client.DeleteLayer(req)
|
|
return err
|
|
}
|
|
|
|
func (lt *opsworksLayerType) AttributeMap(d *schema.ResourceData) map[string]*string {
|
|
attrs := map[string]*string{}
|
|
|
|
for key, def := range lt.Attributes {
|
|
value := d.Get(key)
|
|
switch def.Type {
|
|
case schema.TypeString:
|
|
strValue := value.(string)
|
|
attrs[def.AttrName] = &strValue
|
|
case schema.TypeInt:
|
|
intValue := value.(int)
|
|
strValue := strconv.Itoa(intValue)
|
|
attrs[def.AttrName] = &strValue
|
|
case schema.TypeBool:
|
|
boolValue := value.(bool)
|
|
if boolValue {
|
|
attrs[def.AttrName] = &opsworksTrueString
|
|
} else {
|
|
attrs[def.AttrName] = &opsworksFalseString
|
|
}
|
|
default:
|
|
// should never happen
|
|
panic(fmt.Errorf("Unsupported OpsWorks layer attribute type"))
|
|
}
|
|
}
|
|
|
|
return attrs
|
|
}
|
|
|
|
func (lt *opsworksLayerType) SetAttributeMap(d *schema.ResourceData, attrs map[string]*string) {
|
|
for key, def := range lt.Attributes {
|
|
// Ignore write-only attributes; we'll just keep what we already have stored.
|
|
// (The AWS API returns garbage placeholder values for these.)
|
|
if def.WriteOnly {
|
|
continue
|
|
}
|
|
|
|
if strPtr, ok := attrs[def.AttrName]; ok && strPtr != nil {
|
|
strValue := *strPtr
|
|
|
|
switch def.Type {
|
|
case schema.TypeString:
|
|
d.Set(key, strValue)
|
|
case schema.TypeInt:
|
|
intValue, err := strconv.Atoi(strValue)
|
|
if err == nil {
|
|
d.Set(key, intValue)
|
|
} else {
|
|
// Got garbage from the AWS API
|
|
d.Set(key, nil)
|
|
}
|
|
case schema.TypeBool:
|
|
boolValue := true
|
|
if strValue == opsworksFalseString {
|
|
boolValue = false
|
|
}
|
|
d.Set(key, boolValue)
|
|
default:
|
|
// should never happen
|
|
panic(fmt.Errorf("Unsupported OpsWorks layer attribute type"))
|
|
}
|
|
return
|
|
|
|
} else {
|
|
d.Set(key, nil)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (lt *opsworksLayerType) LifecycleEventConfiguration(d *schema.ResourceData) *opsworks.LifecycleEventConfiguration {
|
|
return &opsworks.LifecycleEventConfiguration{
|
|
Shutdown: &opsworks.ShutdownEventConfiguration{
|
|
DelayUntilElbConnectionsDrained: aws.Bool(d.Get("drain_elb_on_shutdown").(bool)),
|
|
ExecutionTimeout: aws.Int64(int64(d.Get("instance_shutdown_timeout").(int))),
|
|
},
|
|
}
|
|
}
|
|
|
|
func (lt *opsworksLayerType) SetLifecycleEventConfiguration(d *schema.ResourceData, v *opsworks.LifecycleEventConfiguration) {
|
|
if v == nil || v.Shutdown == nil {
|
|
d.Set("drain_elb_on_shutdown", nil)
|
|
d.Set("instance_shutdown_timeout", nil)
|
|
} else {
|
|
d.Set("drain_elb_on_shutdown", v.Shutdown.DelayUntilElbConnectionsDrained)
|
|
d.Set("instance_shutdown_timeout", v.Shutdown.ExecutionTimeout)
|
|
}
|
|
}
|
|
|
|
func (lt *opsworksLayerType) CustomRecipes(d *schema.ResourceData) *opsworks.Recipes {
|
|
return &opsworks.Recipes{
|
|
Configure: expandStringList(d.Get("custom_configure_recipes").([]interface{})),
|
|
Deploy: expandStringList(d.Get("custom_deploy_recipes").([]interface{})),
|
|
Setup: expandStringList(d.Get("custom_setup_recipes").([]interface{})),
|
|
Shutdown: expandStringList(d.Get("custom_shutdown_recipes").([]interface{})),
|
|
Undeploy: expandStringList(d.Get("custom_undeploy_recipes").([]interface{})),
|
|
}
|
|
}
|
|
|
|
func (lt *opsworksLayerType) SetCustomRecipes(d *schema.ResourceData, v *opsworks.Recipes) {
|
|
// Null out everything first, and then we'll consider what to put back.
|
|
d.Set("custom_configure_recipes", nil)
|
|
d.Set("custom_deploy_recipes", nil)
|
|
d.Set("custom_setup_recipes", nil)
|
|
d.Set("custom_shutdown_recipes", nil)
|
|
d.Set("custom_undeploy_recipes", nil)
|
|
|
|
if v == nil {
|
|
return
|
|
}
|
|
|
|
d.Set("custom_configure_recipes", flattenStringList(v.Configure))
|
|
d.Set("custom_deploy_recipes", flattenStringList(v.Deploy))
|
|
d.Set("custom_setup_recipes", flattenStringList(v.Setup))
|
|
d.Set("custom_shutdown_recipes", flattenStringList(v.Shutdown))
|
|
d.Set("custom_undeploy_recipes", flattenStringList(v.Undeploy))
|
|
}
|
|
|
|
func (lt *opsworksLayerType) VolumeConfigurations(d *schema.ResourceData) []*opsworks.VolumeConfiguration {
|
|
configuredVolumes := d.Get("ebs_volume").(*schema.Set).List()
|
|
result := make([]*opsworks.VolumeConfiguration, len(configuredVolumes))
|
|
|
|
for i := 0; i < len(configuredVolumes); i++ {
|
|
volumeData := configuredVolumes[i].(map[string]interface{})
|
|
|
|
result[i] = &opsworks.VolumeConfiguration{
|
|
MountPoint: aws.String(volumeData["mount_point"].(string)),
|
|
NumberOfDisks: aws.Int64(int64(volumeData["number_of_disks"].(int))),
|
|
Size: aws.Int64(int64(volumeData["size"].(int))),
|
|
VolumeType: aws.String(volumeData["type"].(string)),
|
|
}
|
|
iops := int64(volumeData["iops"].(int))
|
|
if iops != 0 {
|
|
result[i].Iops = aws.Int64(iops)
|
|
}
|
|
|
|
raidLevelStr := volumeData["raid_level"].(string)
|
|
if raidLevelStr != "" {
|
|
raidLevel, err := strconv.Atoi(raidLevelStr)
|
|
if err == nil {
|
|
result[i].RaidLevel = aws.Int64(int64(raidLevel))
|
|
}
|
|
}
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
func (lt *opsworksLayerType) SetVolumeConfigurations(d *schema.ResourceData, v []*opsworks.VolumeConfiguration) {
|
|
newValue := make([]*map[string]interface{}, len(v))
|
|
|
|
for i := 0; i < len(v); i++ {
|
|
config := v[i]
|
|
data := make(map[string]interface{})
|
|
newValue[i] = &data
|
|
|
|
if config.Iops != nil {
|
|
data["iops"] = int(*config.Iops)
|
|
} else {
|
|
data["iops"] = 0
|
|
}
|
|
if config.MountPoint != nil {
|
|
data["mount_point"] = *config.MountPoint
|
|
}
|
|
if config.NumberOfDisks != nil {
|
|
data["number_of_disks"] = int(*config.NumberOfDisks)
|
|
}
|
|
if config.RaidLevel != nil {
|
|
data["raid_level"] = strconv.Itoa(int(*config.RaidLevel))
|
|
}
|
|
if config.Size != nil {
|
|
data["size"] = int(*config.Size)
|
|
}
|
|
if config.VolumeType != nil {
|
|
data["type"] = *config.VolumeType
|
|
}
|
|
}
|
|
|
|
d.Set("ebs_volume", newValue)
|
|
}
|