provider/aws: Support import of aws_opsworks_instance (#11783)

Fixes: #11180

```
% make testacc TEST=./builtin/providers/aws TESTARGS='-run=TestAccAWSOpsworksInstance'
==> Checking that code complies with gofmt requirements...
go generate $(go list ./... | grep -v /terraform/vendor/)
2017/02/08 15:01:08 Generated command/internal_plugin_list.go
TF_ACC=1 go test ./builtin/providers/aws -v -run=TestAccAWSOpsworksInstance -timeout 120m
=== RUN   TestAccAWSOpsworksInstance_importBasic
--- PASS: TestAccAWSOpsworksInstance_importBasic (84.47s)
=== RUN   TestAccAWSOpsworksInstance
--- PASS: TestAccAWSOpsworksInstance (113.09s)
PASS
ok  	github.com/hashicorp/terraform/builtin/providers/aws	197.583s
```
This commit is contained in:
Paul Stack 2017-02-10 14:53:50 +00:00 committed by GitHub
parent 5a467edb0b
commit a306a6d780
3 changed files with 111 additions and 61 deletions

View File

@ -21,198 +21,201 @@ func resourceAwsOpsworksInstance() *schema.Resource {
Read: resourceAwsOpsworksInstanceRead, Read: resourceAwsOpsworksInstanceRead,
Update: resourceAwsOpsworksInstanceUpdate, Update: resourceAwsOpsworksInstanceUpdate,
Delete: resourceAwsOpsworksInstanceDelete, Delete: resourceAwsOpsworksInstanceDelete,
Importer: &schema.ResourceImporter{
State: resourceAwsOpsworksInstanceImport,
},
Schema: map[string]*schema.Schema{ Schema: map[string]*schema.Schema{
"id": &schema.Schema{ "id": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
}, },
"agent_version": &schema.Schema{ "agent_version": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Default: "INHERIT", Default: "INHERIT",
}, },
"ami_id": &schema.Schema{ "ami_id": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
ForceNew: true, ForceNew: true,
}, },
"architecture": &schema.Schema{ "architecture": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Default: "x86_64", Default: "x86_64",
ValidateFunc: validateArchitecture, ValidateFunc: validateArchitecture,
}, },
"auto_scaling_type": &schema.Schema{ "auto_scaling_type": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
ValidateFunc: validateAutoScalingType, ValidateFunc: validateAutoScalingType,
}, },
"availability_zone": &schema.Schema{ "availability_zone": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
ForceNew: true, ForceNew: true,
}, },
"created_at": &schema.Schema{ "created_at": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"delete_ebs": &schema.Schema{ "delete_ebs": {
Type: schema.TypeBool, Type: schema.TypeBool,
Optional: true, Optional: true,
Default: true, Default: true,
}, },
"delete_eip": &schema.Schema{ "delete_eip": {
Type: schema.TypeBool, Type: schema.TypeBool,
Optional: true, Optional: true,
Default: true, Default: true,
}, },
"ebs_optimized": &schema.Schema{ "ebs_optimized": {
Type: schema.TypeBool, Type: schema.TypeBool,
Optional: true, Optional: true,
Default: false, Default: false,
ForceNew: true, ForceNew: true,
}, },
"ec2_instance_id": &schema.Schema{ "ec2_instance_id": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"ecs_cluster_arn": &schema.Schema{ "ecs_cluster_arn": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"elastic_ip": &schema.Schema{ "elastic_ip": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"hostname": &schema.Schema{ "hostname": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"infrastructure_class": &schema.Schema{ "infrastructure_class": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"install_updates_on_boot": &schema.Schema{ "install_updates_on_boot": {
Type: schema.TypeBool, Type: schema.TypeBool,
Optional: true, Optional: true,
Default: true, Default: true,
}, },
"instance_profile_arn": &schema.Schema{ "instance_profile_arn": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"instance_type": &schema.Schema{ "instance_type": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
}, },
"last_service_error_id": &schema.Schema{ "last_service_error_id": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"layer_ids": &schema.Schema{ "layer_ids": {
Type: schema.TypeList, Type: schema.TypeList,
Required: true, Required: true,
Elem: &schema.Schema{Type: schema.TypeString}, Elem: &schema.Schema{Type: schema.TypeString},
}, },
"os": &schema.Schema{ "os": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
ForceNew: true, ForceNew: true,
}, },
"platform": &schema.Schema{ "platform": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"private_dns": &schema.Schema{ "private_dns": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"private_ip": &schema.Schema{ "private_ip": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"public_dns": &schema.Schema{ "public_dns": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"public_ip": &schema.Schema{ "public_ip": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"registered_by": &schema.Schema{ "registered_by": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"reported_agent_version": &schema.Schema{ "reported_agent_version": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"reported_os_family": &schema.Schema{ "reported_os_family": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"reported_os_name": &schema.Schema{ "reported_os_name": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"reported_os_version": &schema.Schema{ "reported_os_version": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"root_device_type": &schema.Schema{ "root_device_type": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
ForceNew: true, ForceNew: true,
@ -220,63 +223,63 @@ func resourceAwsOpsworksInstance() *schema.Resource {
ValidateFunc: validateRootDeviceType, ValidateFunc: validateRootDeviceType,
}, },
"root_device_volume_id": &schema.Schema{ "root_device_volume_id": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"security_group_ids": &schema.Schema{ "security_group_ids": {
Type: schema.TypeList, Type: schema.TypeList,
Optional: true, Optional: true,
Computed: true, Computed: true,
Elem: &schema.Schema{Type: schema.TypeString}, Elem: &schema.Schema{Type: schema.TypeString},
}, },
"ssh_host_dsa_key_fingerprint": &schema.Schema{ "ssh_host_dsa_key_fingerprint": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"ssh_host_rsa_key_fingerprint": &schema.Schema{ "ssh_host_rsa_key_fingerprint": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"ssh_key_name": &schema.Schema{ "ssh_key_name": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"stack_id": &schema.Schema{ "stack_id": {
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Required: true,
ForceNew: true, ForceNew: true,
}, },
"state": &schema.Schema{ "state": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
ValidateFunc: validateState, ValidateFunc: validateState,
}, },
"status": &schema.Schema{ "status": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
}, },
"subnet_id": &schema.Schema{ "subnet_id": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
ForceNew: true, ForceNew: true,
}, },
"tenancy": &schema.Schema{ "tenancy": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
@ -284,7 +287,7 @@ func resourceAwsOpsworksInstance() *schema.Resource {
ValidateFunc: validateTenancy, ValidateFunc: validateTenancy,
}, },
"virtualization_type": &schema.Schema{ "virtualization_type": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
@ -292,48 +295,48 @@ func resourceAwsOpsworksInstance() *schema.Resource {
ValidateFunc: validateVirtualizationType, ValidateFunc: validateVirtualizationType,
}, },
"ebs_block_device": &schema.Schema{ "ebs_block_device": {
Type: schema.TypeSet, Type: schema.TypeSet,
Optional: true, Optional: true,
Computed: true, Computed: true,
ForceNew: true, ForceNew: true,
Elem: &schema.Resource{ Elem: &schema.Resource{
Schema: map[string]*schema.Schema{ Schema: map[string]*schema.Schema{
"delete_on_termination": &schema.Schema{ "delete_on_termination": {
Type: schema.TypeBool, Type: schema.TypeBool,
Optional: true, Optional: true,
Default: true, Default: true,
ForceNew: true, ForceNew: true,
}, },
"device_name": &schema.Schema{ "device_name": {
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Required: true,
ForceNew: true, ForceNew: true,
}, },
"iops": &schema.Schema{ "iops": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Computed: true, Computed: true,
ForceNew: true, ForceNew: true,
}, },
"snapshot_id": &schema.Schema{ "snapshot_id": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
ForceNew: true, ForceNew: true,
}, },
"volume_size": &schema.Schema{ "volume_size": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Computed: true, Computed: true,
ForceNew: true, ForceNew: true,
}, },
"volume_type": &schema.Schema{ "volume_type": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
@ -349,19 +352,19 @@ func resourceAwsOpsworksInstance() *schema.Resource {
return hashcode.String(buf.String()) return hashcode.String(buf.String())
}, },
}, },
"ephemeral_block_device": &schema.Schema{ "ephemeral_block_device": {
Type: schema.TypeSet, Type: schema.TypeSet,
Optional: true, Optional: true,
Computed: true, Computed: true,
ForceNew: true, ForceNew: true,
Elem: &schema.Resource{ Elem: &schema.Resource{
Schema: map[string]*schema.Schema{ Schema: map[string]*schema.Schema{
"device_name": &schema.Schema{ "device_name": {
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Required: true,
}, },
"virtual_name": &schema.Schema{ "virtual_name": {
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Required: true,
}, },
@ -376,7 +379,7 @@ func resourceAwsOpsworksInstance() *schema.Resource {
}, },
}, },
"root_block_device": &schema.Schema{ "root_block_device": {
// TODO: This is a set because we don't support singleton // TODO: This is a set because we don't support singleton
// sub-resources today. We'll enforce that the set only ever has // sub-resources today. We'll enforce that the set only ever has
// length zero or one below. When TF gains support for // length zero or one below. When TF gains support for
@ -390,28 +393,28 @@ func resourceAwsOpsworksInstance() *schema.Resource {
// Termination flag on the block device mapping entry for the root // Termination flag on the block device mapping entry for the root
// device volume." - bit.ly/ec2bdmap // device volume." - bit.ly/ec2bdmap
Schema: map[string]*schema.Schema{ Schema: map[string]*schema.Schema{
"delete_on_termination": &schema.Schema{ "delete_on_termination": {
Type: schema.TypeBool, Type: schema.TypeBool,
Optional: true, Optional: true,
Default: true, Default: true,
ForceNew: true, ForceNew: true,
}, },
"iops": &schema.Schema{ "iops": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Computed: true, Computed: true,
ForceNew: true, ForceNew: true,
}, },
"volume_size": &schema.Schema{ "volume_size": {
Type: schema.TypeInt, Type: schema.TypeInt,
Optional: true, Optional: true,
Computed: true, Computed: true,
ForceNew: true, ForceNew: true,
}, },
"volume_type": &schema.Schema{ "volume_type": {
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true, Computed: true,
@ -558,7 +561,13 @@ func resourceAwsOpsworksInstanceRead(d *schema.ResourceData, meta interface{}) e
d.Set("instance_profile_arn", instance.InstanceProfileArn) d.Set("instance_profile_arn", instance.InstanceProfileArn)
d.Set("instance_type", instance.InstanceType) d.Set("instance_type", instance.InstanceType)
d.Set("last_service_error_id", instance.LastServiceErrorId) d.Set("last_service_error_id", instance.LastServiceErrorId)
d.Set("layer_ids", instance.LayerIds) var layerIds []string
for _, v := range instance.LayerIds {
layerIds = append(layerIds, *v)
}
if err := d.Set("layer_ids", layerIds); err != nil {
return fmt.Errorf("[DEBUG] Error setting layer_ids attribute: %#v, error: %#v", layerIds, err)
}
d.Set("os", instance.Os) d.Set("os", instance.Os)
d.Set("platform", instance.Platform) d.Set("platform", instance.Platform)
d.Set("private_dns", instance.PrivateDns) d.Set("private_dns", instance.PrivateDns)
@ -886,6 +895,16 @@ func resourceAwsOpsworksInstanceDelete(d *schema.ResourceData, meta interface{})
return nil return nil
} }
func resourceAwsOpsworksInstanceImport(
d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
// Neither delete_eip nor delete_ebs can be fetched
// from any API call, so we need to default to the values
// we set in the schema by default
d.Set("delete_ebs", true)
d.Set("delete_eip", true)
return []*schema.ResourceData{d}, nil
}
func startOpsworksInstance(d *schema.ResourceData, meta interface{}, wait bool) error { func startOpsworksInstance(d *schema.ResourceData, meta interface{}, wait bool) error {
client := meta.(*AWSClient).opsworksconn client := meta.(*AWSClient).opsworksconn

View File

@ -12,6 +12,29 @@ import (
"github.com/hashicorp/terraform/terraform" "github.com/hashicorp/terraform/terraform"
) )
func TestAccAWSOpsworksInstance_importBasic(t *testing.T) {
stackName := fmt.Sprintf("tf-%d", acctest.RandInt())
resourceName := "aws_opsworks_instance.tf-acc"
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAwsOpsworksInstanceDestroy,
Steps: []resource.TestStep{
{
Config: testAccAwsOpsworksInstanceConfigCreate(stackName),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"state"}, //state is something we pass to the API and get back as status :(
},
},
})
}
func TestAccAWSOpsworksInstance(t *testing.T) { func TestAccAWSOpsworksInstance(t *testing.T) {
stackName := fmt.Sprintf("tf-%d", acctest.RandInt()) stackName := fmt.Sprintf("tf-%d", acctest.RandInt())
var opsinst opsworks.Instance var opsinst opsworks.Instance
@ -20,7 +43,7 @@ func TestAccAWSOpsworksInstance(t *testing.T) {
Providers: testAccProviders, Providers: testAccProviders,
CheckDestroy: testAccCheckAwsOpsworksInstanceDestroy, CheckDestroy: testAccCheckAwsOpsworksInstanceDestroy,
Steps: []resource.TestStep{ Steps: []resource.TestStep{
resource.TestStep{ {
Config: testAccAwsOpsworksInstanceConfigCreate(stackName), Config: testAccAwsOpsworksInstanceConfigCreate(stackName),
Check: resource.ComposeTestCheckFunc( Check: resource.ComposeTestCheckFunc(
testAccCheckAWSOpsworksInstanceExists( testAccCheckAWSOpsworksInstanceExists(
@ -58,7 +81,7 @@ func TestAccAWSOpsworksInstance(t *testing.T) {
), ),
), ),
}, },
resource.TestStep{ {
Config: testAccAwsOpsworksInstanceConfigUpdate(stackName), Config: testAccAwsOpsworksInstanceConfigUpdate(stackName),
Check: resource.ComposeTestCheckFunc( Check: resource.ComposeTestCheckFunc(
testAccCheckAWSOpsworksInstanceExists( testAccCheckAWSOpsworksInstanceExists(

View File

@ -132,3 +132,11 @@ The following attributes are exported:
* `tenancy` - The Instance tenancy * `tenancy` - The Instance tenancy
* `security_group_ids` - The associated security groups. * `security_group_ids` - The associated security groups.
## Import
Opsworks Instances can be imported using the `instance id`, e.g.
```
$ terraform import aws_opsworks_instance.my_instance 4d6d1710-ded9-42a1-b08e-b043ad7af1e2
```