Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

resource/aws_launch_configuration: Add support for ebs_block_device.*.no_device #4070

Merged
merged 2 commits into from
Apr 5, 2018

Conversation

radeksimko
Copy link
Member

@radeksimko radeksimko commented Apr 5, 2018

Closes #2132

Original commit & authorship is retained (as usually) - thanks @maxfortune for the initial work.

As described in the commit message I added an acceptance test and reflected the new field in Read() so that drifts are detected as user would normally expect.


I played with multiple different solutions before eventually choosing this one. While it may not look ideal (due to awkward workaround for delete_on_termination), the other ones I considered had more annoying downsides. Here's a complete list of solutions I decided to stash:

  • Big refactoring the whole schema to reflect the API more accurately (i.e. replacing ebs_block_device, ephemeral_block_device & root_block_device with block_device_mapping and nested ebs field).
    • This seemed to be a good idea until I read the reasoning behind the current "abstracted" schema. While some reasons (about ephemeral devices not being available in API) don't necessarily apply here in the context of Launch Configuration I still think that keeping device-related schemas across resources (EC2 instance, spot instance, AMI, ...) consistent is important for the UX.
  • Small refactoring of the ebs_block_device schema to make all Ebs fields actually optional (i.e. nest fields like delete_on_termination under new ebs field) and never conflict with NoDevice.
    • I realized that migration to the new schema is very difficult. We'd have to suppress drift detection for either the new or old (deprecated) fields because of how Set index for ebs_block_device is computed - it has no way of knowing whether a value comes explicitly from config or is just computed (new ebs block in this case).
  • Removing Default: true from delete_on_termination and forcing the user to be explicit.
    • I realized that this would probably make it less convenient for some users (since default API & CloudFormation behaviour is delete_on_termination = true) and it would also force us to introduce a breaking change as state migration has no way of knowing whether "delete_on_termination": "true" in state comes from an explicit config or just reflects default value. Making the field Computed wasn't very sound idea either because we'd loose the ability to detect drifts (from default delete_on_termination = true).

@radeksimko radeksimko added enhancement Requests to existing resources that expand the functionality or scope. service/autoscaling Issues and PRs that pertain to the autoscaling service. labels Apr 5, 2018
@radeksimko radeksimko requested a review from a team April 5, 2018 15:01
@ghost ghost added the size/M Managed by automation to categorize the size of a PR. label Apr 5, 2018
Copy link
Contributor

@bflad bflad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Passed acceptance testing but I do have a question why the one set hash required updating.

10 tests passed (all tests)
=== RUN   TestAccAWSLaunchConfiguration_withSpotPrice
--- PASS: TestAccAWSLaunchConfiguration_withSpotPrice (8.94s)
=== RUN   TestAccAWSLaunchConfiguration_withEncryption
--- PASS: TestAccAWSLaunchConfiguration_withEncryption (11.63s)
=== RUN   TestAccAWSLaunchConfiguration_basic
--- PASS: TestAccAWSLaunchConfiguration_basic (17.03s)
=== RUN   TestAccAWSLaunchConfiguration_withBlockDevices
--- PASS: TestAccAWSLaunchConfiguration_withBlockDevices (19.48s)
=== RUN   TestAccAWSLaunchConfiguration_withVpcClassicLink
--- PASS: TestAccAWSLaunchConfiguration_withVpcClassicLink (19.96s)
=== RUN   TestAccAWSLaunchConfiguration_updateEbsBlockDevices
--- PASS: TestAccAWSLaunchConfiguration_updateEbsBlockDevices (24.54s)
=== RUN   TestAccAWSLaunchConfiguration_importBasic
--- PASS: TestAccAWSLaunchConfiguration_importBasic (25.89s)
=== RUN   TestAccAWSLaunchConfiguration_updateRootBlockDevice
--- PASS: TestAccAWSLaunchConfiguration_updateRootBlockDevice (26.51s)
=== RUN   TestAccAWSLaunchConfiguration_ebs_noDevice
--- PASS: TestAccAWSLaunchConfiguration_ebs_noDevice (29.16s)
=== RUN   TestAccAWSLaunchConfiguration_withIAMProfile
--- PASS: TestAccAWSLaunchConfiguration_withIAMProfile (30.25s)

@@ -281,15 +281,37 @@ func TestAccAWSLaunchConfiguration_updateEbsBlockDevices(t *testing.T) {
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSLaunchConfigurationExists("aws_launch_configuration.baz", &conf),
resource.TestCheckResourceAttr(
"aws_launch_configuration.baz", "ebs_block_device.2764618555.volume_size", "9"),
"aws_launch_configuration.baz", "ebs_block_device.1393547169.volume_size", "9"),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this okay that it changed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It worried me too when I saw that, but I did verify that state migration is not necessary:

$ terraform init && terraform apply && terraform plan

