github.com/trawler/terraform@v0.10.8-0.20171106022149-4b1c7a1d9b48/website/docs/modules/usage.html.markdown (about)

     1  ---
     2  layout: "docs"
     3  page_title: "Using Modules"
     4  sidebar_current: "docs-modules-usage"
     5  description: Using modules in Terraform is very similar to defining resources.
     6  ---
     7  
     8  # Module Usage
     9  
    10  Using child modules in Terraform is very similar to defining resources:
    11  
    12  ```shell
    13  module "consul" {
    14    source  = "hashicorp/consul/aws"
    15    servers = 3
    16  }
    17  ```
    18  
    19  You can view the full documentation for configuring modules in the [Module Configuration](/docs/configuration/modules.html) section.
    20  
    21  In modules we only specify a name, rather than a name and a type as for resources.
    22  This name is used elsewhere in the configuration to reference the module and
    23  its outputs.
    24  
    25  The source tells Terraform what to create. In this example, we instantiate
    26  the [Consul module for AWS](https://registry.terraform.io/modules/hashicorp/consul/aws)
    27  from the [Terraform Registry](https://registry.terraform.io). Other source
    28  types are supported, as described in the following section.
    29  
    30  Just like a resource, the a module's configuration can be deleted to destroy the
    31  resources belonging to the module.
    32  
    33  ## Source
    34  
    35  The only required configuration key for a module is the `source` parameter. The
    36  value of this tells Terraform where to download the module's source code.
    37  Terraform comes with support for a variety of module sources.
    38  
    39  The recommended source for external modules is a
    40  [Terraform Registry](/docs/registry/index.html), which provides the full
    41  capabilities of modules such as version constraints.
    42  Registry modules are specified using a simple slash-separated path like the
    43  `hashicorp/consul/aws` path used in the above example. The full source string
    44  for each registry module can be found from the registry website.
    45  
    46  Terraform also supports modules in local directories, identified by a relative
    47  path starting with either `./` or `../`. Such local modules are useful to
    48  organize code more complex repositories, and are described in more detail
    49  in [_Creating Modules_](/docs/modules/create.html).
    50  
    51  Finally, Terraform can download modules directly from various storage providers
    52  and version control systems. These sources do not support versioning and other
    53  registry benefits, but can be convenient for getting started when already
    54  available within an organization. The full list of available sources
    55  are documented in [the module sources documentation](/docs/modules/sources.html).
    56  
    57  When a configuration uses modules, they must first be installed by running
    58  [`terraform init`](/docs/commands/init.html):
    59  
    60  ```shell
    61  $ terraform init
    62  ```
    63  
    64  This command will download any modules that haven't been updated already,
    65  as well as performing other Terraform working directory initialization such
    66  as installing providers.
    67  
    68  By default the command will not check for available updates to already-installed
    69  modules, but you can use the `-update` option to check for available upgrades.
    70  When version constraints are specified (as described in the following section)
    71  a newer version will be used only if it is within the given constraint.
    72  
    73  ## Module Versions
    74  
    75  It is recommended to explicitly constrain the acceptable version numbers for
    76  each external module so that upstream changes aren't automatically adopted,
    77  since this may result in unexpected or unwanted changes changes.
    78  
    79  The `version` attribute within the `module` block is used for this purpose:
    80  
    81  ```shell
    82  module "consul" {
    83    source  = "hashicorp/consul/aws"
    84    version = "0.0.5"
    85  
    86    servers = 3
    87  }
    88  ```
    89  
    90  The `version` attribute value may either be a single explicit version or
    91  a version constraint expression. Constraint expressions use the following
    92  syntax to specify a _range_ of versions that are acceptable:
    93  
    94  * `>= 1.2.0`: version 1.2.0 or newer
    95  * `<= 1.2.0`: version 1.2.0 or older
    96  * `~> 1.2`: any non-beta patch release within the `1.2` range
    97  * `>= 1.0.0, <= 2.0.0`: any version between 1.0.0 and 2.0.0 inclusive
    98  
    99  When depending on third-party modules, references to specific versions are
   100  recommended since this ensures that updates only happen when convenient to you.
   101  
   102  For modules maintained within your organization, a version range strategy
   103  may be appropriate if a semantic versioning methodology is used consistently
   104  or if there is a well-defined release process that avoids unwanted updates.
   105  
   106  Version constraints are supported only for modules installed from a module
   107  registry, such as the [Terraform Registry](https://registry.terraform.io/).
   108  Other module sources may provide their own versioning mechanisms within the
   109  source string itself, or they may not support versions at all. In particular,
   110  modules whose sources are local file paths do not support `version` because
   111  they are constrained to share the same version as their caller by being
   112  obtained by the same source repository.
   113  
   114  ## Configuration
   115  
   116  The arguments used in a `module` block, such as the `servers` parameter above,
   117  correspond to [variables](/docs/configuration/variables.html) within the module
   118  itself. You can therefore discover all the available variables for a module by
   119  inspecting the source of it.
   120  
   121  The special arguments `source`, `version` and `providers` are exceptions. These
   122  are used for special purposes by Terraform and should therefore not be used
   123  as variable names within a module.
   124  
   125  ## Outputs
   126  
   127  Modules encapsulate their resources. A resource in one module cannot directly depend on resources or attributes in other modules, unless those are exported through [outputs](/docs/configuration/outputs.html). These outputs can be referenced in other places in your configuration, for example:
   128  
   129  ```hcl
   130  resource "aws_instance" "client" {
   131    ami               = "ami-408c7f28"
   132    instance_type     = "t1.micro"
   133    availability_zone = "${module.consul.server_availability_zone}"
   134  }
   135  ```
   136  
   137  This is deliberately very similar to accessing resource attributes. Instead of
   138  referencing a resource attribute, however, the expression in this case
   139  references an output of the module.
   140  
   141  Just like with resources, interpolation expressions can create implicit
   142  dependencies on resources and other modules. Since modules encapsulate
   143  other resources, however, the dependency is not on the module as a whole
   144  but rather on the `server_availability_zone` output specifically, which
   145  allows Terraform to work on resources in different modules concurrently rather
   146  than waiting for the entire module to be complete before proceeding.
   147  
   148  ## Providers within Modules
   149  
   150  For convenience in simple configurations, child modules by default inherit
   151  provider configurations from their parent. This means that in most cases
   152  only the root module needs explicit `provider` blocks, and then any defined
   153  provider can be freely used with the same settings in child modules.
   154  
   155  In more complex situations it may be necessary for a child module to use
   156  different provider settings than its parent. In this situation it is
   157  possible to define
   158  [multiple provider instances](/docs/configuration/providers.html#multiple-provider-instances)
   159  and pass them explicitly and selectively to a child module:
   160  
   161  ```hcl
   162  # The default "aws" configuration is used for AWS resources in the root
   163  # module where no explicit provider instance is selected.
   164  provider "aws" {
   165    region = "us-west-1"
   166  }
   167  
   168  # A non-default, or "aliased" configuration is also defined for a different
   169  # region.
   170  provider "aws" {
   171    alias  = "usw2"
   172    region = "us-west-2"
   173  }
   174  
   175  # An example child module is instantiated with the _aliased_ configuration,
   176  # so any AWS resources it defines will use the us-west-2 region.
   177  module "example" {
   178    source    = "./example"
   179    providers = {
   180      aws = "aws.usw2"
   181    }
   182  }
   183  ```
   184  
   185  The `providers` argument within a `module` block serves the same purpose as
   186  the `provider` argument within a resource as described for
   187  [multiple provider instances](/docs/configuration/providers.html#multiple-provider-instances),
   188  but is a map rather than a single string because a module may contain resources
   189  from many different providers.
   190  
   191  Once the `providers` argument is used in a `module` block it overrides all of
   192  the default inheritance behavior, so it is necessary to enumerate mappings
   193  for _all_ of the required providers. This is to avoid confusion and surprises
   194  when mixing both implicit and explicit provider passing.
   195  
   196  In more complex situations it may be necessary for a child module _itself_
   197  to have multiple instances of the same provider. For example, a module
   198  that configures connectivity between networks in two AWS regions is likely
   199  to need both a source and a destination region. In that case, the root module
   200  may look something like this:
   201  
   202  ```hcl
   203  provider "aws" {
   204    alias  = "usw1"
   205    region = "us-west-1"
   206  }
   207  
   208  provider "aws" {
   209    alias  = "usw2"
   210    region = "us-west-2"
   211  }
   212  
   213  module "tunnel" {
   214    source    = "./tunnel"
   215    providers = {
   216      "aws.src" = "aws.usw1"
   217      "aws.dst" = "aws.usw2"
   218    }
   219  }
   220  ```
   221  
   222  The subdirectory `./tunnel` should then contain configuration like the
   223  following, to declare the two provider aliases it expects:
   224  
   225  ```
   226  provider "aws" {
   227    alias = "src"
   228  }
   229  
   230  provider "aws" {
   231    alias = "dst"
   232  }
   233  ```
   234  
   235  Each resource should then have its own `provider` attribute set to either
   236  `"aws.src"` or `"aws.dst"` to choose which of the provider instances to use.
   237  
   238  It is recommended to use the default inheritance behavior in most cases where
   239  only a single default instance of each provider is used, and switch to
   240  passing providers explicitly as soon as multiple instances are needed.
   241  
   242  In all cases it is recommended to keep explicit provider declarations only in
   243  the root module and pass them (either implicitly or explicitly) down to
   244  descendent modules. This avoids the provider configurations being "lost"
   245  when descendent providers are removed from the configuration. It also allows
   246  the user of a configuration to determine which providers require credentials
   247  by inspecting only the root module.
   248  
   249  ## Multiple Instances of a Module
   250  
   251  A particular module source can be instantiated multiple times:
   252  
   253  ```hcl
   254  # my_buckets.tf
   255  
   256  module "assets_bucket" {
   257    source = "./publish_bucket"
   258    name   = "assets"
   259  }
   260  
   261  module "media_bucket" {
   262    source = "./publish_bucket"
   263    name   = "media"
   264  }
   265  ```
   266  
   267  ```hcl
   268  # publish_bucket/bucket-and-cloudfront.tf
   269  
   270  variable "name" {} # this is the input parameter of the module
   271  
   272  resource "aws_s3_bucket" "example" {
   273    # ...
   274  }
   275  
   276  resource "aws_iam_user" "deploy_user" {
   277    # ...
   278  }
   279  ```
   280  
   281  This example defines a local child module in the `./publish_bucket`
   282  subdirectory. That module has configuration to create an S3 bucket. The module
   283  wraps the bucket and all the other implementation details required to configure
   284  a bucket.
   285  
   286  We can then instantiate the module multiple times in our configuration by
   287  giving each instance a unique name -- here `module "assets_bucket"` and
   288  `module "media_bucket"` -- whilst specifying the same `source` value.
   289  
   290  Resources from child modules are prefixed with `module.<module-instance-name>`
   291  when displayed in plan output and elsewhere in the UI. For example, the
   292  `./publish_bucket` module contains `aws_s3_bucket.example`, and so the two
   293  instances of this module produce S3 bucket resources with [_resource addresses_](/docs/internals/resource-addressing.html)
   294  `module.assets_bucket.aws_s3_bucket.example` and `module.media_bucket.aws_s3_bucket.example`
   295  respectively. These full addresses are used within the UI and on the command
   296  line, but are not valid within interpolation expressions due to the
   297  encapsulation behavior described above.
   298  
   299  When refactoring an existing configuration to introduce modules, moving
   300  resource blocks between modules causes Terraform to see the new location
   301  as an entirely separate resource to the old. Always check the execution plan
   302  after performing such actions to ensure that no resources are surprisingly
   303  deleted.
   304  
   305  Each instance of a module may optionally have different providers passed to it
   306  using the `providers` argument described above. This can be useful in situations
   307  where, for example, a duplicated set of resources must be created across
   308  several regions or datacenters.
   309  
   310  ## Summarizing Modules in the UI
   311  
   312  By default, commands such as the [plan command](/docs/commands/plan.html) and
   313  [graph command](/docs/commands/graph.html) will show each resource in a nested
   314  module to represent the full scope of the configuration. For more complex
   315  configurations, the `-module-depth` option may be useful to summarize some or all
   316  of the modules as single objects.
   317  
   318  For example, with a configuration similar to what we've built above, the default
   319  graph output looks like the following:
   320  
   321  ![Terraform Expanded Module Graph](docs/module_graph_expand.png)
   322  
   323  If we instead set `-module-depth=0`, the graph will look like this:
   324  
   325  ![Terraform Module Graph](docs/module_graph.png)
   326  
   327  Other commands work similarly with modules. Note that `-module-depth` only
   328  affects how modules are presented in the UI; it does not affect how modules
   329  and their contained resources are processed by Terraform operations.
   330  
   331  ## Tainting resources within a module
   332  
   333  The [taint command](/docs/commands/taint.html) can be used to _taint_ specific
   334  resources within a module:
   335  
   336  ```shell
   337  $ terraform taint -module=salt_master aws_instance.salt_master
   338  ```
   339  
   340  It is not possible to taint an entire module. Instead, each resource within
   341  the module must be tainted separately.