github.com/Kevinklinger/open_terraform@v0.11.12-beta1/website/intro/getting-started/dependencies.html.md (about) 1 --- 2 layout: "intro" 3 page_title: "Resource Dependencies" 4 sidebar_current: "gettingstarted-deps" 5 description: |- 6 In this page, we're going to introduce resource dependencies, where we'll not only see a configuration with multiple resources for the first time, but also scenarios where resource parameters use information from other resources. 7 --- 8 9 # Resource Dependencies 10 11 In this page, we're going to introduce resource dependencies, 12 where we'll not only see a configuration with multiple resources 13 for the first time, but also scenarios where resource parameters 14 use information from other resources. 15 16 Up to this point, our example has only contained a single resource. 17 Real infrastructure has a diverse set of resources and resource 18 types. Terraform configurations can contain multiple resources, 19 multiple resource types, and these types can even span multiple 20 providers. 21 22 On this page, we'll show a basic example of multiple resources 23 and how to reference the attributes of other resources to configure 24 subsequent resources. 25 26 ## Assigning an Elastic IP 27 28 We'll improve our configuration by assigning an elastic IP to 29 the EC2 instance we're managing. Modify your `example.tf` and 30 add the following: 31 32 ```hcl 33 resource "aws_eip" "ip" { 34 instance = "${aws_instance.example.id}" 35 } 36 ``` 37 38 This should look familiar from the earlier example of adding 39 an EC2 instance resource, except this time we're building 40 an "aws\_eip" resource type. This resource type allocates 41 and associates an 42 [elastic IP](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html) 43 to an EC2 instance. 44 45 The only parameter for 46 [aws\_eip](/docs/providers/aws/r/eip.html) is "instance" which 47 is the EC2 instance to assign the IP to. For this value, we 48 use an interpolation to use an attribute from the EC2 instance 49 we managed earlier. 50 51 The syntax for this interpolation should be straightforward: 52 it requests the "id" attribute from the "aws\_instance.example" 53 resource. 54 55 ## Apply Changes 56 57 Run `terraform apply` to see how Terraform plans to apply this change. 58 The output will look similar to the following: 59 60 ``` 61 $ terraform apply 62 63 + aws_eip.ip 64 allocation_id: "<computed>" 65 association_id: "<computed>" 66 domain: "<computed>" 67 instance: "${aws_instance.example.id}" 68 network_interface: "<computed>" 69 private_ip: "<computed>" 70 public_ip: "<computed>" 71 72 + aws_instance.example 73 ami: "ami-b374d5a5" 74 availability_zone: "<computed>" 75 ebs_block_device.#: "<computed>" 76 ephemeral_block_device.#: "<computed>" 77 instance_state: "<computed>" 78 instance_type: "t2.micro" 79 key_name: "<computed>" 80 placement_group: "<computed>" 81 private_dns: "<computed>" 82 private_ip: "<computed>" 83 public_dns: "<computed>" 84 public_ip: "<computed>" 85 root_block_device.#: "<computed>" 86 security_groups.#: "<computed>" 87 source_dest_check: "true" 88 subnet_id: "<computed>" 89 tenancy: "<computed>" 90 vpc_security_group_ids.#: "<computed>" 91 ``` 92 93 Terraform will create two resources: the instance and the elastic 94 IP. In the "instance" value for the "aws\_eip", you can see the 95 raw interpolation is still present. This is because this variable 96 won't be known until the "aws\_instance" is created. It will be 97 replaced at apply-time. 98 99 As usual, Terraform prompts for confirmation before making any changes. 100 Answer `yes` to apply. The continued output will look similar to the 101 following: 102 103 ``` 104 # ... 105 aws_instance.example: Creating... 106 ami: "" => "ami-b374d5a5" 107 instance_type: "" => "t2.micro" 108 [..] 109 aws_instance.example: Still creating... (10s elapsed) 110 aws_instance.example: Creation complete 111 aws_eip.ip: Creating... 112 allocation_id: "" => "<computed>" 113 association_id: "" => "<computed>" 114 domain: "" => "<computed>" 115 instance: "" => "i-f3d77d69" 116 network_interface: "" => "<computed>" 117 private_ip: "" => "<computed>" 118 public_ip: "" => "<computed>" 119 aws_eip.ip: Creation complete 120 121 Apply complete! Resources: 2 added, 0 changed, 0 destroyed. 122 ``` 123 124 As shown above, Terraform created the EC2 instance before creating the Elastic 125 IP address. Due to the interpolation expression that passes the ID of the EC2 126 instance to the Elastic IP address, Terraform is able to infer a dependency, 127 and knows it must create the instance first. 128 129 ## Implicit and Explicit Dependencies 130 131 By studying the resource attributes used in interpolation expressions, 132 Terraform can automatically infer when one resource depends on another. 133 In the example above, the expression `${aws_instance.example.id}` creates 134 an _implicit dependency_ on the `aws_instance` named `example`. 135 136 Terraform uses this dependency information to determine the correct order 137 in which to create the different resources. In the example above, Terraform 138 knows that the `aws_instance` must be created before the `aws_eip`. 139 140 Implicit dependencies via interpolation expressions are the primary way 141 to inform Terraform about these relationships, and should be used whenever 142 possible. 143 144 Sometimes there are dependencies between resources that are _not_ visible to 145 Terraform. The `depends_on` argument is accepted by any resource and accepts 146 a list of resources to create _explicit dependencies_ for. 147 148 For example, perhaps an application we will run on our EC2 instance expects 149 to use a specific Amazon S3 bucket, but that dependency is configured 150 inside the application code and thus not visible to Terraform. In 151 that case, we can use `depends_on` to explicitly declare the dependency: 152 153 ```hcl 154 # New resource for the S3 bucket our application will use. 155 resource "aws_s3_bucket" "example" { 156 # NOTE: S3 bucket names must be unique across _all_ AWS accounts, so 157 # this name must be changed before applying this example to avoid naming 158 # conflicts. 159 bucket = "terraform-getting-started-guide" 160 acl = "private" 161 } 162 163 # Change the aws_instance we declared earlier to now include "depends_on" 164 resource "aws_instance" "example" { 165 ami = "ami-2757f631" 166 instance_type = "t2.micro" 167 168 # Tells Terraform that this EC2 instance must be created only after the 169 # S3 bucket has been created. 170 depends_on = ["aws_s3_bucket.example"] 171 } 172 ``` 173 174 ## Non-Dependent Resources 175 176 We can continue to build this configuration by adding another EC2 instance: 177 178 ```hcl 179 resource "aws_instance" "another" { 180 ami = "ami-b374d5a5" 181 instance_type = "t2.micro" 182 } 183 ``` 184 185 Because this new instance does not depend on any other resource, it can 186 be created in parallel with the other resources. Where possible, Terraform 187 will perform operations concurrently to reduce the total time taken to 188 apply changes. 189 190 Before moving on, remove this new resource from your configuration and 191 run `terraform apply` again to destroy it. We won't use this second instance 192 any further in the getting started guide. 193 194 ## Next 195 196 In this page you were introduced to using multiple resources, interpolating 197 attributes from one resource into another, and declaring dependencies between 198 resources to define operation ordering. 199 200 In the next section, [we'll use provisioners](/intro/getting-started/provision.html) 201 to do some basic bootstrapping of our launched instance.