Answers: <p>You can use a remote backend as a data source. That is working well for us thus far but this project is not very mature and we will likely refactor a time or ten.</p>
  
  <pre><code>data "terraform_remote_state" "network" {
    backend = "s3"
    config {
      // some variables related to config would likely go here
    }
  }
  </code></pre>
  
  <p>then for the teams not managing the network to consume that data you could create an instance like (special attention to the <code>subnet_id</code> here):</p>
  
  <pre><code>resource "aws_instance" "oracle_ec2" {
    ami           = "${lookup(var.ami, var.region)}"
    instance_type = "${var.instance_type}"
    key_name      = "${var.key_name}"
    subnet_id     = "${data.terraform_remote_state.network.subnet_id}"
  }
  </code></pre>
  
  <p>The network team should be able to manage the networking infrastructure and you should be able to consume those values based on current state. </p>
  
  <p><a href="https://www.terraform.io/docs/providers/terraform/d/remote_state.html" rel="noreferrer">Terraform Remote State Data Source</a></p>
  
  <blockquote>
    <p>2) If new instances launch as t2.large(Instance type passed as variable) while old ones run on t2.micro</p>
  </blockquote>
  
  <p>If you change the instance type from <code>t2.micro</code> to <code>t2.large</code> then yes the <code>t2.micro</code> instances will be destroyed and replaced with the <code>t2.large</code>. The name of the game is immutability outside of meta data changes like altering tags. Look into lifecycle hooks to alleviate some of this pain</p>
  
  <pre><code>lifecycle {
    create_before_destroy = true
  }
  </code></pre>
  
  <blockquote>
    <p>will it recreate old instances too if I just increase the count</p>
  </blockquote>
  
  <p>No, current instances would not be destroyed. Terraform will check the state to see how many instances you currently have. If more instances are necessary, terraform will know how many instances to create and create the instances necessary</p>
  
  <blockquote>
    <p>Also, is there a way to automate this process i.e. append something like a template for new EC2 instance to existing .tf file.</p>
  </blockquote>
  
  <p>Not sure what exactly you mean by this one. What I will say is that having the data coupled to the instance itself makes instance immutability and using terraform more difficult. A (untested and unproven) thought and potential solution in my head is to:</p>
  
  <pre><code>//create an ebs volume
  resource "aws_ebs_volume" "oracle-data" {
    ...
  }
  
  //attach that volume to the instance
  resource "aws_volume_attachment" "oracle-data-attachment" {
    ...
  }
  </code></pre>
  
  <p>with some bash involved for an init script that creates and mounts the new volume to be used in conjunction with the <code>aws_volume_attachment</code> resource. That could potentially create a new instance preserving the EBS volume then reattaching it to the new instance.</p>
  
Answers: CC BY-SA 3.0
Answers: 2017-12-12T20:23:06.583Z
Answers: Thanks @TechDawg for the details answer, just had the opportunity to get back to Terraform.
  
  I will try to rephrase my last question. Assuming, I have 5 t2.medium EC2 instances running already. I would like to add 5 more EC2 Instances but with a different set of configuration, this new change is going to flow from ServiceNow which the user will be using to choose the type of hardware. Should this new request, be turned into a template for EC2 instance and get appended as new set of EC2 resources in the TF file ?
Answers: Dvusrgme
Answers: CC BY-SA 3.0
Answers: 2017-12-12T20:29:06.600Z
Answers: For example: 
  
  
  For example: 
  
  ----Current-->
  resource "aws_instance" "oracle_ec2" {
    ami           = "${lookup(var.ami, var.region)}"
    instance_type = "t2.medium"
    count = 5
  }
  ----Append --->
  resource "aws_instance" "oracle_ec2" {
    ami           = "${lookup(var.ami, var.region)}"
    instance_type = "m4.xlarge"
    count = 5
  }
Answers: Dvusrgme
Answers: CC BY-SA 3.0
Answers: 2017-12-07T20:22:25.767Z
Answers: 2017-12-07T20:22:25.767Z
Answers: TechDawg270
Body: <p>We are planning to use Terraform for provisioning EC2 instance which will host Oracle DB. While we are able to achieve this, there are some questions for which I am searching for suggestions / feedback's. </p>
  
  <p><strong>Below is the directory structure we are planning:</strong></p>
  
  <pre><code>|aws      
    |Environments
      |STAGING
          |Modules
             |Compute
             |Networking
  
      |PRODUCTION
          |Modules
             |Compute
             |Networking
  </code></pre>
  
  <p><strong>Questions:</strong></p>
  
  <ul>
  <li><p>We are able to create EC2 instances using existing VPC. As VPC is not something that will be owned by my team. Is it enough to keep VPC ID, SUBNET ID, etc as variables in EC2 resource or is there a best practice to keep them in modules for existing VPC ? Overall, our tf codes are not going to manage the VPC's, just use what is being giving to us, but want to make it dynamic so that changes are simple, yet DRY</p></li>
  <li><p>We are planning for Continuous Development, meaning, developers / requester will have the ability to request for a new ec2 instance with certain version of database. Right now, we are installing db with bootstrap scripts. Though this works as expected. Increasing count for more than 1 instance works, but what if the configuration slightly changes. </p></li>
  </ul>
  
  <blockquote>
    <p><strong>For example:</strong> </p>
    
    <p>1) If I need more  capacity on root volume for the new instance,    changing the existing resource shows a plan that will
    destroy    existing resource and recreate. <strong>How can we achieve this
    ?</strong> Is    duplicating the <strong>aws_instance</strong> resource, the only way when
    the    configuration changes for new EC2 instance?</p>
    
    <p>2) If new instances launch as t2.large(Instance type passed as variable) while old ones run on t2.micro, will it recreate old
    instances too if I just increase the count</p>
  </blockquote>
  
  <p><em>Also, is there a way to automate this process i.e. append something like a template for new EC2 instance to existing .tf file.</em> </p>
  
  <p><strong>What do we have now</strong></p>
  
  <p><strong><em>Main.tf</em></strong></p>
  
  <pre><code>provider "aws" {
    access_key = "${var.access_key}"
    secret_key = "${var.secret_key}"
    region     = "${var.region}"
  }
  
  resource "aws_instance" "oracle_ec2" {
    ami           = "${lookup(var.ami, var.region)}"
    instance_type = "${var.instance_type}"
    key_name      = "${var.key_name}"
    subnet_id     = "${var.subnet_id}"
  
    vpc_security_group_ids = ["${aws_security_group.oracle_sg_new.id}"]
  
    root_block_device {
      volume_type           = "gp2"
      volume_size           = 10
      delete_on_termination = true
    }
  
    ebs_block_device {
      device_name           = "/dev/xvdb"
      volume_type           = "gp2"
      volume_size           = 200
      delete_on_termination = true
    }    
  
    count = "${var.instance_count}"
  
    tags {
      Name = "Ora"
    }
  
  }
  </code></pre>
  
Tags: <amazon-web-services><terraform><amazon-s3><infrastructure-as-code>
Title: How to apply using Terraform to launch multiple EC2 Resource with different configs (VPC not maintained by TF)
UserDisplayName: Dvusrgme
ThreadText: # How to apply using Terraform to launch multiple EC2 Resource with different configs (VPC not maintained by TF)
  
  (Asked by: username_0 on 2017-11-30)
  
  We are planning to use Terraform for provisioning EC2 instance which will host Oracle DB. While we are able to achieve this, there are some questions for which I am searching for suggestions / feedback's.
  
  **Below is the directory structure we are planning:**
  
  ```
  |aws      
    |Environments
      |STAGING
          |Modules
             |Compute
             |Networking
  
      |PRODUCTION
          |Modules
             |Compute
             |Networking
  
  ```
  
  **Questions:**
  
  * We are able to create EC2 instances using existing VPC. As VPC is not something that will be owned by my team. Is it enough to keep VPC ID, SUBNET ID, etc as variables in EC2 resource or is there a best practice to keep them in modules for existing VPC ? Overall, our tf codes are not going to manage the VPC's, just use what is being giving to us, but want to make it dynamic so that changes are simple, yet DRY
  * We are planning for Continuous Development, meaning, developers / requester will have the ability to request for a new ec2 instance with certain version of database. Right now, we are installing db with bootstrap scripts. Though this works as expected. Increasing count for more than 1 instance works, but what if the configuration slightly changes.
  
  > **For example:**
  >
  > 1) If I need more capacity on root volume for the new instance, changing the existing resource shows a plan that will
  > destroy existing resource and recreate. **How can we achieve this
  > ?** Is duplicating the **aws\_instance** resource, the only way when
  > the configuration changes for new EC2 instance?
  >
  > 2) If new instances launch as t2.large(Instance type passed as variable) while old ones run on t2.micro, will it recreate old
  > instances too if I just increase the count
  
  *Also, is there a way to automate this process i.e. append something like a template for new EC2 instance to existing .tf file.*
  
  **What do we have now**
  
  ***Main.tf***
  
  ```
  provider "aws" {
    access_key = "${var.access_key}"
    secret_key = "${var.secret_key}"
    region     = "${var.region}"
  }
  
  resource "aws_instance" "oracle_ec2" {
    ami           = "${lookup(var.ami, var.region)}"
    instance_type = "${var.instance_type}"
    key_name      = "${var.key_name}"
    subnet_id     = "${var.subnet_id}"
  
    vpc_security_group_ids = ["${aws_security_group.oracle_sg_new.id}"]
  
    root_block_device {
      volume_type           = "gp2"
      volume_size           = 10
      delete_on_termination = true
    }
  
    ebs_block_device {
      device_name           = "/dev/xvdb"
      volume_type           = "gp2"
      volume_size           = 200
      delete_on_termination = true
    }    
  
    count = "${var.instance_count}"
  
    tags {
      Name = "Ora"
    }
  
  }
  
  ```
  
  **Tags:** amazon-web-services, terraform, amazon-s3, infrastructure-as-code
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2017-12-07. Score: 6 | Accepted answer
  
  You can use a remote backend as a data source. That is working well for us thus far but this project is not very mature and we will likely refactor a time or ten.
  
  ```
  data "terraform_remote_state" "network" {
    backend = "s3"
    config {
      // some variables related to config would likely go here
    }
  }
  
  ```
  
  then for the teams not managing the network to consume that data you could create an instance like (special attention to the `subnet_id` here):
  
  ```
  resource "aws_instance" "oracle_ec2" {
    ami           = "${lookup(var.ami, var.region)}"
    instance_type = "${var.instance_type}"
    key_name      = "${var.key_name}"
    subnet_id     = "${data.terraform_remote_state.network.subnet_id}"
  }
  
  ```
  
  The network team should be able to manage the networking infrastructure and you should be able to consume those values based on current state.
  
  [Terraform Remote State Data Source](https://www.terraform.io/docs/providers/terraform/d/remote_state.html)
  
  > 2) If new instances launch as t2.large(Instance type passed as variable) while old ones run on t2.micro
  
  If you change the instance type from `t2.micro` to `t2.large` then yes the `t2.micro` instances will be destroyed and replaced with the `t2.large`. The name of the game is immutability outside of meta data changes like altering tags. Look into lifecycle hooks to alleviate some of this pain
  
  ```
  lifecycle {
    create_before_destroy = true
  }
  
  ```
  
  > will it recreate old instances too if I just increase the count
  
  No, current instances would not be destroyed. Terraform will check the state to see how many instances you currently have. If more instances are necessary, terraform will know how many instances to create and create the instances necessary
  
  > Also, is there a way to automate this process i.e. append something like a template for new EC2 instance to existing .tf file.
  
  Not sure what exactly you mean by this one. What I will say is that having the data coupled to the instance itself makes instance immutability and using terraform more difficult. A (untested and unproven) thought and potential solution in my head is to:
  
  ```
  //create an ebs volume
  resource "aws_ebs_volume" "oracle-data" {
    ...
  }
  
  //attach that volume to the instance
  resource "aws_volume_attachment" "oracle-data-attachment" {
    ...
  }
  
  ```
  
  with some bash involved for an init script that creates and mounts the new volume to be used in conjunction with the `aws_volume_attachment` resource. That could potentially create a new instance preserving the EBS volume then reattaching it to the new instance.
  
  > **Comments:**
  > **username_0**: Thanks @TechDawg for the details answer, just had the opportunity to get back to Terraform.  I will try to rephrase my last question. Assuming, I have 5 t2.medium EC2 instances running already. I would like to add 5 more EC2 Instances but with a different set of configuration, this new change is going to flow from ServiceNow which the user will be using to choose the type of hardware. Should this new request, be turned into a template for EC2 instance and get appended as new set of EC2 resources in the TF file ?  
  > **username_0**: For example:    For example:   ----Current--> resource "aws_instance" "oracle_ec2" {   ami           = "${lookup(var.ami, var.region)}"   instance_type = "t2.medium"   count = 5 } ----Append ---> resource "aws_instance" "oracle_ec2" {   ami           = "${lookup(var.ami, var.region)}"   instance_type = "m4.xlarge"   count = 5 }  
  
  ---
  
  