github.com/jmbataller/terraform@v0.6.8-0.20151125192640-b7a12e3a580c/website/source/docs/modules/create.html.markdown (about)

     1  ---
     2  layout: "docs"
     3  page_title: "Creating Modules"
     4  sidebar_current: "docs-modules-create"
     5  description: |-
     6    Creating modules in Terraform is easy. You may want to do this to better organize your code, to make a reusable component, or just to learn more about Terraform. For any reason, if you already know the basics of Terraform, creating a module is a piece of cake.
     7  ---
     8  
     9  # Creating Modules
    10  
    11  Creating modules in Terraform is easy. You may want to do this to better
    12  organize your code, to make a reusable component, or just to learn more about
    13  Terraform. For any reason, if you already know the basics of Terraform,
    14  creating a module is a piece of cake.
    15  
    16  Modules in Terraform are just folders with Terraform files. In fact,
    17  when you run `terraform apply`, the current working directory holding
    18  the Terraform files you're applying comprise what is called the
    19  _root module_. It itself is a valid module.
    20  
    21  Therefore, you can enter the source of any module, run `terraform apply`,
    22  and expect it to work (assuming you satisfy the required variables, if any).
    23  
    24  ## An Example
    25  
    26  Within a folder containing Terraform configurations, create a subfolder
    27  "child". In this subfolder, make one empty "main.tf" file. Then, back in
    28  the root folder containing the "child" folder, add this to one of the
    29  Terraform files:
    30  
    31  ```
    32  module "child" {
    33  	source = "./child"
    34  }
    35  ```
    36  
    37  This will work. You've created your first module! You can add resources
    38  to the child module to see how that interaction works.
    39  
    40  Note: Prior to running the above, you'll have to run
    41  [the get command](/docs/commands/get.html) for Terraform to sync
    42  your modules. This should be instant since the module is just a local path.
    43  
    44  ## Inputs/Outputs
    45  
    46  To make modules more useful than simple isolated containers of Terraform
    47  configurations, modules can be configured and also have outputs that can be
    48  consumed by the configuration using the module.
    49  
    50  Inputs of a module are [variables](/docs/configuration/variables.html)
    51  and outputs are [outputs](/docs/configuration/outputs.html). There is no
    52  special syntax to define these, they're defined just like any other
    53  variables or outputs.
    54  
    55  In the "child" module we created above, add the following:
    56  
    57  ```
    58  variable "memory" {}
    59  
    60  output "received" {
    61  	value = "${var.memory}"
    62  }
    63  ```
    64  
    65  This will create a required variable "memory" and then an output "received"
    66  that will simply be the value of the memory variable.
    67  
    68  You can then configure the module and use the output like so:
    69  
    70  ```
    71  module "child" {
    72  	source = "./child"
    73  
    74  	memory = "1G"
    75  }
    76  
    77  output "child_memory" {
    78  	value = "${module.child.received}"
    79  }
    80  ```
    81  
    82  If you run `apply`, you'll again see that this works.
    83  
    84  And that is all there is to it. Variables and outputs are used to configure
    85  modules and provide results. Resources within a module are isolated,
    86  and the whole thing is managed as a single unit.
    87  
    88  ## Paths and Embedded Files
    89  
    90  It is sometimes useful to embed files within the module that aren't
    91  Terraform configuration files, such as a script to provision a resource
    92  or a file to upload.
    93  
    94  In these cases, you can't use a relative path, since paths in Terraform
    95  are generally relative to the working directory that Terraform was executed
    96  from. Instead, you want to use a module-relative path. To do this, use
    97  the [path interpolated variables](/docs/configuration/interpolation.html).
    98  
    99  An example is shown below:
   100  
   101  ```
   102  resource "aws_instance" "server" {
   103  	...
   104  
   105  	provisioner "remote-exec" {
   106  		script = "${path.module}/script.sh"
   107  	}
   108  }
   109  ```
   110  
   111  In the above, we use `${path.module}` to get a module-relative path. This
   112  is usually what you'll want in any case.
   113  
   114  ## Nested Modules
   115  
   116  You can use a module within a module just like you would anywhere else.
   117  This module will be hidden from the root user, so you'll have re-expose any
   118  variables if you need to, as well as outputs.
   119  
   120  The [get command](/docs/commands/get.html) will automatically get all
   121  nested modules as well.
   122  
   123  You don't have to worry about conflicting versions of modules, since
   124  Terraform builds isolated subtrees of all dependencies. For example,
   125  one module might use version 1.0 of module "foo" and another module
   126  might use version 2.0 of module "foo", and this would all work fine
   127  within Terraform since the modules are created separately.