diff --git a/website/docs/configuration-0-11/data-sources.html.md b/website/docs/configuration-0-11/data-sources.html.md new file mode 100644 index 000000000..6897eb34a --- /dev/null +++ b/website/docs/configuration-0-11/data-sources.html.md @@ -0,0 +1,112 @@ +--- +layout: "docs" +page_title: "Configuring Data Sources" +sidebar_current: "docs-config-data-sources" +description: |- + Data sources allow data to be fetched or computed for use elsewhere in Terraform configuration. +--- + +# Data Source Configuration + +*Data sources* allow data to be fetched or computed for use elsewhere +in Terraform configuration. Use of data sources allows a Terraform +configuration to build on information defined outside of Terraform, +or defined by another separate Terraform configuration. + +[Providers](/docs/configuration/providers.html) are responsible in +Terraform for defining and implementing data sources. Whereas +a [resource](/docs/configuration/resources.html) causes Terraform +to create and manage a new infrastructure component, data sources +present read-only views into pre-existing data, or they compute +new values on the fly within Terraform itself. + +For example, a data source may retrieve artifact information from +Terraform Enterprise, configuration information from Consul, or look up a pre-existing +AWS resource by filtering on its attributes and tags. + +Every data source in Terraform is mapped to a provider based +on longest-prefix matching. For example the `aws_ami` +data source would map to the `aws` provider (if that exists). + +This page assumes you're familiar with the +[configuration syntax](/docs/configuration/syntax.html) +already. + +## Example + +A data source configuration looks like the following: + +```hcl +# Find the latest available AMI that is tagged with Component = web +data "aws_ami" "web" { + filter { + name = "state" + values = ["available"] + } + + filter { + name = "tag:Component" + values = ["web"] + } + + most_recent = true +} +``` + +## Description + +The `data` block creates a data instance of the given `TYPE` (first +parameter) and `NAME` (second parameter). The combination of the type +and name must be unique. + +Within the block (the `{ }`) is configuration for the data instance. The +configuration is dependent on the type, and is documented for each +data source in the [providers section](/docs/providers/index.html). + +Each data instance will export one or more attributes, which can be +interpolated into other resources using variables of the form +`data.TYPE.NAME.ATTR`. For example: + +```hcl +resource "aws_instance" "web" { + ami = "${data.aws_ami.web.id}" + instance_type = "t1.micro" +} +``` + +### Meta-parameters + +As data sources are essentially a read only subset of resources they also support the same [meta-parameters](https://www.terraform.io/docs/configuration/resources.html#meta-parameters) of resources except for the [`lifecycle` configuration block](https://www.terraform.io/docs/configuration/resources.html#lifecycle). + +## Multiple Provider Instances + +Similarly to [resources](/docs/configuration/resources.html), the +`provider` meta-parameter can be used where a configuration has +multiple aliased instances of the same provider: + +```hcl +data "aws_ami" "web" { + provider = "aws.west" + + # ... +} +``` + +See the ["Multiple Provider Instances"](/docs/configuration/resources.html#multiple-provider-instances) documentation for resources +for more information. + +## Data Source Lifecycle + +If the arguments of a data instance contain no references to computed values, +such as attributes of resources that have not yet been created, then the +data instance will be read and its state updated during Terraform's "refresh" +phase, which by default runs prior to creating a plan. This ensures that the +retrieved data is available for use during planning and the diff will show +the real values obtained. + +Data instance arguments may refer to computed values, in which case the +attributes of the instance itself cannot be resolved until all of its +arguments are defined. In this case, refreshing the data instance will be +deferred until the "apply" phase, and all interpolations of the data instance +attributes will show as "computed" in the plan since the values are not yet +known. diff --git a/website/docs/configuration-0-11/environment-variables.html.md b/website/docs/configuration-0-11/environment-variables.html.md new file mode 100644 index 000000000..5df5deb0e --- /dev/null +++ b/website/docs/configuration-0-11/environment-variables.html.md @@ -0,0 +1,118 @@ +--- +layout: "docs" +page_title: "Environment Variables" +sidebar_current: "docs-config-environment-variables" +description: |- + Terraform uses different environment variables that can be used to configure various aspects of how Terraform behaves. this section documents those variables, their potential values, and how to use them. +--- + +# Environment Variables + +## TF_LOG + +If set to any value, enables detailed logs to appear on stderr which is useful for debugging. For example: + +```shell +export TF_LOG=TRACE +``` + +To disable, either unset it or set it to empty. When unset, logging will default to stderr. For example: + +```shell +export TF_LOG= +``` + +For more on debugging Terraform, check out the section on [Debugging](/docs/internals/debugging.html). + +## TF_LOG_PATH + +This specifies where the log should persist its output to. Note that even when `TF_LOG_PATH` is set, `TF_LOG` must be set in order for any logging to be enabled. For example, to always write the log to the directory you're currently running terraform from: + +```shell +export TF_LOG_PATH=./terraform.log +``` + +For more on debugging Terraform, check out the section on [Debugging](/docs/internals/debugging.html). + +## TF_INPUT + +If set to "false" or "0", causes terraform commands to behave as if the `-input=false` flag was specified. This is used when you want to disable prompts for variables that haven't had their values specified. For example: + +```shell +export TF_INPUT=0 +``` + +## TF_MODULE_DEPTH + +When given a value, causes terraform commands to behave as if the `-module-depth=VALUE` flag was specified. By setting this to 0, for example, you enable commands such as [plan](/docs/commands/plan.html) and [graph](/docs/commands/graph.html) to display more compressed information. + +```shell +export TF_MODULE_DEPTH=0 +``` + +For more information regarding modules, check out the section on [Using Modules](/docs/modules/usage.html). + +## TF_VAR_name + +Environment variables can be used to set variables. The environment variables must be in the format `TF_VAR_name` and this will be checked last for a value. For example: + +```shell +export TF_VAR_region=us-west-1 +export TF_VAR_ami=ami-049d8641 +export TF_VAR_alist='[1,2,3]' +export TF_VAR_amap='{ foo = "bar", baz = "qux" }' +``` + +For more on how to use `TF_VAR_name` in context, check out the section on [Variable Configuration](/docs/configuration/variables.html). + +## TF_CLI_ARGS and TF_CLI_ARGS_name + +The value of `TF_CLI_ARGS` will specify additional arguments to the +command-line. This allows easier automation in CI environments as well as +modifying default behavior of Terraform on your own system. + +These arguments are inserted directly _after_ the subcommand +(such as `plan`) and _before_ any flags specified directly on the command-line. +This behavior ensures that flags on the command-line take precedence over +environment variables. + +For example, the following command: `TF_CLI_ARGS="-input=false" terraform apply -force` +is the equivalent to manually typing: `terraform apply -input=false -force`. + +The flag `TF_CLI_ARGS` affects all Terraform commands. If you specify a +named command in the form of `TF_CLI_ARGS_name` then it will only affect +that command. As an example, to specify that only plans never refresh, +you can set `TF_CLI_ARGS_plan="-refresh=false"`. + +The value of the flag is parsed as if you typed it directly to the shell. +Double and single quotes are allowed to capture strings and arguments will +be separated by spaces otherwise. + +## TF_DATA_DIR + +`TF_DATA_DIR` changes the location where Terraform keeps its +per-working-directory data, such as the current remote backend configuration. + +By default this data is written into a `.terraform` subdirectory of the +current directory, but the path given in `TF_DATA_DIR` will be used instead +if non-empty. + +In most cases it should not be necessary to set this variable, but it may +be useful to do so if e.g. the working directory is not writable. + +The data directory is used to retain data that must persist from one command +to the next, so it's important to have this variable set consistently throughout +all of the Terraform workflow commands (starting with `terraform init`) or else +Terraform may be unable to find providers, modules, and other artifacts. + +## TF_SKIP_REMOTE_TESTS + +This can be set prior to running the unit tests to opt-out of any tests +requiring remote network connectivity. The unit tests make an attempt to +automatically detect when connectivity is unavailable and skip the relevant +tests, but by setting this variable you can force these tests to be skipped. + +```shell +export TF_SKIP_REMOTE_TESTS=1 +make test +``` diff --git a/website/docs/configuration-0-11/index.html.md b/website/docs/configuration-0-11/index.html.md new file mode 100644 index 000000000..2b3e7f396 --- /dev/null +++ b/website/docs/configuration-0-11/index.html.md @@ -0,0 +1,25 @@ +--- +layout: "docs" +page_title: "Configuration" +sidebar_current: "docs-config" +description: |- + Terraform uses text files to describe infrastructure and to set variables. These text files are called Terraform _configurations_ and end in `.tf`. This section talks about the format of these files as well as how they're loaded. +--- + +# Configuration + +Terraform uses text files to describe infrastructure and to set variables. +These text files are called Terraform _configurations_ and end in +`.tf`. This section talks about the format of these files as well as +how they're loaded. + +The format of the configuration files are able to be in two formats: +Terraform format and JSON. The Terraform format is more human-readable, +supports comments, and is the generally recommended format for most +Terraform files. The JSON format is meant for machines to create, +modify, and update, but can also be done by Terraform operators if +you prefer. Terraform format ends in `.tf` and JSON format ends in +`.tf.json`. + +Click a sub-section in the navigation to the left to learn more about +Terraform configuration. diff --git a/website/docs/configuration-0-11/interpolation.html.md b/website/docs/configuration-0-11/interpolation.html.md new file mode 100644 index 000000000..b4b4b1607 --- /dev/null +++ b/website/docs/configuration-0-11/interpolation.html.md @@ -0,0 +1,547 @@ +--- +layout: "docs" +page_title: "Interpolation Syntax" +sidebar_current: "docs-config-interpolation" +description: |- + Embedded within strings in Terraform, whether you're using the Terraform syntax or JSON syntax, you can interpolate other values into strings. These interpolations are wrapped in `${}`, such as `${var.foo}`. +--- + +# Interpolation Syntax + +Embedded within strings in Terraform, whether you're using the +Terraform syntax or JSON syntax, you can interpolate other values. These +interpolations are wrapped in `${}`, such as `${var.foo}`. + +The interpolation syntax is powerful and allows you to reference +variables, attributes of resources, call functions, etc. + +You can perform [simple math](#math) in interpolations, allowing +you to write expressions such as `${count.index + 1}`. And you can +also use [conditionals](#conditionals) to determine a value based +on some logic. + +You can escape interpolation with double dollar signs: `$${foo}` +will be rendered as a literal `${foo}`. + +## Available Variables + +There are a variety of available variable references you can use. + +#### User string variables + +Use the `var.` prefix followed by the variable name. For example, +`${var.foo}` will interpolate the `foo` variable value. + +#### User map variables + +The syntax is `var.MAP["KEY"]`. For example, `${var.amis["us-east-1"]}` +would get the value of the `us-east-1` key within the `amis` map +variable. + +#### User list variables + +The syntax is `"${var.LIST}"`. For example, `"${var.subnets}"` +would get the value of the `subnets` list, as a list. You can also +return list elements by index: `${var.subnets[idx]}`. + +#### Attributes of your own resource + +The syntax is `self.ATTRIBUTE`. For example `${self.private_ip}` +will interpolate that resource's private IP address. + +-> **Note**: The `self.ATTRIBUTE` syntax is only allowed and valid within +provisioners. + +#### Attributes of other resources + +The syntax is `TYPE.NAME.ATTRIBUTE`. For example, +`${aws_instance.web.id}` will interpolate the ID attribute from the +`aws_instance` resource named `web`. If the resource has a `count` +attribute set, you can access individual attributes with a zero-based +index, such as `${aws_instance.web.0.id}`. You can also use the splat +syntax to get a list of all the attributes: `${aws_instance.web.*.id}`. + +#### Attributes of a data source + +The syntax is `data.TYPE.NAME.ATTRIBUTE`. For example. `${data.aws_ami.ubuntu.id}` will interpolate the `id` attribute from the `aws_ami` [data source](/docs/configuration/data-sources.html) named `ubuntu`. If the data source has a `count` +attribute set, you can access individual attributes with a zero-based +index, such as `${data.aws_subnet.example.0.cidr_block}`. You can also use the splat +syntax to get a list of all the attributes: `${data.aws_subnet.example.*.cidr_block}`. + +#### Outputs from a module + +The syntax is `MODULE.NAME.OUTPUT`. For example `${module.foo.bar}` will +interpolate the `bar` output from the `foo` +[module](/docs/modules/index.html). + +#### Count information + +The syntax is `count.FIELD`. For example, `${count.index}` will +interpolate the current index in a multi-count resource. For more +information on `count`, see the [resource configuration +page](/docs/configuration/resources.html). + +#### Path information + +The syntax is `path.TYPE`. TYPE can be `cwd`, `module`, or `root`. +`cwd` will interpolate the current working directory. `module` will +interpolate the path to the current module. `root` will interpolate the +path of the root module. In general, you probably want the +`path.module` variable. + +#### Terraform meta information + +The syntax is `terraform.FIELD`. This variable type contains metadata about +the currently executing Terraform run. FIELD can currently only be `env` to +reference the currently active [state environment](/docs/state/environments.html). + +## Conditionals + +Interpolations may contain conditionals to branch on the final value. + +```hcl +resource "aws_instance" "web" { + subnet = "${var.env == "production" ? var.prod_subnet : var.dev_subnet}" +} +``` + +The conditional syntax is the well-known ternary operation: + +```text +CONDITION ? TRUEVAL : FALSEVAL +``` + +The condition can be any valid interpolation syntax, such as variable +access, a function call, or even another conditional. The true and false +value can also be any valid interpolation syntax. The returned types by +the true and false side must be the same. + +The supported operators are: + + * Equality: `==` and `!=` + * Numerical comparison: `>`, `<`, `>=`, `<=` + * Boolean logic: `&&`, `||`, unary `!` + +A common use case for conditionals is to enable/disable a resource by +conditionally setting the count: + +```hcl +resource "aws_instance" "vpn" { + count = "${var.something ? 1 : 0}" +} +``` + +In the example above, the "vpn" resource will only be included if +"var.something" evaluates to true. Otherwise, the VPN resource will +not be created at all. + +## Built-in Functions + +Terraform ships with built-in functions. Functions are called with the +syntax `name(arg, arg2, ...)`. For example, to read a file: +`${file("path.txt")}`. + +~> **NOTE**: Proper escaping is required for JSON field values containing quotes +(`"`) such as `environment` values. If directly setting the JSON, they should be +escaped as `\"` in the JSON, e.g. `"value": "I \"love\" escaped quotes"`. If +using a Terraform variable value, they should be escaped as `\\\"` in the +variable, e.g. `value = "I \\\"love\\\" escaped quotes"` in the variable and +`"value": "${var.myvariable}"` in the JSON. + +### Supported built-in functions + +The supported built-in functions are: + + * `abs(float)` - Returns the absolute value of a given float. + Example: `abs(1)` returns `1`, and `abs(-1)` would also return `1`, + whereas `abs(-3.14)` would return `3.14`. See also the `signum` function. + + * `basename(path)` - Returns the last element of a path. + + * `base64decode(string)` - Given a base64-encoded string, decodes it and + returns the original string. + + * `base64encode(string)` - Returns a base64-encoded representation of the + given string. + + * `base64gzip(string)` - Compresses the given string with gzip and then + encodes the result to base64. This can be used with certain resource + arguments that allow binary data to be passed with base64 encoding, since + Terraform strings are required to be valid UTF-8. + + * `base64sha256(string)` - Returns a base64-encoded representation of raw + SHA-256 sum of the given string. + **This is not equivalent** of `base64encode(sha256(string))` + since `sha256()` returns hexadecimal representation. + + * `base64sha512(string)` - Returns a base64-encoded representation of raw + SHA-512 sum of the given string. + **This is not equivalent** of `base64encode(sha512(string))` + since `sha512()` returns hexadecimal representation. + + * `bcrypt(password, cost)` - Returns the Blowfish encrypted hash of the string + at the given cost. A default `cost` of 10 will be used if not provided. + + * `ceil(float)` - Returns the least integer value greater than or equal + to the argument. + + * `chomp(string)` - Removes trailing newlines from the given string. + + * `chunklist(list, size)` - Returns the `list` items chunked by `size`. + Examples: + * `chunklist(aws_subnet.foo.*.id, 1)`: will outputs `[["id1"], ["id2"], ["id3"]]` + * `chunklist(var.list_of_strings, 2)`: will outputs `[["id1", "id2"], ["id3", "id4"], ["id5"]]` + + * `cidrhost(iprange, hostnum)` - Takes an IP address range in CIDR notation + and creates an IP address with the given host number. If given host + number is negative, the count starts from the end of the range. + For example, `cidrhost("10.0.0.0/8", 2)` returns `10.0.0.2` and + `cidrhost("10.0.0.0/8", -2)` returns `10.255.255.254`. + + * `cidrnetmask(iprange)` - Takes an IP address range in CIDR notation + and returns the address-formatted subnet mask format that some + systems expect for IPv4 interfaces. For example, + `cidrnetmask("10.0.0.0/8")` returns `255.0.0.0`. Not applicable + to IPv6 networks since CIDR notation is the only valid notation for + IPv6. + + * `cidrsubnet(iprange, newbits, netnum)` - Takes an IP address range in + CIDR notation (like `10.0.0.0/8`) and extends its prefix to include an + additional subnet number. For example, + `cidrsubnet("10.0.0.0/8", 8, 2)` returns `10.2.0.0/16`; + `cidrsubnet("2607:f298:6051:516c::/64", 8, 2)` returns + `2607:f298:6051:516c:200::/72`. + + * `coalesce(string1, string2, ...)` - Returns the first non-empty value from + the given arguments. At least two arguments must be provided. + + * `coalescelist(list1, list2, ...)` - Returns the first non-empty list from + the given arguments. At least two arguments must be provided. + + * `compact(list)` - Removes empty string elements from a list. This can be + useful in some cases, for example when passing joined lists as module + variables or when parsing module outputs. + Example: `compact(module.my_asg.load_balancer_names)` + + * `concat(list1, list2, ...)` - Combines two or more lists into a single list. + Example: `concat(aws_instance.db.*.tags.Name, aws_instance.web.*.tags.Name)` + + * `contains(list, element)` - Returns *true* if a list contains the given element + and returns *false* otherwise. Examples: `contains(var.list_of_strings, "an_element")` + + * `dirname(path)` - Returns all but the last element of path, typically the path's directory. + + * `distinct(list)` - Removes duplicate items from a list. Keeps the first + occurrence of each element, and removes subsequent occurrences. This + function is only valid for flat lists. Example: `distinct(var.usernames)` + + * `element(list, index)` - Returns a single element from a list + at the given index. If the index is greater than the number of + elements, this function will wrap using a standard mod algorithm. + This function only works on flat lists. Examples: + * `element(aws_subnet.foo.*.id, count.index)` + * `element(var.list_of_strings, 2)` + + * `file(path)` - Reads the contents of a file into the string. Variables + in this file are _not_ interpolated. The contents of the file are + read as-is. The `path` is interpreted relative to the working directory. + [Path variables](#path-information) can be used to reference paths relative + to other base locations. For example, when using `file()` from inside a + module, you generally want to make the path relative to the module base, + like this: `file("${path.module}/file")`. + + * `floor(float)` - Returns the greatest integer value less than or equal to + the argument. + + * `flatten(list of lists)` - Flattens lists of lists down to a flat list of + primitive values, eliminating any nested lists recursively. Examples: + * `flatten(data.github_user.user.*.gpg_keys)` + + * `format(format, args, ...)` - Formats a string according to the given + format. The syntax for the format is standard `sprintf` syntax. + Good documentation for the syntax can be [found here](https://golang.org/pkg/fmt/). + Example to zero-prefix a count, used commonly for naming servers: + `format("web-%03d", count.index + 1)`. + + * `formatlist(format, args, ...)` - Formats each element of a list + according to the given format, similarly to `format`, and returns a list. + Non-list arguments are repeated for each list element. + For example, to convert a list of DNS addresses to a list of URLs, you might use: + `formatlist("https://%s:%s/", aws_instance.foo.*.public_dns, var.port)`. + If multiple args are lists, and they have the same number of elements, then the formatting is applied to the elements of the lists in parallel. + Example: + `formatlist("instance %v has private ip %v", aws_instance.foo.*.id, aws_instance.foo.*.private_ip)`. + Passing lists with different lengths to formatlist results in an error. + + * `indent(numspaces, string)` - Prepends the specified number of spaces to all but the first + line of the given multi-line string. May be useful when inserting a multi-line string + into an already-indented context. The first line is not indented, to allow for the + indented string to be placed after some sort of already-indented preamble. + Example: `" \"items\": ${ indent(4, "[\n \"item1\"\n]") },"` + + * `index(list, elem)` - Finds the index of a given element in a list. + This function only works on flat lists. + Example: `index(aws_instance.foo.*.tags.Name, "foo-test")` + + * `join(delim, list)` - Joins the list with the delimiter for a resultant string. + This function works only on flat lists. + Examples: + * `join(",", aws_instance.foo.*.id)` + * `join(",", var.ami_list)` + + * `jsonencode(value)` - Returns a JSON-encoded representation of the given + value, which can contain arbitrarily-nested lists and maps. Note that if + the value is a string then its value will be placed in quotes. + + * `keys(map)` - Returns a lexically sorted list of the map keys. + + * `length(list)` - Returns the number of members in a given list or map, or the number of characters in a given string. + * `${length(split(",", "a,b,c"))}` = 3 + * `${length("a,b,c")}` = 5 + * `${length(map("key", "val"))}` = 1 + + * `list(items, ...)` - Returns a list consisting of the arguments to the function. + This function provides a way of representing list literals in interpolation. + * `${list("a", "b", "c")}` returns a list of `"a", "b", "c"`. + * `${list()}` returns an empty list. + + * `log(x, base)` - Returns the logarithm of `x`. + + * `lookup(map, key, [default])` - Performs a dynamic lookup into a map + variable. The `map` parameter should be another variable, such + as `var.amis`. If `key` does not exist in `map`, the interpolation will + fail unless you specify a third argument, `default`, which should be a + string value to return if no `key` is found in `map`. This function + only works on flat maps and will return an error for maps that + include nested lists or maps. + + * `lower(string)` - Returns a copy of the string with all Unicode letters mapped to their lower case. + + * `map(key, value, ...)` - Returns a map consisting of the key/value pairs + specified as arguments. Every odd argument must be a string key, and every + even argument must have the same type as the other values specified. + Duplicate keys are not allowed. Examples: + * `map("hello", "world")` + * `map("us-east", list("a", "b", "c"), "us-west", list("b", "c", "d"))` + + * `matchkeys(values, keys, searchset)` - For two lists `values` and `keys` of + equal length, returns all elements from `values` where the corresponding + element from `keys` exists in the `searchset` list. E.g. + `matchkeys(aws_instance.example.*.id, + aws_instance.example.*.availability_zone, list("us-west-2a"))` will return a + list of the instance IDs of the `aws_instance.example` instances in + `"us-west-2a"`. No match will result in empty list. Items of `keys` are + processed sequentially, so the order of returned `values` is preserved. + + * `max(float1, float2, ...)` - Returns the largest of the floats. + + * `merge(map1, map2, ...)` - Returns the union of 2 or more maps. The maps + are consumed in the order provided, and duplicate keys overwrite previous + entries. + * `${merge(map("a", "b"), map("c", "d"))}` returns `{"a": "b", "c": "d"}` + + * `min(float1, float2, ...)` - Returns the smallest of the floats. + + * `md5(string)` - Returns a (conventional) hexadecimal representation of the + MD5 hash of the given string. + + * `pathexpand(string)` - Returns a filepath string with `~` expanded to the home directory. Note: + This will create a plan diff between two different hosts, unless the filepaths are the same. + + * `pow(x, y)` - Returns the base `x` of exponential `y` as a float. + + Example: + * `${pow(3,2)}` = 9 + * `${pow(4,0)}` = 1 + + * `replace(string, search, replace)` - Does a search and replace on the + given string. All instances of `search` are replaced with the value + of `replace`. If `search` is wrapped in forward slashes, it is treated + as a regular expression. If using a regular expression, `replace` + can reference subcaptures in the regular expression by using `$n` where + `n` is the index or name of the subcapture. If using a regular expression, + the syntax conforms to the [re2 regular expression syntax](https://github.com/google/re2/wiki/Syntax). + + * `rsadecrypt(string, key)` - Decrypts `string` using RSA. The padding scheme + PKCS #1 v1.5 is used. The `string` must be base64-encoded. `key` must be an + RSA private key in PEM format. You may use `file()` to load it from a file. + + * `sha1(string)` - Returns a (conventional) hexadecimal representation of the + SHA-1 hash of the given string. + Example: `"${sha1("${aws_vpc.default.tags.customer}-s3-bucket")}"` + + * `sha256(string)` - Returns a (conventional) hexadecimal representation of the + SHA-256 hash of the given string. + Example: `"${sha256("${aws_vpc.default.tags.customer}-s3-bucket")}"` + + * `sha512(string)` - Returns a (conventional) hexadecimal representation of the + SHA-512 hash of the given string. + Example: `"${sha512("${aws_vpc.default.tags.customer}-s3-bucket")}"` + + * `signum(integer)` - Returns `-1` for negative numbers, `0` for `0` and `1` for positive numbers. + This function is useful when you need to set a value for the first resource and + a different value for the rest of the resources. + Example: `element(split(",", var.r53_failover_policy), signum(count.index))` + where the 0th index points to `PRIMARY` and 1st to `FAILOVER` + + * `slice(list, from, to)` - Returns the portion of `list` between `from` (inclusive) and `to` (exclusive). + Example: `slice(var.list_of_strings, 0, length(var.list_of_strings) - 1)` + + * `sort(list)` - Returns a lexographically sorted list of the strings contained in + the list passed as an argument. Sort may only be used with lists which contain only + strings. + Examples: `sort(aws_instance.foo.*.id)`, `sort(var.list_of_strings)` + + * `split(delim, string)` - Splits the string previously created by `join` + back into a list. This is useful for pushing lists through module + outputs since they currently only support string values. Depending on the + use, the string this is being performed within may need to be wrapped + in brackets to indicate that the output is actually a list, e.g. + `a_resource_param = ["${split(",", var.CSV_STRING)}"]`. + Example: `split(",", module.amod.server_ids)` + + * `substr(string, offset, length)` - Extracts a substring from the input string. A negative offset is interpreted as being equivalent to a positive offset measured backwards from the end of the string. A length of `-1` is interpreted as meaning "until the end of the string". + + * `timestamp()` - Returns a UTC timestamp string in RFC 3339 format. This string will change with every + invocation of the function, so in order to prevent diffs on every plan & apply, it must be used with the + [`ignore_changes`](/docs/configuration/resources.html#ignore-changes) lifecycle attribute. + + * `timeadd(time, duration)` - Returns a UTC timestamp string corresponding to adding a given `duration` to `time` in RFC 3339 format. + For example, `timeadd("2017-11-22T00:00:00Z", "10m")` produces a value `"2017-11-22T00:10:00Z"`. + + * `title(string)` - Returns a copy of the string with the first characters of all the words capitalized. + + * `transpose(map)` - Swaps the keys and list values in a map of lists of strings. For example, transpose(map("a", list("1", "2"), "b", list("2", "3")) produces a value equivalent to map("1", list("a"), "2", list("a", "b"), "3", list("b")). + + * `trimspace(string)` - Returns a copy of the string with all leading and trailing white spaces removed. + + * `upper(string)` - Returns a copy of the string with all Unicode letters mapped to their upper case. + + * `urlencode(string)` - Returns an URL-safe copy of the string. + + * `uuid()` - Returns a random UUID string. This string will change with every invocation of the function, so in order to prevent diffs on every plan & apply, it must be used with the [`ignore_changes`](/docs/configuration/resources.html#ignore-changes) lifecycle attribute. + + * `values(map)` - Returns a list of the map values, in the order of the keys + returned by the `keys` function. This function only works on flat maps and + will return an error for maps that include nested lists or maps. + + * `zipmap(list, list)` - Creates a map from a list of keys and a list of + values. The keys must all be of type string, and the length of the lists + must be the same. + For example, to output a mapping of AWS IAM user names to the fingerprint + of the key used to encrypt their initial password, you might use: + `zipmap(aws_iam_user.users.*.name, aws_iam_user_login_profile.users.*.key_fingerprint)`. + +## Templates + +Long strings can be managed using templates. +[Templates](/docs/providers/template/index.html) are +[data-sources](/docs/configuration/data-sources.html) defined by a +filename and some variables to use during interpolation. They have a +computed `rendered` attribute containing the result. + +A template data source looks like: + +```hcl +data "template_file" "example" { + template = "$${hello} $${world}!" + vars { + hello = "goodnight" + world = "moon" + } +} + +output "rendered" { + value = "${data.template_file.example.rendered}" +} +``` + +Then the rendered value would be `goodnight moon!`. + +You may use any of the built-in functions in your template. For more +details on template usage, please see the +[template_file documentation](/docs/providers/template/d/file.html). + +### Using Templates with Count + +Here is an example that combines the capabilities of templates with the interpolation +from `count` to give us a parameterized template, unique to each resource instance: + +```hcl +variable "count" { + default = 2 +} + +variable "hostnames" { + default = { + "0" = "example1.org" + "1" = "example2.net" + } +} + +data "template_file" "web_init" { + # Render the template once for each instance + count = "${length(var.hostnames)}" + template = "${file("templates/web_init.tpl")}" + vars { + # count.index tells us the index of the instance we are rendering + hostname = "${var.hostnames[count.index]}" + } +} + +resource "aws_instance" "web" { + # Create one instance for each hostname + count = "${length(var.hostnames)}" + + # Pass each instance its corresponding template_file + user_data = "${data.template_file.web_init.*.rendered[count.index]}" +} +``` + +With this, we will build a list of `template_file.web_init` data resources +which we can use in combination with our list of `aws_instance.web` resources. + +## Math + +Simple math can be performed in interpolations: + +```hcl +variable "count" { + default = 2 +} + +resource "aws_instance" "web" { + # ... + + count = "${var.count}" + + # Tag the instance with a counter starting at 1, ie. web-001 + tags { + Name = "${format("web-%03d", count.index + 1)}" + } +} +``` + +The supported operations are: + +- *Add* (`+`), *Subtract* (`-`), *Multiply* (`*`), and *Divide* (`/`) for **float** types +- *Add* (`+`), *Subtract* (`-`), *Multiply* (`*`), *Divide* (`/`), and *Modulo* (`%`) for **integer** types + +Operator precedences is the standard mathematical order of operations: +*Multiply* (`*`), *Divide* (`/`), and *Modulo* (`%`) have precedence over +*Add* (`+`) and *Subtract* (`-`). Parenthesis can be used to force ordering. + +```text +"${2 * 4 + 3 * 3}" # computes to 17 +"${3 * 3 + 2 * 4}" # computes to 17 +"${2 * (4 + 3) * 3}" # computes to 42 +``` + +You can use the [terraform console](/docs/commands/console.html) command to +try the math operations. + +-> **Note:** Since Terraform allows hyphens in resource and variable names, +it's best to use spaces between math operators to prevent confusion or unexpected +behavior. For example, `${var.instance-count - 1}` will subtract **1** from the +`instance-count` variable value, while `${var.instance-count-1}` will interpolate +the `instance-count-1` variable value. diff --git a/website/docs/configuration-0-11/load.html.md b/website/docs/configuration-0-11/load.html.md new file mode 100644 index 000000000..101ac3fec --- /dev/null +++ b/website/docs/configuration-0-11/load.html.md @@ -0,0 +1,36 @@ +--- +layout: "docs" +page_title: "Load Order and Semantics" +sidebar_current: "docs-config-load" +description: |- + When invoking any command that loads the Terraform configuration, Terraform loads all configuration files within the directory specified in alphabetical order. +--- + +# Load Order and Semantics + +When invoking any command that loads the Terraform configuration, +Terraform loads all configuration files within the directory +specified in alphabetical order. + +The files loaded must end in +either `.tf` or `.tf.json` to specify the format that is in use. +Otherwise, the files are ignored. Multiple file formats can +be present in the same directory; it is okay to have one Terraform +configuration file be Terraform syntax and another be JSON. + +[Override](/docs/configuration/override.html) +files are the exception, as they're loaded after all non-override +files, in alphabetical order. + +The configuration within the loaded files are appended to each +other. This is in contrast to being merged. This means that two +resources with the same name are not merged, and will instead +cause a validation error. This is in contrast to +[overrides](/docs/configuration/override.html), +which do merge. + +The order of variables, resources, etc. defined within the +configuration doesn't matter. Terraform configurations are +[declarative](https://en.wikipedia.org/wiki/Declarative_programming), +so references to other resources and variables do not depend +on the order they're defined. diff --git a/website/docs/configuration-0-11/locals.html.md b/website/docs/configuration-0-11/locals.html.md new file mode 100644 index 000000000..d897ccf80 --- /dev/null +++ b/website/docs/configuration-0-11/locals.html.md @@ -0,0 +1,92 @@ +--- +layout: "docs" +page_title: "Configuring Local Values" +sidebar_current: "docs-config-locals" +description: |- + Local values assign a name to an expression that can then be used multiple times + within a module. +--- + +# Local Value Configuration + +Local values assign a name to an expression, that can then be used multiple +times within a module. + +Comparing modules to functions in a traditional programming language, +if [variables](./variables.html) are analogous to function arguments and +[outputs](./outputs.html) are analogous to function return values then +_local values_ are comparable to a function's local variables. + +This page assumes you're already familiar with +[the configuration syntax](/docs/configuration/syntax.html). + +## Examples + +Local values are defined in `locals` blocks: + +```hcl +# Ids for multiple sets of EC2 instances, merged together +locals { + instance_ids = "${concat(aws_instance.blue.*.id, aws_instance.green.*.id)}" +} + +# A computed default name prefix +locals { + default_name_prefix = "${var.project_name}-web" + name_prefix = "${var.name_prefix != "" ? var.name_prefix : local.default_name_prefix}" +} + +# Local values can be interpolated elsewhere using the "local." prefix. +resource "aws_s3_bucket" "files" { + bucket = "${local.name_prefix}-files" + # ... +} +``` + +Named local maps can be merged with local maps to implement common or default +values: + +```hcl +# Define the common tags for all resources +locals { + common_tags = { + Component = "awesome-app" + Environment = "production" + } +} + +# Create a resource that blends the common tags with instance-specific tags. +resource "aws_instance" "server" { + ami = "ami-123456" + instance_type = "t2.micro" + + tags = "${merge( + local.common_tags, + map( + "Name", "awesome-app-server", + "Role", "server" + ) + )}" +} +``` + +## Description + +The `locals` block defines one or more local variables within a module. +Each `locals` block can have as many locals as needed, and there can be any +number of `locals` blocks within a module. + +The names given for the items in the `locals` block must be unique throughout +a module. The given value can be any expression that is valid within +the current module. + +The expression of a local value can refer to other locals, but as usual +reference cycles are not allowed. That is, a local cannot refer to itself +or to a variable that refers (directly or indirectly) back to it. + +It's recommended to group together logically-related local values into +a single block, particularly if they depend on each other. This will help +the reader understand the relationships between variables. Conversely, +prefer to define _unrelated_ local values in _separate_ blocks, and consider +annotating each block with a comment describing any context common to all +of the enclosed locals. diff --git a/website/docs/configuration-0-11/modules.html.md b/website/docs/configuration-0-11/modules.html.md new file mode 100644 index 000000000..15c1b37e1 --- /dev/null +++ b/website/docs/configuration-0-11/modules.html.md @@ -0,0 +1,57 @@ +--- +layout: "docs" +page_title: "Configuring Modules" +sidebar_current: "docs-config-modules" +description: |- + Modules are used in Terraform to modularize and encapsulate groups of resources in your infrastructure. For more information on modules, see the dedicated modules section. +--- + +# Module Configuration + +Modules are used in Terraform to modularize and encapsulate groups of +resources in your infrastructure. For more information on modules, see +the dedicated +[modules section](/docs/modules/index.html). + +This page assumes you're familiar with the +[configuration syntax](/docs/configuration/syntax.html) +already. + +## Example + +```hcl +module "consul" { + source = "hashicorp/consul/aws" + servers = 5 +} +``` + +## Description + +A `module` block instructs Terraform to create an instance of a module, +and in turn to instantiate any resources defined within it. + +The name given in the block header is used to reference the particular module +instance from expressions within the calling module, and to refer to the +module on the command line. It has no meaning outside of a particular +Terraform configuration. + +Within the block body is the configuration for the module. All attributes +within the block must correspond to [variables](/docs/configuration/variables.html) +within the module, with the exception of the following which Terraform +treats as special: + +* `source` - (Required) A [module source](/docs/modules/sources.html) string + specifying the location of the child module source code. + +* `version` - (Optional) A [version constraint](/docs/modules/usage.html#module-versions) + string that specifies which versions of the referenced module are acceptable. + The newest version matching the constraint will be used. `version` is supported + only for modules retrieved from module registries. + +* `providers` - (Optional) A map whose keys are provider configuration names + that are expected by child module and whose values are corresponding + provider names in the calling module. This allows + [provider configurations to be passed explicitly to child modules](/docs/modules/usage.html#providers-within-modules). + If not specified, the child module inherits all of the default (un-aliased) + provider configurations from the calling module. diff --git a/website/docs/configuration-0-11/outputs.html.md b/website/docs/configuration-0-11/outputs.html.md new file mode 100644 index 000000000..dadc1f253 --- /dev/null +++ b/website/docs/configuration-0-11/outputs.html.md @@ -0,0 +1,106 @@ +--- +layout: "docs" +page_title: "Configuring Outputs" +sidebar_current: "docs-config-outputs" +description: |- + Outputs define values that will be highlighted to the user when Terraform applies, and can be queried easily using the output command. Output usage is covered in more detail in the getting started guide. This page covers configuration syntax for outputs. +--- + +# Output Configuration + +Outputs define values that will be highlighted to the user +when Terraform applies, and can be queried easily using the +[output command](/docs/commands/output.html). Output usage +is covered in more detail in the +[getting started guide](/intro/getting-started/outputs.html). +This page covers configuration syntax for outputs. + +Terraform knows a lot about the infrastructure it manages. +Most resources have attributes associated with them, and +outputs are a way to easily extract and query that information. + +This page assumes you are familiar with the +[configuration syntax](/docs/configuration/syntax.html) +already. + +## Example + +A simple output configuration looks like the following: + +```hcl +output "address" { + value = "${aws_instance.db.public_dns}" +} +``` + +This will output a string value corresponding to the public +DNS address of the Terraform-defined AWS instance named "db". It +is possible to export complex data types like maps and lists as +well: + +```hcl +output "addresses" { + value = ["${aws_instance.web.*.public_dns}"] +} +``` + +## Description + +The `output` block configures a single output variable. Multiple +output variables can be configured with multiple output blocks. +The `NAME` given to the output block is the name used to reference +the output variable. It must conform to Terraform variable naming +conventions if it is to be used as an input to other modules. + +Within the block (the `{ }`) is configuration for the output. +These are the parameters that can be set: + +- `value` (required) - The value of the output. This can be a string, list, or + map. This usually includes an interpolation since outputs that are static + aren't usually useful. + +- `description` (optional) - A human-friendly description for the output. This + is primarily for documentation for users using your Terraform configuration. A + future version of Terraform will expose these descriptions as part of some + Terraform CLI command. + +- `depends_on` (list of strings) - Explicit dependencies that this output has. + These dependencies will be created before this output value is processed. The + dependencies are in the format of `TYPE.NAME`, for example `aws_instance.web`. + +- `sensitive` (optional, boolean) - See below. + +## Syntax + +The full syntax is: + +```text +output NAME { + value = VALUE +} +``` + +## Sensitive Outputs + +Outputs can be marked as containing sensitive material by setting the +`sensitive` attribute to `true`, like this: + +```hcl +output "sensitive" { + sensitive = true + value = VALUE +} +``` + +When outputs are displayed on-screen following a `terraform apply` or +`terraform refresh`, sensitive outputs are redacted, with `` +displayed in place of their value. + +### Limitations of Sensitive Outputs + +- The values of sensitive outputs are still stored in the Terraform state, and + available using the `terraform output` command, so cannot be relied on as a + sole means of protecting values. + +- Sensitivity is not tracked internally, so if the output is interpolated in + another module into a resource, the value will be displayed. diff --git a/website/docs/configuration-0-11/override.html.md b/website/docs/configuration-0-11/override.html.md new file mode 100644 index 000000000..0d497f6e1 --- /dev/null +++ b/website/docs/configuration-0-11/override.html.md @@ -0,0 +1,54 @@ +--- +layout: "docs" +page_title: "Overrides" +sidebar_current: "docs-config-override" +description: |- + Terraform loads all configuration files within a directory and appends them together. Terraform also has a concept of overrides, a way to create files that are loaded last and merged into your configuration, rather than appended. +--- + +# Overrides + +Terraform loads all configuration files within a directory and +appends them together. Terraform also has a concept of _overrides_, +a way to create files that are loaded last and _merged_ into your +configuration, rather than appended. + +Overrides have a few use cases: + + * Machines (tools) can create overrides to modify Terraform + behavior without having to edit the Terraform configuration + tailored to human readability. + + * Temporary modifications can be made to Terraform configurations + without having to modify the configuration itself. + +Overrides names must be `override` or end in `_override`, excluding +the extension. Examples of valid override files are `override.tf`, +`override.tf.json`, `temp_override.tf`. + +Override files are loaded last in alphabetical order. + +Override files can be in Terraform syntax or JSON, just like non-override +Terraform configurations. + +## Example + +If you have a Terraform configuration `example.tf` with the contents: + +```hcl +resource "aws_instance" "web" { + ami = "ami-408c7f28" +} +``` + +And you created a file `override.tf` with the contents: + +```hcl +resource "aws_instance" "web" { + ami = "foo" +} +``` + +Then the AMI for the one resource will be replaced with "foo". Note +that the override syntax can be Terraform syntax or JSON. You can +mix and match syntaxes without issue. diff --git a/website/docs/configuration-0-11/providers.html.md b/website/docs/configuration-0-11/providers.html.md new file mode 100644 index 000000000..cb93f747d --- /dev/null +++ b/website/docs/configuration-0-11/providers.html.md @@ -0,0 +1,342 @@ +--- +layout: "docs" +page_title: "Configuring Providers" +sidebar_current: "docs-config-providers" +description: |- + Providers are responsible in Terraform for managing the lifecycle of a resource: create, read, update, delete. +--- + +# Provider Configuration + +Providers are responsible in Terraform for managing the lifecycle +of a [resource](/docs/configuration/resources.html): create, +read, update, delete. + +Most providers require some sort of configuration to provide +authentication information, endpoint URLs, etc. Where explicit configuration +is required, a `provider` block is used within the configuration as +illustrated in the following sections. + +By default, resources are matched with provider configurations by matching +the start of the resource name. For example, a resource of type +`vsphere_virtual_machine` is associated with a provider called `vsphere`. + +This page assumes you're familiar with the +[configuration syntax](/docs/configuration/syntax.html) +already. + +## Example + +A provider configuration looks like the following: + +```hcl +provider "aws" { + access_key = "foo" + secret_key = "bar" + region = "us-east-1" +} +``` + +## Description + +A `provider` block represents a configuration for the provider named in its +header. For example, `provider "aws"` above is a configuration for the +`aws` provider. + +Within the block body (between `{ }`) is configuration for the provider. +The configuration is dependent on the type, and is documented +[for each provider](/docs/providers/index.html). + +The arguments `alias` and `version`, if present, are special arguments +handled by Terraform Core for their respective features described above. All +other arguments are defined by the provider itself. + +A `provider` block may be omitted if its body would be empty. Using a resource +in configuration implicitly creates an empty provider configuration for it +unless a `provider` block is explicitly provided. + +## Initialization + +Each time a new provider is added to configuration -- either explicitly via +a `provider` block or by adding a resource from that provider -- it's necessary +to initialize that provider before use. Initialization downloads and installs +the provider's plugin and prepares it to be used. + +Provider initialization is one of the actions of `terraform init`. Running +this command will download and initialize any providers that are not already +initialized. + +Providers downloaded by `terraform init` are only installed for the current +working directory; other working directories can have their own installed +provider versions. + +Note that `terraform init` cannot automatically download providers that are not +distributed by HashiCorp. See [Third-party Plugins](#third-party-plugins) below +for installation instructions. + +For more information, see +[the `terraform init` command](/docs/commands/init.html). + +## Provider Versions + +Providers are released on a separate rhythm from Terraform itself, and thus +have their own version numbers. For production use, it is recommended to +constrain the acceptable provider versions via configuration, to ensure that +new versions with breaking changes will not be automatically installed by +`terraform init` in future. + +When `terraform init` is run _without_ provider version constraints, it +prints a suggested version constraint string for each provider: + +``` +The following providers do not have any version constraints in configuration, +so the latest version was installed. + +To prevent automatic upgrades to new major versions that may contain breaking +changes, it is recommended to add version = "..." constraints to the +corresponding provider blocks in configuration, with the constraint strings +suggested below. + +* provider.aws: version = "~> 1.0" +``` + +To constrain the provider version as suggested, add a `version` argument to +the provider configuration block: + +```hcl +provider "aws" { + version = "~> 1.0" + + access_key = "foo" + secret_key = "bar" + region = "us-east-1" +} +``` + +This special argument applies to _all_ providers. +[`terraform providers`](/docs/commands/providers.html) can be used to +view the specified version constraints for all providers used in the +current configuration. + +The `version` attribute value may either be a single explicit version or +a version constraint expression. Constraint expressions use the following +syntax to specify a _range_ of versions that are acceptable: + +* `>= 1.2.0`: version 1.2.0 or newer +* `<= 1.2.0`: version 1.2.0 or older +* `~> 1.2.0`: any non-beta version `>= 1.2.0` and `< 1.3.0`, e.g. `1.2.X` +* `~> 1.2`: any non-beta version `>= 1.2.0` and `< 2.0.0`, e.g. `1.X.Y` +* `>= 1.0.0, <= 2.0.0`: any version between 1.0.0 and 2.0.0 inclusive + +When `terraform init` is re-run with providers already installed, it will +use an already-installed provider that meets the constraints in preference +to downloading a new version. To upgrade to the latest acceptable version +of each provider, run `terraform init -upgrade`. This command also upgrades +to the latest versions of all Terraform modules. + +## Multiple Provider Instances + +You can define multiple configurations for the same provider in order to support +multiple regions, multiple hosts, etc. The primary use case for this is +using multiple cloud regions. Other use-cases include targeting multiple +Docker hosts, multiple Consul hosts, etc. + +To include multiple configurations for a given provider, include multiple +`provider` blocks with the same provider name, but set the `alias` field to an +instance name to use for each additional instance. For example: + +```hcl +# The default provider configuration +provider "aws" { + # ... +} + +# Additional provider configuration for west coast region +provider "aws" { + alias = "west" + region = "us-west-2" +} +``` + +A `provider` block with out `alias` set is known as the _default_ provider +configuration. When `alias` is set, it creates an _additional_ provider +configuration. For providers that have no required configuration arguments, the +implied _empty_ configuration is also considered to be a _default_ provider +configuration. + +Resources are normally associated with the default provider configuration +inferred from the resource type name. For example, a resource of type +`aws_instance` uses the _default_ (un-aliased) `aws` provider configuration +unless otherwise stated. + +The `provider` argument within any `resource` or `data` block overrides this +default behavior and allows an additional provider configuration to be +selected using its alias: + +```hcl +resource "aws_instance" "foo" { + provider = "aws.west" + + # ... +} +``` + +The value of the `provider` argument is always the provider name and an +alias separated by a period, such as `"aws.west"` above. + +Provider configurations may also be passed from a parent module into a +child module, as described in +[_Providers within Modules_](/docs/modules/usage.html#providers-within-modules). + +## Interpolation + +Provider configurations may use [interpolation syntax](/docs/configuration/interpolation.html) +to allow dynamic configuration: + +```hcl +provider "aws" { + region = "${var.aws_region}" +} +``` + +Interpolation is supported only for the per-provider configuration arguments. +It is not supported for the special `alias` and `version` arguments. + +Although in principle it is possible to use any interpolation expression within +a provider configuration argument, providers must be configurable to perform +almost all operations within Terraform, and so it is not possible to use +expressions whose value cannot be known until after configuration is applied, +such as the id of a resource. + +It is always valid to use [input variables](/docs/configuration/variables.html) +and [data sources](/docs/configuration/data-sources.html) whose configurations +do not in turn depend on as-yet-unknown values. [Local values](/docs/configuration/locals.html) +may also be used, but currently may cause errors when running `terraform destroy`. + +## Third-party Plugins + +Anyone can develop and distribute their own Terraform providers. (See +[Writing Custom Providers](/docs/extend/writing-custom-providers.html) for more +about provider development.) These third-party providers must be manually +installed, since `terraform init` cannot automatically download them. + +Install third-party providers by placing their plugin executables in the user +plugins directory. The user plugins directory is in one of the following +locations, depending on the host operating system: + +Operating system | User plugins directory +------------------|----------------------- +Windows | `%APPDATA%\terraform.d\plugins` +All other systems | `~/.terraform.d/plugins` + +Once a plugin is installed, `terraform init` can initialize it normally. + +Providers distributed by HashiCorp can also go in the user plugins directory. If +a manually installed version meets the configuration's version constraints, +Terraform will use it instead of downloading that provider. This is useful in +airgapped environments and when testing pre-release provider builds. + +### Plugin Names and Versions + +The naming scheme for provider plugins is `terraform-provider-_vX.Y.Z`, +and Terraform uses the name to understand the name and version of a particular +provider binary. + +If multiple versions of a plugin are installed, Terraform will use the newest +version that meets the configuration's version constraints. + +Third-party plugins are often distributed with an appropriate filename already +set in the distribution archive, so that they can be extracted directly into the +user plugins directory. + +### OS and Architecture Directories + +Terraform plugins are compiled for a specific operating system and architecture, +and any plugins in the root of the user plugins directory must be compiled for +the current system. + +If you use the same plugins directory on multiple systems, you can install +plugins into subdirectories with a naming scheme of `_` (for example, +`darwin_amd64`). Terraform uses plugins from the root of the plugins directory +and from the subdirectory that corresponds to the current system, ignoring +other subdirectories. + +Terraform's OS and architecture strings are the standard ones used by the Go +language. The following are the most common: + +* `darwin_amd64` +* `freebsd_386` +* `freebsd_amd64` +* `freebsd_arm` +* `linux_386` +* `linux_amd64` +* `linux_arm` +* `openbsd_386` +* `openbsd_amd64` +* `solaris_amd64` +* `windows_386` +* `windows_amd64` + +## Provider Plugin Cache + +By default, `terraform init` downloads plugins into a subdirectory of the +working directory so that each working directory is self-contained. As a +consequence, if you have multiple configurations that use the same provider +then a separate copy of its plugin will be downloaded for each configuration. + +Given that provider plugins can be quite large (on the order of hundreds of +megabytes), this default behavior can be inconvenient for those with slow +or metered Internet connections. Therefore Terraform optionally allows the +use of a local directory as a shared plugin cache, which then allows each +distinct plugin binary to be downloaded only once. + +To enable the plugin cache, use the `plugin_cache_dir` setting in +[the CLI configuration file](https://www.terraform.io/docs/commands/cli-config.html). +For example: + +```hcl +# (Note that the CLI configuration file is _not_ the same as the .tf files +# used to configure infrastructure.) + +plugin_cache_dir = "$HOME/.terraform.d/plugin-cache" +``` + +This directory must already exist before Terraform will cache plugins; +Terraform will not create the directory itself. + +Please note that on Windows it is necessary to use forward slash separators +(`/`) rather than the conventional backslash (`\`) since the configuration +file parser considers a backslash to begin an escape sequence. + +Setting this in the configuration file is the recommended approach for a +persistent setting. Alternatively, the `TF_PLUGIN_CACHE_DIR` environment +variable can be used to enable caching or to override an existing cache +directory within a particular shell session: + +```bash +export TF_PLUGIN_CACHE_DIR="$HOME/.terraform.d/plugin-cache" +``` + +When a plugin cache directory is enabled, the `terraform init` command will +still access the plugin distribution server to obtain metadata about which +plugins are available, but once a suitable version has been selected it will +first check to see if the selected plugin is already available in the cache +directory. If so, the already-downloaded plugin binary will be used. + +If the selected plugin is not already in the cache, it will be downloaded +into the cache first and then copied from there into the correct location +under your current working directory. + +When possible, Terraform will use hardlinks or symlinks to avoid storing +a separate copy of a cached plugin in multiple directories. At present, this +is not supported on Windows and instead a copy is always created. + +The plugin cache directory must *not* be the third-party plugin directory +or any other directory Terraform searches for pre-installed plugins, since +the cache management logic conflicts with the normal plugin discovery logic +when operating on the same directory. + +Please note that Terraform will never itself delete a plugin from the +plugin cache once it's been placed there. Over time, as plugins are upgraded, +the cache directory may grow to contain several unused versions which must be +manually deleted. diff --git a/website/docs/configuration-0-11/resources.html.md b/website/docs/configuration-0-11/resources.html.md new file mode 100644 index 000000000..c2bb21daf --- /dev/null +++ b/website/docs/configuration-0-11/resources.html.md @@ -0,0 +1,352 @@ +--- +layout: "docs" +page_title: "Configuring Resources" +sidebar_current: "docs-config-resources" +description: |- + The most important thing you'll configure with Terraform are resources. Resources are a component of your infrastructure. It might be some low level component such as a physical server, virtual machine, or container. Or it can be a higher level component such as an email provider, DNS record, or database provider. +--- + +# Resource Configuration + +The most important thing you'll configure with Terraform are +resources. Resources are a component of your infrastructure. +It might be some low level component such as a physical server, +virtual machine, or container. Or it can be a higher level +component such as an email provider, DNS record, or database +provider. + +This page assumes you're familiar with the +[configuration syntax](/docs/configuration/syntax.html) +already. + +## Example + +A resource configuration looks like the following: + +```hcl +resource "aws_instance" "web" { + ami = "ami-408c7f28" + instance_type = "t1.micro" +} +``` + +## Description + +The `resource` block creates a resource of the given `TYPE` (first +parameter) and `NAME` (second parameter). The combination of the type +and name must be unique. + +Within the block (the `{ }`) is configuration for the resource. The +configuration is dependent on the type, and is documented for each +resource type in the +[providers section](/docs/providers/index.html). + +### Meta-parameters + +There are **meta-parameters** available to all resources: + +- `count` (int) - The number of identical resources to create. This doesn't + apply to all resources. For details on using variables in conjunction with + count, see [Using Variables with `count`](#using-variables-with-count) below. + + -> Modules don't currently support the `count` parameter. + +- `depends_on` (list of strings) - Explicit dependencies that this resource has. + These dependencies will be created before this resource. For syntax and other + details, see the section below on [explicit + dependencies](#explicit-dependencies). + +- `provider` (string) - The name of a specific provider to use for this + resource. The name is in the format of `TYPE.ALIAS`, for example, `aws.west`. + Where `west` is set using the `alias` attribute in a provider. See [multiple + provider instances](#multiple-provider-instances). + +- `lifecycle` (configuration block) - Customizes the lifecycle behavior of the + resource. The specific options are documented below. + + The `lifecycle` block allows the following keys to be set: + + - `create_before_destroy` (bool) - This flag is used to ensure the replacement + of a resource is created before the original instance is destroyed. As an + example, this can be used to create an new DNS record before removing an old + record. + + - `prevent_destroy` (bool) - This flag provides extra protection against the + destruction of a given resource. When this is set to `true`, any plan that + includes a destroy of this resource will return an error message. + + - `ignore_changes` (list of strings) - Customizes how diffs are evaluated for + resources, allowing individual attributes to be ignored through changes. As + an example, this can be used to ignore dynamic changes to the resource from + external resources. Other meta-parameters cannot be ignored. + + ~> Ignored attribute names can be matched by their name, not state ID. + For example, if an `aws_route_table` has two routes defined and the + `ignore_changes` list contains "route", both routes will be ignored. + Additionally you can also use a single entry with a wildcard (e.g. `"*"`) + which will match all attribute names. Using a partial string together + with a wildcard (e.g. `"rout*"`) is **not** supported. + + -> Interpolations are not currently supported in the `lifecycle` configuration block (see [issue #3116](https://github.com/hashicorp/terraform/issues/3116)) + +### Timeouts + +Individual Resources may provide a `timeouts` block to enable users to configure the +amount of time a specific operation is allowed to take before being considered +an error. For example, the +[aws_db_instance](/docs/providers/aws/r/db_instance.html#timeouts) +resource provides configurable timeouts for the +`create`, `update`, and `delete` operations. Any Resource that provides Timeouts +will document the default values for that operation, and users can overwrite +them in their configuration. + +Example overwriting the `create` and `delete` timeouts: + +```hcl +resource "aws_db_instance" "timeout_example" { + allocated_storage = 10 + engine = "mysql" + engine_version = "5.6.17" + instance_class = "db.t1.micro" + name = "mydb" + + # ... + + timeouts { + create = "60m" + delete = "2h" + } +} +``` + +Individual Resources must opt-in to providing configurable Timeouts, and +attempting to configure the timeout for a Resource that does not support +Timeouts, or overwriting a specific action that the Resource does not specify as +an option, will result in an error. Valid units of time are `s`, `m`, `h`. + +### Explicit Dependencies + +Terraform ensures that dependencies are successfully created before a +resource is created. During a destroy operation, Terraform ensures that +this resource is destroyed before its dependencies. + +A resource automatically depends on anything it references via +[interpolations](/docs/configuration/interpolation.html). The automatically +determined dependencies are all that is needed most of the time. You can also +use the `depends_on` parameter to explicitly define a list of additional +dependencies. + +The primary use case of explicit `depends_on` is to depend on a _side effect_ +of another operation. For example: if a provisioner creates a file, and your +resource reads that file, then there is no interpolation reference for Terraform +to automatically connect the two resources. However, there is a causal +ordering that needs to be represented. This is an ideal case for `depends_on`. +In most cases, however, `depends_on` should be avoided and Terraform should +be allowed to determine dependencies automatically. + +The syntax of `depends_on` is a list of resources and modules: + +- Resources are `TYPE.NAME`, such as `aws_instance.web`. +- Modules are `module.NAME`, such as `module.foo`. + +When a resource depends on a module, _everything_ in that module must be +created before the resource is created. + +An example of a resource depending on both a module and resource is shown +below. Note that `depends_on` can contain any number of dependencies: + +```hcl +resource "aws_instance" "web" { + depends_on = ["aws_instance.leader", "module.vpc"] +} +``` + +-> **Use sparingly!** `depends_on` is rarely necessary. +In almost every case, Terraform's automatic dependency system is the best-case +scenario by having your resources depend only on what they explicitly use. +Please think carefully before you use `depends_on` to determine if Terraform +could automatically do this a better way. + +### Connection block + +Within a resource, you can optionally have a **connection block**. +Connection blocks describe to Terraform how to connect to the +resource for +[provisioning](/docs/provisioners/index.html). This block doesn't +need to be present if you're using only local provisioners, or +if you're not provisioning at all. + +Resources provide some data on their own, such as an IP address, +but other data must be specified by the user. + +The full list of settings that can be specified are listed on +the [provisioner connection page](/docs/provisioners/connection.html). + +### Provisioners + +Within a resource, you can specify zero or more **provisioner +blocks**. Provisioner blocks configure +[provisioners](/docs/provisioners/index.html). + +Within the provisioner block is provisioner-specific configuration, +much like resource-specific configuration. + +Provisioner blocks can also contain a connection block +(documented above). This connection block can be used to +provide more specific connection info for a specific provisioner. +An example use case might be to use a different user to log in +for a single provisioner. + +## Using Variables With `count` + +When declaring multiple instances of a resource using [`count`](#count), it is +common to want each instance to have a different value for a given attribute. + +You can use the `${count.index}` +[interpolation](/docs/configuration/interpolation.html) along with a map +[variable](/docs/configuration/variables.html) to accomplish this. + +For example, here's how you could create three [AWS +Instances](/docs/providers/aws/r/instance.html) each with their own +static IP address: + +```hcl +variable "instance_ips" { + default = { + "0" = "10.11.12.100" + "1" = "10.11.12.101" + "2" = "10.11.12.102" + } +} + +resource "aws_instance" "app" { + count = "3" + private_ip = "${lookup(var.instance_ips, count.index)}" + # ... +} +``` + +To reference a particular instance of a resource you can use `resource.foo.*.id[#]` where `#` is the index number of the instance. + +For example, to create a list of all [AWS subnet](/docs/providers/aws/r/subnet.html) ids vs referencing a specific subnet in the list you can use this syntax: + +```hcl +resource "aws_vpc" "foo" { + cidr_block = "198.18.0.0/16" +} + +resource "aws_subnet" "bar" { + count = 2 + vpc_id = "${aws_vpc.foo.id}" + cidr_block = "${cidrsubnet(aws_vpc.foo.cidr_block, 8, count.index)}" +} + +output "vpc_id" { + value = "${aws_vpc.foo.id}" +} + +output "all_subnet_ids" { + value = "${aws_subnet.bar.*.id}" +} + +output "subnet_id_0" { + value = "${aws_subnet.bar.*.id[0]}" +} + +output "subnet_id_1" { + value = "${aws_subnet.bar.*.id[1]}" +} +``` + +## Multiple Provider Instances + +By default, a resource targets the provider based on its type. For example +an `aws_instance` resource will target the "aws" provider. As of Terraform +0.5.0, a resource can target any provider by name. + +The primary use case for this is to target a specific configuration of +a provider that is configured multiple times to support multiple regions, etc. + +To target another provider, set the `provider` field: + +```hcl +resource "aws_instance" "foo" { + provider = "aws.west" + + # ... +} +``` + +The value of the field should be `TYPE` or `TYPE.ALIAS`. The `ALIAS` value +comes from the `alias` field value when configuring the +[provider](/docs/configuration/providers.html). + +```hcl +provider "aws" { + alias = "west" + + # ... +} +``` + +If no `provider` field is specified, the default provider is used. + +## Syntax + +The full syntax is: + +```text +resource TYPE NAME { + CONFIG ... + [count = COUNT] + [depends_on = [NAME, ...]] + [provider = PROVIDER] + + [LIFECYCLE] + + [CONNECTION] + [PROVISIONER ...] +} +``` + +where `CONFIG` is: + +```text +KEY = VALUE + +KEY { + CONFIG +} +``` + +where `LIFECYCLE` is: + +```text +lifecycle { + [create_before_destroy = true|false] + [prevent_destroy = true|false] + [ignore_changes = [ATTRIBUTE NAME, ...]] +} +``` + +where `CONNECTION` is: + +```text +connection { + KEY = VALUE + ... +} +``` + +where `PROVISIONER` is: + +```text +provisioner NAME { + CONFIG ... + + [when = "create"|"destroy"] + [on_failure = "continue"|"fail"] + + [CONNECTION] +} +``` diff --git a/website/docs/configuration-0-11/syntax.html.md b/website/docs/configuration-0-11/syntax.html.md new file mode 100644 index 000000000..56ffe511d --- /dev/null +++ b/website/docs/configuration-0-11/syntax.html.md @@ -0,0 +1,137 @@ +--- +layout: "docs" +page_title: "Configuration Syntax" +sidebar_current: "docs-config-syntax" +description: |- + The syntax of Terraform configurations is custom. It is meant to strike a + balance between human readable and editable as well as being machine-friendly. + For machine-friendliness, Terraform can also read JSON configurations. For + general Terraform configurations, however, we recommend using the Terraform + syntax. +--- + +# Configuration Syntax + +The syntax of Terraform configurations is called [HashiCorp Configuration +Language (HCL)](https://github.com/hashicorp/hcl). It is meant to strike a +balance between human readable and editable as well as being machine-friendly. +For machine-friendliness, Terraform can also read JSON configurations. For +general Terraform configurations, however, we recommend using the HCL Terraform +syntax. + +## Terraform Syntax + +Here is an example of Terraform's HCL syntax: + +```hcl +# An AMI +variable "ami" { + description = "the AMI to use" +} + +/* A multi + line comment. */ +resource "aws_instance" "web" { + ami = "${var.ami}" + count = 2 + source_dest_check = false + + connection { + user = "root" + } +} +``` + +Basic bullet point reference: + + * Single line comments start with `#` + + * Multi-line comments are wrapped with `/*` and `*/` + + * Values are assigned with the syntax of `key = value` (whitespace + doesn't matter). The value can be any primitive (string, + number, boolean), a list, or a map. + + * Strings are in double-quotes. + + * Strings can interpolate other values using syntax wrapped + in `${}`, such as `${var.foo}`. The full syntax for interpolation + is [documented here](/docs/configuration/interpolation.html). + + * Multiline strings can use shell-style "here doc" syntax, with + the string starting with a marker like `< **Important:** The `terraform push` command is deprecated, and only works with [the legacy version of Terraform Enterprise](/docs/enterprise-legacy/index.html). In the current version of Terraform Enterprise, you can upload configurations using the API. See [the docs about API-driven runs](/docs/enterprise/run/api.html) for more details. + +The [`terraform push` command](/docs/commands/push.html) uploads a configuration to a Terraform Enterprise (legacy) environment. The name of the environment (and the organization it's in) can be specified on the command line, or as part of the Terraform configuration in an `atlas` block. + +The `atlas` block does not configure remote state; it only configures the push command. For remote state, [use a `terraform { backend "" {...} }` block](/docs/backends/config.html). + +This page assumes you're familiar with the +[configuration syntax](/docs/configuration/syntax.html) +already. + +## Example + +Terraform push configuration looks like the following: + +```hcl +atlas { + name = "mitchellh/production-example" +} +``` + +~> **Why is this called "atlas"?** Atlas was previously a commercial offering +from HashiCorp that included a full suite of enterprise products. The products +have since been broken apart into their individual products, like **Terraform +Enterprise**. While this transition is in progress, you may see references to +"atlas" in the documentation. We apologize for the inconvenience. + +## Description + +The `atlas` block configures the settings when Terraform is +[pushed](/docs/commands/push.html) to Terraform Enterprise. Only one `atlas` block +is allowed. + +Within the block (the `{ }`) is configuration for Atlas uploading. +No keys are required, but the key typically set is `name`. + +**No value within the `atlas` block can use interpolations.** Due +to the nature of this configuration, interpolations are not possible. +If you want to parameterize these settings, use the Atlas block to +set defaults, then use the command-line flags of the +[push command](/docs/commands/push.html) to override. + +## Syntax + +The full syntax is: + +```text +atlas { + name = VALUE +} +``` diff --git a/website/docs/configuration-0-11/terraform.html.md b/website/docs/configuration-0-11/terraform.html.md new file mode 100644 index 000000000..1f1391c18 --- /dev/null +++ b/website/docs/configuration-0-11/terraform.html.md @@ -0,0 +1,85 @@ +--- +layout: "docs" +page_title: "Configuring Terraform" +sidebar_current: "docs-config-terraform" +description: |- + The `terraform` configuration section is used to configure Terraform itself, such as requiring a minimum Terraform version to execute a configuration. +--- + +# Terraform Configuration + +The `terraform` configuration section is used to configure Terraform itself, +such as requiring a minimum Terraform version to execute a configuration. + +This page assumes you're familiar with the +[configuration syntax](/docs/configuration/syntax.html) +already. + +## Example + +Terraform configuration looks like the following: + +```hcl +terraform { + required_version = "> 0.7.0" +} +``` + +## Description + +The `terraform` block configures the behavior of Terraform itself. + +The currently only allowed configurations within this block are +`required_version` and `backend`. + +`required_version` specifies a set of version constraints +that must be met to perform operations on this configuration. If the +running Terraform version doesn't meet these constraints, an error +is shown. See the section below dedicated to this option. + +See [backends](/docs/backends/index.html) for more detail on the `backend` +configuration. + +**No value within the `terraform` block can use interpolations.** The +`terraform` block is loaded very early in the execution of Terraform +and interpolations are not yet available. + +## Specifying a Required Terraform Version + +The `required_version` setting can be used to require a specific version +of Terraform. If the running version of Terraform doesn't match the +constraints specified, Terraform will show an error and exit. + +When [modules](/docs/configuration/modules.html) are used, all Terraform +version requirements specified by the complete module tree must be +satisified. This means that the `required_version` setting can be used +by a module to require that all consumers of a module also use a specific +version. + +The value of this configuration is a comma-separated list of constraints. +A constraint is an operator followed by a version, such as `> 0.7.0`. +Constraints support the following operations: + +- `=` (or no operator): exact version equality + +- `!=`: version not equal + +- `>`, `>=`, `<`, `<=`: version comparison, where "greater than" is a larger + version number + +- `~>`: pessimistic constraint operator. Example: for `~> 0.9`, this means + `>= 0.9, < 1.0`. Example: for `~> 0.8.4`, this means `>= 0.8.4, < 0.9` + +For modules, a minimum version is recommended, such as `> 0.8.0`. This +minimum version ensures that a module operates as expected, but gives +the consumer flexibility to use newer versions. + +## Syntax + +The full syntax is: + +```text +terraform { + required_version = VALUE +} +``` diff --git a/website/docs/configuration-0-11/variables.html.md b/website/docs/configuration-0-11/variables.html.md new file mode 100644 index 000000000..6d130a6a6 --- /dev/null +++ b/website/docs/configuration-0-11/variables.html.md @@ -0,0 +1,344 @@ +--- +layout: "docs" +page_title: "Configuring Input Variables" +sidebar_current: "docs-config-variables" +description: |- + Input variables are parameters for Terraform modules. + This page covers configuration syntax for variables. +--- + +# Input Variable Configuration + +Input variables serve as parameters for a Terraform module. + +When used in the root module of a configuration, variables can be set from CLI +arguments and environment variables. For [_child_ modules](/docs/configuration/modules.html), +they allow values to pass from parent to child. + +Input variable usage is introduced in the Getting Started guide section +[_Input Variables_](/intro/getting-started/variables.html). + +This page assumes you're familiar with the +[configuration syntax](/docs/configuration/syntax.html) +already. + +## Example + +Input variables can be defined as follows: + +```hcl +variable "key" { + type = "string" +} + +variable "images" { + type = "map" + + default = { + us-east-1 = "image-1234" + us-west-2 = "image-4567" + } +} + +variable "zones" { + default = ["us-east-1a", "us-east-1b"] +} +``` + +## Description + +The `variable` block configures a single input variable for a Terraform module. +Each block declares a single variable. + +The name given in the block header is used to assign a value to the variable +via the CLI and to reference the variable elsewhere in the configuration. + +Within the block body (between `{ }`) is configuration for the variable, +which accepts the following arguments: + +- `type` (Optional) - If set this defines the type of the variable. Valid values + are `string`, `list`, and `map`. If this field is omitted, the variable type + will be inferred based on `default`. If no `default` is provided, the type + is assumed to be `string`. + +- `default` (Optional) - This sets a default value for the variable. If no + default is provided, Terraform will raise an error if a value is not provided + by the caller. The default value can be of any of the supported data types, + as described below. If `type` is also set, the given value must be + of the specified type. + +- `description` (Optional) - A human-friendly description for the variable. This + is primarily for documentation for users using your Terraform configuration. + When a module is published in [Terraform Registry](https://registry.terraform.io/), + the given description is shown as part of the documentation. + +The name of a variable can be any valid identifier. However, due to the +interpretation of [module configuration blocks](/docs/configuration/modules.html), +the names `source`, `version` and `providers` are reserved for Terraform's own +use and are thus not recommended for any module intended to be used as a +child module. + +The default value of an input variable must be a _literal_ value, containing +no interpolation expressions. To assign a name to an expression so that it +may be re-used within a module, use [Local Values](/docs/configuration/locals.html) +instead. + +### Strings + +String values are simple and represent a basic key to value +mapping where the key is the variable name. An example is: + +```hcl +variable "key" { + type = "string" + default = "value" +} +``` + +A multi-line string value can be provided using heredoc syntax. + +```hcl +variable "long_key" { + type = "string" + default = < **Note**: Variable files are evaluated in the order in which they are +specified on the command line. If a particular variable is defined in more than +one variable file, the last value specified is effective. + +### Variable Merging + +When multiple values are provided for the same input variable, map values are +merged while all other values are overriden by the last definition. + +For example, if you define a variable twice on the command line: + +```shell +$ terraform apply -var foo=bar -var foo=baz +``` + +Then the value of `foo` will be `baz`, since it was the last definition seen. + +However, for maps, the values are merged: + +```shell +$ terraform apply -var 'foo={quux="bar"}' -var 'foo={bar="baz"}' +``` + +The resulting value of `foo` will be: + +```shell +{ + quux = "bar" + bar = "baz" +} +``` + +There is no way currently to unset map values in Terraform. Whenever a map +is modified either via variable input or being passed into a module, the +values are always merged. + +### Variable Precedence + +Both these files have the variable `baz` defined: + +_foo.tfvars_ + +```hcl +baz = "foo" +``` + +_bar.tfvars_ + +```hcl +baz = "bar" +``` + +When they are passed in the following order: + +```shell +$ terraform apply -var-file=foo.tfvars -var-file=bar.tfvars +``` + +The result will be that `baz` will contain the value `bar` because `bar.tfvars` +has the last definition loaded. + +Definition files passed using the `-var-file` flag will always be evaluated after +those in the working directory. + +Values passed within definition files or with `-var` will take precedence over +`TF_VAR_` environment variables, as environment variables are considered defaults. diff --git a/website/layouts/docs.erb b/website/layouts/docs.erb index 1bae9a193..d128abf2f 100644 --- a/website/layouts/docs.erb +++ b/website/layouts/docs.erb @@ -68,6 +68,67 @@ + > + Configuration + + + > Commands (CLI)