Initializing provider plugins...

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  + aws_launch_configuration.baz
      id:                                                <computed>
      associate_public_ip_address:                       "false"
      ebs_block_device.#:                                "1"
      ebs_block_device.2764618555.delete_on_termination: "true"
      ebs_block_device.2764618555.device_name:           "/dev/sdb"
      ebs_block_device.2764618555.encrypted:             "true"
      ebs_block_device.2764618555.iops:                  <computed>
      ebs_block_device.2764618555.snapshot_id:           <computed>
      ebs_block_device.2764618555.volume_size:           "9"
      ebs_block_device.2764618555.volume_type:           <computed>
      ebs_optimized:                                     <computed>
      enable_monitoring:                                 "true"
      image_id:                                          "ami-5189a661"
      instance_type:                                     "t2.micro"
      key_name:                                          <computed>
      name:                                              <computed>
      root_block_device.#:                               "1"
      root_block_device.0.delete_on_termination:         "true"
      root_block_device.0.iops:                          <computed>
      root_block_device.0.volume_size:                   "11"
      root_block_device.0.volume_type:                   "gp2"


Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_launch_configuration.baz: Creating...
  associate_public_ip_address:                       "" => "false"
  ebs_block_device.#:                                "" => "1"
  ebs_block_device.2764618555.delete_on_termination: "" => "true"
  ebs_block_device.2764618555.device_name:           "" => "/dev/sdb"
  ebs_block_device.2764618555.encrypted:             "" => "true"
  ebs_block_device.2764618555.iops:                  "" => "<computed>"
  ebs_block_device.2764618555.snapshot_id:           "" => "<computed>"
  ebs_block_device.2764618555.volume_size:           "" => "9"
  ebs_block_device.2764618555.volume_type:           "" => "<computed>"
  ebs_optimized:                                     "" => "<computed>"
  enable_monitoring:                                 "" => "true"
  image_id:                                          "" => "ami-5189a661"
  instance_type:                                     "" => "t2.micro"
  key_name:                                          "" => "<computed>"
  name:                                              "" => "<computed>"
  root_block_device.#:                               "" => "1"
  root_block_device.0.delete_on_termination:         "" => "true"
  root_block_device.0.iops:                          "" => "<computed>"
  root_block_device.0.volume_size:                   "" => "11"
  root_block_device.0.volume_type:                   "" => "gp2"
aws_launch_configuration.baz: Creation complete after 5s (ID: terraform-20180405195506238300000001)

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

aws_launch_configuration.baz: Refreshing state... (ID: terraform-20180405195506238300000001)

------------------------------------------------------------------------

No changes. Infrastructure is up-to-date.

This means that Terraform did not detect any differences between your
configuration and real physical resources that exist. As a result, no
actions need to be performed.

$ terraform init && terraform plan

Initializing provider plugins...

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

aws_launch_configuration.baz: Refreshing state... (ID: terraform-20180405195506238300000001)

------------------------------------------------------------------------

No changes. Infrastructure is up-to-date.

This means that Terraform did not detect any differences between your
configuration and real physical resources that exist. As a result, no
actions need to be performed.

$ terraform show
aws_launch_configuration.baz:
  id = terraform-20180405195506238300000001
  associate_public_ip_address = false
  ebs_block_device.# = 1
  ebs_block_device.2764618555.delete_on_termination = true
  ebs_block_device.2764618555.device_name = /dev/sdb
  ebs_block_device.2764618555.encrypted = true
  ebs_block_device.2764618555.iops = 0
  ebs_block_device.2764618555.snapshot_id =
  ebs_block_device.2764618555.volume_size = 9
  ebs_block_device.2764618555.volume_type =
  ebs_optimized = false
  enable_monitoring = true
  ephemeral_block_device.# = 0
  iam_instance_profile =
  image_id = ami-5189a661
  instance_type = t2.micro
  key_name =
  name = terraform-20180405195506238300000001
  root_block_device.# = 1
  root_block_device.0.delete_on_termination = true
  root_block_device.0.iops = 0
  root_block_device.0.volume_size = 11
  root_block_device.0.volume_type = gp2
  security_groups.# = 0
  spot_price =
  vpc_classic_link_id =
  vpc_classic_link_security_groups.# = 0


$ terraform refresh
aws_launch_configuration.baz: Refreshing state... (ID: terraform-20180405195506238300000001)

$ terraform show
aws_launch_configuration.baz:
  id = terraform-20180405195506238300000001
  associate_public_ip_address = false
  ebs_block_device.# = 1
  ebs_block_device.1393547169.delete_on_termination = true
  ebs_block_device.1393547169.device_name = /dev/sdb
  ebs_block_device.1393547169.encrypted = true
  ebs_block_device.1393547169.iops = 0
  ebs_block_device.1393547169.no_device = false
  ebs_block_device.1393547169.snapshot_id =
  ebs_block_device.1393547169.volume_size = 9
  ebs_block_device.1393547169.volume_type =
  ebs_optimized = false
  enable_monitoring = true
  ephemeral_block_device.# = 0
  iam_instance_profile =
  image_id = ami-5189a661
  instance_type = t2.micro
  key_name =
  name = terraform-20180405195506238300000001
  root_block_device.# = 1
  root_block_device.0.delete_on_termination = true
  root_block_device.0.iops = 0
  root_block_device.0.volume_size = 11
  root_block_device.0.volume_type = gp2
  security_groups.# = 0
  spot_price =
  vpc_classic_link_id =
  vpc_classic_link_security_groups.# = 0

You can see in the last step during refresh that index is automatically re-computed and plan does not show any diff in the previous step. I don't know the exact reason behind that, but I'm confident that we don't need state migration.

@radeksimko radeksimko merged commit c932629 into master Apr 5, 2018
@radeksimko radeksimko deleted the f-lc-no-device branch April 5, 2018 20:00
@bflad bflad added this to the v1.14.0 milestone Apr 6, 2018
@bflad
Copy link
Contributor

bflad commented Apr 6, 2018

This has been released in version 1.14.0 of the AWS provider. Please see the Terraform documentation on provider versioning or reach out if you need any assistance upgrading.

@ghost
Copy link

ghost commented Apr 6, 2020

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thanks!

@ghost ghost locked and limited conversation to collaborators Apr 6, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement Requests to existing resources that expand the functionality or scope. service/autoscaling Issues and PRs that pertain to the autoscaling service. size/M Managed by automation to categorize the size of a PR.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants