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

Applying Security Group changes to aws_instance should update, not destroy/recreate #14416

Closed
bloo opened this issue May 11, 2017 · 10 comments
Closed

Comments

@bloo
Copy link

bloo commented May 11, 2017

Terraform Version

0.9.4

Affected Resource(s)

  • aws_instance
  • aws_security_group

Expected Behavior

Altering aws_security_group definitions should recreate those, then update the aws_instances that were attached to them.

It looks like you can update instances via the AWS API:

http://docs.aws.amazon.com/cli/latest/reference/ec2/modify-instance-attribute.html

Actual Behavior

AWS instances are destroyed and recreated, instead of updated in place.

@grubernaut
Copy link
Contributor

Hey @bloo, thanks for the issue!

Do you have an example configuration that can reproduce the issue? Thanks!

@bloo
Copy link
Author

bloo commented May 12, 2017

Thanks @grubernaut - below is a simple terraform that contains 2 aws_security_groups and 1 aws_instance. The instance references only 1 of the security_groups to start.

  1. terraform apply - creates all 3 resources
  2. uncomment line 13: #"access-https"
  3. terraform apply - should update aws_instance in place, but instead destroys and recreates it.
provider "aws" {
  access_key = "???"
  secret_key = "???"
  region     = "us-east-1"
}

resource "aws_instance" "dummy" {
  ami               = "ami-6d1c2007"
  instance_type     = "t2.micro"
  availability_zone = "us-east-1a"
  security_groups = [
    "access-http",
    #"access-https"
  ]
}

resource "aws_security_group" "access-https" {
  name = "access-https"
  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

resource "aws_security_group" "access-http" {
  name = "access-http"
  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

After uncommenting line 13 and running terraform plan, this is the output:

$ terraform plan
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_security_group.access-https: Refreshing state... (ID: sg-474ad539)
aws_security_group.access-http: Refreshing state... (ID: sg-2a4fd054)
aws_instance.dummy: Refreshing state... (ID: i-0debc5cd1bc48deba)
The Terraform execution plan has been generated and is shown below.
Resources are shown in alphabetical order for quick scanning. Green resources
will be created (or destroyed and then created if an existing resource
exists), yellow resources are being changed in-place, and red resources
will be destroyed. Cyan entries are data sources to be read.

Note: You didn't specify an "-out" parameter to save this plan, so when
"apply" is called, Terraform can't guarantee this is what will execute.

-/+ aws_instance.dummy
    ami:                         "ami-6d1c2007" => "ami-6d1c2007"
    associate_public_ip_address: "true" => "<computed>"
    availability_zone:           "us-east-1a" => "us-east-1a"
    ebs_block_device.#:          "0" => "<computed>"
    ephemeral_block_device.#:    "0" => "<computed>"
    instance_state:              "running" => "<computed>"
    instance_type:               "t2.micro" => "t2.micro"
    ipv6_addresses.#:            "0" => "<computed>"
    key_name:                    "" => "<computed>"
    network_interface_id:        "eni-0113fac8" => "<computed>"
    placement_group:             "" => "<computed>"
    private_dns:                 "ip-172-31-75-42.ec2.internal" => "<computed>"
    private_ip:                  "172.31.75.42" => "<computed>"
    public_dns:                  "ec2-54-208-206-103.compute-1.amazonaws.com" => "<computed>"
    public_ip:                   "54.208.206.103" => "<computed>"
    root_block_device.#:         "1" => "<computed>"
    security_groups.#:           "1" => "2" (forces new resource)
    security_groups.2441721151:  "" => "access-https" (forces new resource)
    security_groups.3803437083:  "access-http" => "access-http"
    source_dest_check:           "true" => "true"
    subnet_id:                   "subnet-2f25cf03" => "<computed>"
    tenancy:                     "default" => "<computed>"
    vpc_security_group_ids.#:    "0" => "<computed>"


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

@bloo
Copy link
Author

bloo commented May 18, 2017

Hi @grubernaut - just wondering if there's anything more I can contribute to this?

@grubernaut
Copy link
Contributor

Hey @bloo, extremely sorry, but I haven't had a chance to look at this issue yet. I'll attempt to dive in tomorrow!

@rfletcher
Copy link
Contributor

@bloo Your example defines an EC2 Classic instance. In EC2 Classic, an instance's security groups can only be set at launch time. They can't be modified. That is possible for VPC instances though, and Terraform behaves as you expect there.

The EC2 Classic limitation is indicated (though subtly) by the AWS documentation you've linked in the original report (emphasis mine):

--groups (list)

[EC2-VPC] Changes the security groups of the instance. You must specify at least one security
group, even if it's just the default security group for the VPC. You must specify the security group ID, not the security group name.

I don't think there's a Terraform bug here.

@bloo
Copy link
Author

bloo commented May 19, 2017

@rfletcher to clarify, I should use the 2nd parameter, not the first one - and it'll allocate a non-classic EC2 instance?

security_groups - The associated security groups.
vpc_security_group_ids - The associated security groups in non-default VPC

@rfletcher
Copy link
Contributor

rfletcher commented May 19, 2017

That's how you'll set any security groups once it is in VPC, but to launch it in VPC you need to specify the subnet. See the subnet_id argument.

@bloo
Copy link
Author

bloo commented May 19, 2017

@rfletcher thanks for the clarification!

@bloo bloo closed this as completed May 19, 2017
@grubernaut
Copy link
Contributor

Thanks for the response here @rfletcher! 😄

@ghost
Copy link

ghost commented Apr 12, 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 have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@ghost ghost locked and limited conversation to collaborators Apr 12, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants