From d3d89ae8944ba8cb572230a61aeb3f2efa4563f9 Mon Sep 17 00:00:00 2001 From: cwlinode Date: Thu, 29 Nov 2018 12:55:31 -0500 Subject: [PATCH 1/6] Intro to HCL --- .../introduction-to-hcl/index.md | 176 ++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 docs/applications/configuration-management/introduction-to-hcl/index.md diff --git a/docs/applications/configuration-management/introduction-to-hcl/index.md b/docs/applications/configuration-management/introduction-to-hcl/index.md new file mode 100644 index 00000000000..a951d638b9a --- /dev/null +++ b/docs/applications/configuration-management/introduction-to-hcl/index.md @@ -0,0 +1,176 @@ +--- +author: + name: Linode + email: docs@linode.com +description: 'Use Salt States to Create a LAMP Stack and Fail2ban Across All Listed Salt Minions on Debian 8.' +keywords: ["terraform", "hcl", "hashicorp"] +license: '[CC BY-ND 4.0](https://creativecommons.org/licenses/by-nd/4.0)' +modified: 2018-11-26 +modified_by: + name: Linode +published: 2018-11-26 +title: Introduction to HashiCorp Configuration Language (HCL) +--- + +HCL is a configuration language developed by [HashiCorp](https://www.hashicorp.com/) to use in their product lineup. It was created with the goal of being both human and machine friendly, and to allow for use of command line tools but also JSON compatibility. This guides provides an introduction to some commonly used HCL terminology. + +## Providers + +A provider is a piece of software used to interact wit an IaaS or PaaS API, and Terraform can manage multiple providers in a single configuration. A provider usually requires a credentials set or token to interface with your service account such as your [Linode API access token](/docs/platform/api/getting-started-with-the-linode-api/#get-an-access-token). You can see a list of all officially available providers [here](https://www.terraform.io/docs/providers/). + +Configuring a provider block can be as minimal as simply specifying the Linode provider and your API access token. + +{{< file "terraform.tf" config >}} +provider "linode" { + token = ". . ." +} +{{< /file >}} + + +## Resources + +A Terraform resource can be any component of your infrastructure which is manageable with Terraform, from a Linode instance to a block storage volume, to a DNS record. Resources are indicated by a resource block in a `.tf` file and look similar to below: + +{{< file "terraform.tf" config >}} +resource "Linode-VM" "WordPress" { + image = "linode/ubuntu18.04" + label = "WPServer" + region = "us-east" + type = "g6-standard-1" + authorized_keys = [ ". . ." ] + root_pass = ". . ." +} +{{< /file >}} + +HCL-specific [meta-parameters](https://www.terraform.io/docs/configuration/resources.html#meta-parameters) exist for resources and are independent of the provider you use. Meta-parameters allow you to do things such as define the provider or the number of resources, or protect certain resources from being destroyed upon running `terraform apply`. See [Terraform's docs](https://www.terraform.io/docs/configuration/resources.html) for more information on resources. + + +## Modules + +A module is a Terraform block, or set of blocks, used to organize the creation of resources into reusable configurations. Use of a module is denoted by a module block, which will point to a source file containing all modules parameters. Modules can use variables and + +For example, to turn the resource block above into a module, put it into its own `.tf` file: + +{{< file "/modules/linode-vm/main.tf" config >}} +resource "Linode-VM" "WordPress" { + image = "linode/ubuntu18.04" + label = "WPServer" + region = "us-east" + type = "g6-standard-1" + authorized_keys = "${var.authorized_keys}" + root_pass = "${var.root_pass} +} +{{< /file >}} + +If you're using variables in the module, create a file to define them in: + +{{< file "/modules/linode-vm/variables.tf" config >}} +variable "authorized_keys" { + description = "SSH pubkey." + default = [". . ."] +} + +variable "root_pass" { + description = "The Linode's root password on creation." + default = ". . ." +} +{{< /file >}} + +Then specify the module using the `source` parameter in a module block: + +{{< file "terraform.tf" config>}} +module "linode-vm" { + source = "/modules/linode-vm" +} +{{< /file >}} + +See [Terraform's documentation](https://www.terraform.io/docs/modules/index.html) for more info on modules. + + +## Variables + +Variables in Terraform are similar to other language's concept of the term. A parameter is set, and that parameter can be subsequently referred back to throughout a project's configuration files. + +In the example below, variables are defined in `variables.tf` and their values assigned in `terraform.tfvars`. + +{{< file "variables.tf" >}} +token = {} +authorized_keys = {} + +variable "region" { + default = "us-east" +} +{{< /file >}} + +{{< file "terraform.tfvars" >}} +token = ". . ." +authorized_keys = [ ". . ." ] +{{< /file >}} + +Those variables are then used elsewhere, such as your project's main `.tf` file: + +{{< file "terraform.tf" >}} +provider "linode" { + token = "${var.token}" + authorized_keys = "${var.authorized_keys}" + region = "${var.region}" +} +{{< /file >}} + +{{< note >}} +Variables in `variables.tf` which appear in a `variable` block do not rely on the `tfvars` file, but empty strings do. If, for example, a token was not defined in `tfvars`, Terraform would ask for it during a `terraform apply` and you would need to enter it manually. If you prefer, you could also define all values in `variables.tf` and omit using a `tfvars` file. Organize your project however works best for you. +{{< /note >}} + +See [Terraform's documentation](https://www.terraform.io/intro/getting-started/variables.html) for more information. + + +## Functions + +Terraform has built-in computational functions you can use to manipulate string data. Some examples are reading a file path into a string , encrypting or creating a checksum of an object, and search and replace capabilities. + +[Terraform's documentation](https://www.terraform.io/docs/configuration/interpolation.html#supported-built-in-functions) gives a full list of available functions and what they do. + +{{< note >}} +Running `terraform console` creates an environment where you can test interpolation functions. For example: + +{{< output >}} +root@system:~$ terraform console +> list("newark", "atlanta", "dallas") +[ + "newark", + "atlanta", + "dallas", +] +> +{{< /output >}} +{{< /note >}} + + +## Interpolation + +Terraform supports [interpolation](https://en.wikipedia.org/wiki/String_interpolation) of [variables](https://www.terraform.io/docs/configuration/interpolation.html#available-variables), conditionals, and other values into your configuration file's string data. + +For example, when Terraform parses the example below, if the `environment` variable is `production`, then the `prod_subnet` variable is used. If not, then the variable `dev_subent` is used. + +{{< file >}} +resource "linode" "web" { + subnet = "${var.env == "production" ? var.prod_subnet : var.dev_subnet}" +} +{{< /file >}} + + +## Templates + +[Templates](https://www.terraform.io/docs/configuration/interpolation.html#templates) can be used to contain large data strings which are either self-contained in a [data source](https://www.terraform.io/docs/configuration/data-sources.html) block or called as a separate file. Templates can use variables and [meta-parameters](https://www.terraform.io/docs/configuration/resources.html#meta-parameters) just like modules and resources. + +For example, the following template filters all Linodes on your account to display only those running Debian 8. + + +{{< file >}} +data "linode_instance" { + filter { + name = "label" + values = ["linode/debian8"] + } +} +{{< /file >}} \ No newline at end of file From b1b4aa4e4725917a177f8eea1510583b3527c520 Mon Sep 17 00:00:00 2001 From: cwlinode Date: Thu, 29 Nov 2018 15:45:40 -0500 Subject: [PATCH 2/6] Update index.md --- .../configuration-management/introduction-to-hcl/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/applications/configuration-management/introduction-to-hcl/index.md b/docs/applications/configuration-management/introduction-to-hcl/index.md index a951d638b9a..14a1530e089 100644 --- a/docs/applications/configuration-management/introduction-to-hcl/index.md +++ b/docs/applications/configuration-management/introduction-to-hcl/index.md @@ -2,7 +2,7 @@ author: name: Linode email: docs@linode.com -description: 'Use Salt States to Create a LAMP Stack and Fail2ban Across All Listed Salt Minions on Debian 8.' +description: 'This guides provides an introduction to some commonly used HCL terminology.' keywords: ["terraform", "hcl", "hashicorp"] license: '[CC BY-ND 4.0](https://creativecommons.org/licenses/by-nd/4.0)' modified: 2018-11-26 @@ -173,4 +173,4 @@ data "linode_instance" { values = ["linode/debian8"] } } -{{< /file >}} \ No newline at end of file +{{< /file >}} From afea9d49673d90132adae9feae0edc783a4daf73 Mon Sep 17 00:00:00 2001 From: Andy Stevens Date: Fri, 30 Nov 2018 15:39:39 -0500 Subject: [PATCH 3/6] Tech Edit --- .../introduction-to-hcl/index.md | 50 ++++++++++++------- 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/docs/applications/configuration-management/introduction-to-hcl/index.md b/docs/applications/configuration-management/introduction-to-hcl/index.md index 14a1530e089..3d43d8ca550 100644 --- a/docs/applications/configuration-management/introduction-to-hcl/index.md +++ b/docs/applications/configuration-management/introduction-to-hcl/index.md @@ -16,7 +16,7 @@ HCL is a configuration language developed by [HashiCorp](https://www.hashicorp.c ## Providers -A provider is a piece of software used to interact wit an IaaS or PaaS API, and Terraform can manage multiple providers in a single configuration. A provider usually requires a credentials set or token to interface with your service account such as your [Linode API access token](/docs/platform/api/getting-started-with-the-linode-api/#get-an-access-token). You can see a list of all officially available providers [here](https://www.terraform.io/docs/providers/). +A provider is a piece of software used to interact with an Infrastructure as a Service (IaaS) or Platform as a Service (PaaS) API, and Terraform can manage multiple providers in a single configuration. A provider usually requires a credentials set or token to interface with your service account such as your [Linode API access token](/docs/platform/api/getting-started-with-the-linode-api/#get-an-access-token). You can see a list of all officially available providers [here](https://www.terraform.io/docs/providers/). Configuring a provider block can be as minimal as simply specifying the Linode provider and your API access token. @@ -32,7 +32,7 @@ provider "linode" { A Terraform resource can be any component of your infrastructure which is manageable with Terraform, from a Linode instance to a block storage volume, to a DNS record. Resources are indicated by a resource block in a `.tf` file and look similar to below: {{< file "terraform.tf" config >}} -resource "Linode-VM" "WordPress" { +resource "linode_instance" "WordPress" { image = "linode/ubuntu18.04" label = "WPServer" region = "us-east" @@ -42,17 +42,17 @@ resource "Linode-VM" "WordPress" { } {{< /file >}} -HCL-specific [meta-parameters](https://www.terraform.io/docs/configuration/resources.html#meta-parameters) exist for resources and are independent of the provider you use. Meta-parameters allow you to do things such as define the provider or the number of resources, or protect certain resources from being destroyed upon running `terraform apply`. See [Terraform's docs](https://www.terraform.io/docs/configuration/resources.html) for more information on resources. +HCL-specific [meta-parameters](https://www.terraform.io/docs/configuration/resources.html#meta-parameters) exist for resources and are independent of the provider you use. Meta-parameters allow you to do things such as define which provider to use or the number of resources to create, or protect certain resources from being destroyed upon running `terraform apply`. See [Terraform's docs](https://www.terraform.io/docs/configuration/resources.html) for more information on resources. ## Modules -A module is a Terraform block, or set of blocks, used to organize the creation of resources into reusable configurations. Use of a module is denoted by a module block, which will point to a source file containing all modules parameters. Modules can use variables and +A module is a Terraform block, or set of blocks, used to organize the creation of resources into reusable configurations. Use of a module is denoted by a module block, which will point to a source file containing all modules parameters. For example, to turn the resource block above into a module, put it into its own `.tf` file: {{< file "/modules/linode-vm/main.tf" config >}} -resource "Linode-VM" "WordPress" { +resource "linode_instance" "WordPress" { image = "linode/ubuntu18.04" label = "WPServer" region = "us-east" @@ -89,13 +89,13 @@ See [Terraform's documentation](https://www.terraform.io/docs/modules/index.html ## Variables -Variables in Terraform are similar to other language's concept of the term. A parameter is set, and that parameter can be subsequently referred back to throughout a project's configuration files. +Variables in Terraform are similar to other language's concept of the term. A parameter is set, and that parameter can be subsequently referred to throughout a project's configuration files. In the example below, variables are defined in `variables.tf` and their values assigned in `terraform.tfvars`. {{< file "variables.tf" >}} -token = {} -authorized_keys = {} +variable "token" {} +variable "authorized_keys" {} variable "region" { default = "us-east" @@ -112,13 +112,18 @@ Those variables are then used elsewhere, such as your project's main `.tf` file: {{< file "terraform.tf" >}} provider "linode" { token = "${var.token}" +} + +resource "linode_instance" "my_instance" { authorized_keys = "${var.authorized_keys}" region = "${var.region}" + + . . . } {{< /file >}} {{< note >}} -Variables in `variables.tf` which appear in a `variable` block do not rely on the `tfvars` file, but empty strings do. If, for example, a token was not defined in `tfvars`, Terraform would ask for it during a `terraform apply` and you would need to enter it manually. If you prefer, you could also define all values in `variables.tf` and omit using a `tfvars` file. Organize your project however works best for you. +Variables in `variables.tf` which have a default value do not rely on the `.tfvars` file, but empty variables do. However, if, for example, a token's value was not defined in a `.tfvars` file and there is no default value, Terraform would ask for it during a `terraform apply` and you would need to enter it manually. If you prefer, you could define default values in `variables.tf` and omit using a `.tfvars` file. {{< /note >}} See [Terraform's documentation](https://www.terraform.io/intro/getting-started/variables.html) for more information. @@ -150,11 +155,11 @@ root@system:~$ terraform console Terraform supports [interpolation](https://en.wikipedia.org/wiki/String_interpolation) of [variables](https://www.terraform.io/docs/configuration/interpolation.html#available-variables), conditionals, and other values into your configuration file's string data. -For example, when Terraform parses the example below, if the `environment` variable is `production`, then the `prod_subnet` variable is used. If not, then the variable `dev_subent` is used. +For example, when Terraform parses the example below, if the `env` variable has the value `production`, then the `prod_subnet` variable is used. If not, then the variable `dev_subent` is used. {{< file >}} -resource "linode" "web" { - subnet = "${var.env == "production" ? var.prod_subnet : var.dev_subnet}" +resource "linode_instance" "web" { + tags = ["${var.env == "production" ? var.prod_subnet : var.dev_subnet}"] } {{< /file >}} @@ -163,14 +168,23 @@ resource "linode" "web" { [Templates](https://www.terraform.io/docs/configuration/interpolation.html#templates) can be used to contain large data strings which are either self-contained in a [data source](https://www.terraform.io/docs/configuration/data-sources.html) block or called as a separate file. Templates can use variables and [meta-parameters](https://www.terraform.io/docs/configuration/resources.html#meta-parameters) just like modules and resources. -For example, the following template filters all Linodes on your account to display only those running Debian 8. +For example, the following template assigns a value for `${web_ip}` anywhere it exists inside the template file `ips.json`. + + +{{< file >}} +data "template_file" "web" { + template = "${file("${path.module}/ips.json")}" + + vars { + web_ip = "${linode_instance.web.ip_address}" + } +} +{{< /file >}} +You could then define an Output to view the template on `terraform apply`: {{< file >}} -data "linode_instance" { - filter { - name = "label" - values = ["linode/debian8"] - } +output "ip" { + value = "${data.template_file.web.rendered}" } {{< /file >}} From 8713f3d8efb70ada4bd7e4ce69bf4645f3dce405 Mon Sep 17 00:00:00 2001 From: leslitagordita Date: Fri, 7 Dec 2018 13:04:45 -0500 Subject: [PATCH 4/6] Copy Edits plus expanded details. --- .../introduction-to-hcl/index.md | 240 +++++++++++------- 1 file changed, 152 insertions(+), 88 deletions(-) diff --git a/docs/applications/configuration-management/introduction-to-hcl/index.md b/docs/applications/configuration-management/introduction-to-hcl/index.md index 3d43d8ca550..bb08b255c1b 100644 --- a/docs/applications/configuration-management/introduction-to-hcl/index.md +++ b/docs/applications/configuration-management/introduction-to-hcl/index.md @@ -2,8 +2,8 @@ author: name: Linode email: docs@linode.com -description: 'This guides provides an introduction to some commonly used HCL terminology.' -keywords: ["terraform", "hcl", "hashicorp"] +description: 'This guides provides an introduction to HCL syntax and commonly used HCL terminology.' +keywords: ["terraform", "hcl", "hashicorp", "orchestration"] license: '[CC BY-ND 4.0](https://creativecommons.org/licenses/by-nd/4.0)' modified: 2018-11-26 modified_by: @@ -12,128 +12,201 @@ published: 2018-11-26 title: Introduction to HashiCorp Configuration Language (HCL) --- -HCL is a configuration language developed by [HashiCorp](https://www.hashicorp.com/) to use in their product lineup. It was created with the goal of being both human and machine friendly, and to allow for use of command line tools but also JSON compatibility. This guides provides an introduction to some commonly used HCL terminology. +HCL is a configuration language built by [HashiCorp](https://www.hashicorp.com/) and is used with their cloud infrastructure automation tools, like [Terraform](/docs/applications/configuration-management/how-to-build-your-infrastructure-using-terraform-and-linode/). This language was created with the goal of being both human and machine friendly. HCL is JSON-compatible, which means it is interoperable with other systems outside of the Terraform product line. This guide provides an introduction to HCL syntax and some commonly used HCL terminology. + +## HCL Syntax + +HashiCorp's configuration syntax is easy to read and write. It was created to have clearly visible and defined structure as an improvement upon other well known configuration languages, like YAML. + + {{< file "~/terraform/main.tf">}} +# Linode provider block. Installs Linode plugin. +provider "linode" { + token = "${var.token}" +} + +variable "region" { + description = "This is the location where the Linode instance is deployed." +} + +/* A multi + line comment. */ +resource "linode_instance" "example_linode" { + image = "linode/ubuntu18.04" + label = "example-linode" + region = "${var.region}" + type = "g6-standard-1" + authorized_keys = [ "my-key" ] + root_pass = "example-password" +} + {{}} + + {{< note >}} + You should not include sensitive data in your resource declarations. For more information on secrets management, see the Secrets Management with Terraform guide. + {{}} + + Below are some key elements of HCL syntax: + + - HCL syntax is composed of *stanzas* or *blocks* that define a variety of configurations available to Terraform. [Provider plugins](https://www.terraform.io/docs/configuration/providers.html) expand on the available base Terraform configurations. + - Stanzas or blocks are comprised of `key = value` pairs. Terraform accepts the following value types: `string`, `number`, `boolean`, `map`, and `list`. + - Single line comments start with `#`, while multi-line comments use an opening `/*` and a closing `*/`. + - [Interpolation syntax](https://www.terraform.io/docs/configuration/interpolation.html) can be used to reference values stored outside of a configuration block in places like an input variable or a module's output. + + A variable reference using interpolation syntax is constructed as follows: `"${var.region}"`. This example references a variable named `region`. The opening `${` and closing `}` indicate the start of interpolation syntax. + - You can use multi-line strings using an opening `<}} + {{< file "~/terraform/terraform.tf" >}} provider "linode" { - token = ". . ." + token = "my-token" } -{{< /file >}} + {{}} + +Once your provider is declared, you can begin configuring resources available from the provider. + +{{< note >}} +Providers are written as Terraform plugins. Whenever declaring a new provider in your Terraform configuration files, the `terraform init` command should be run. This command will complete several initalization steps, like downloading new provider plugins, to prepare your working directory for use. +{{}} ## Resources -A Terraform resource can be any component of your infrastructure which is manageable with Terraform, from a Linode instance to a block storage volume, to a DNS record. Resources are indicated by a resource block in a `.tf` file and look similar to below: +A Terraform resource is any component of your infrastructure that is manageable with your provider. Resources available with the Linode provider range from a Linode instance, to a block storage volume, to a DNS record. Terraform's [Linode Provider documentation](https://www.terraform.io/docs/providers/linode/index.html) contains a full listng of all supported resources. -{{< file "terraform.tf" config >}} +Resources are declared using a resource block in a `.tf` configuration file. The following example deploys a Linode instance with an Ubuntu 18.04 image. + +{{< file "~/terraform/main.tf" >}} resource "linode_instance" "WordPress" { image = "linode/ubuntu18.04" label = "WPServer" region = "us-east" type = "g6-standard-1" - authorized_keys = [ ". . ." ] - root_pass = ". . ." + authorized_keys = [ "example-key" ] + root_pass = "example-root-pass" } -{{< /file >}} +{{}} -HCL-specific [meta-parameters](https://www.terraform.io/docs/configuration/resources.html#meta-parameters) exist for resources and are independent of the provider you use. Meta-parameters allow you to do things such as define which provider to use or the number of resources to create, or protect certain resources from being destroyed upon running `terraform apply`. See [Terraform's docs](https://www.terraform.io/docs/configuration/resources.html) for more information on resources. +This example deploys a 2GB Linode instance located in the US East data center with an Ubuntu 18.04 image. Values are also provided for a label, Public SSH key and root password to assign to the Linode. + +HCL-specific [meta-parameters](https://www.terraform.io/docs/configuration/resources.html#meta-parameters) are available to all resources and are independent of the provider you use. Meta-parameters allow you to do things like customize the lifecycle behavior of the resource, define the number of resources to create, or protect certain resources from being destroyed. See [Terraform's Resource Configuration](https://www.terraform.io/docs/configuration/resources.html) page for more information on meta-parameters. ## Modules -A module is a Terraform block, or set of blocks, used to organize the creation of resources into reusable configurations. Use of a module is denoted by a module block, which will point to a source file containing all modules parameters. +A module is an encapsulated set of Terraform configurations used to organize the creation of resources into reusable configurations. The [Terraform Module Registry](https://registry.terraform.io/) is a repository of community modules that can help you get started creating resources for various providers. You can also create your own modules to better organzie your Terraform configurations and make them available for reuse via remote version control systems, like GitHub. -For example, to turn the resource block above into a module, put it into its own `.tf` file: +A module block instructs Terraform to create an instance of a module that then instantiates any resources defined within that module. The only required configuration for a module block is the `source` paremeter that indicates the location of the module's source code. All other required configurations will vary from module to module. If you are using a local module you can use a relative path as the `source` value. The source path for a Terraform Registry module will be available on the module's registry page: -{{< file "/modules/linode-vm/main.tf" config >}} -resource "linode_instance" "WordPress" { - image = "linode/ubuntu18.04" - label = "WPServer" - region = "us-east" - type = "g6-standard-1" - authorized_keys = "${var.authorized_keys}" - root_pass = "${var.root_pass} +{{< file "~/terraform/main.tf" >}} +module "linode-module-example" { + source = "/modules/linode-module-example" } -{{< /file >}} +{{}} + +This example creates an instance of a module named `linode-example-module` and provides a relative path as the location of the module's source code. + +Creating modules involves defining resource requirements and paremeterizing configurations using input [variables](#variables), variable files and outputs. To learn how to create your own Terraform modules, see the Create a Terraform Module guide. + +## Input Variables -If you're using variables in the module, create a file to define them in: +You can define *input variables* to serve as Terraform module parameters. All input variables are normally defined within a file named `variables.tf`, however, they can be declared inside any `.tf` configuration file. -{{< file "/modules/linode-vm/variables.tf" config >}} -variable "authorized_keys" { - description = "SSH pubkey." - default = [". . ."] +- Terraform accepts the following variable types: `string`, `map`, `list`, `boolean`. If a variable type is not explicitly defined, Terraform will default to `type = "string"`. + +- It is good practice to provide a meaningful `description` with all your input variables. + +- If a variable does not contain a `default` value or if you would like to override a variable's default value, you must provide a value as an environment variable or with a variable values file. + + {{< file "~/terraform/variables.tf" >}} +variable "token" { + description = "This is your Linode APIv4 Token." } -variable "root_pass" { - description = "The Linode's root password on creation." - default = ". . ." +variable "region" { + description: " This is the location where the Linode instance is deployed." + default = "us-east" } -{{< /file >}} + {{}} -Then specify the module using the `source` parameter in a module block: +In the example `variables.tf` file two input variables named `token` and `region` are defined, respectively. The `region` variable defines a `default` value. Both variables will default to `type = "string"`, since a type is not explicitly declared. -{{< file "terraform.tf" config>}} -module "linode-vm" { - source = "/modules/linode-vm" -} -{{< /file >}} +Below, values for the previous example's input variables are provided in a variable values file and as environment variables, respectively. -See [Terraform's documentation](https://www.terraform.io/docs/modules/index.html) for more info on modules. +- **Variable Values File** + {{< file "~/terraform/terraform.tfvars" >}} +token = "my-token" +region = "us-west" + {{}} -## Variables +- **Environment Variable** -Variables in Terraform are similar to other language's concept of the term. A parameter is set, and that parameter can be subsequently referred to throughout a project's configuration files. + TF_VAR_token=my-token-value TF_VAR_region=us-west terraform apply -In the example below, variables are defined in `variables.tf` and their values assigned in `terraform.tfvars`. + {{< note >}} + Environment variables can only assign values to variables of `type = "string"` + {{}} -{{< file "variables.tf" >}} -variable "token" {} -variable "authorized_keys" {} +You can call existing input variables within your configuration file using Terraform's interpolation syntax. Notice the value of the `linode_instace` resource's `region` parameter: -variable "region" { - default = "us-east" +{{< file "~/terraform/main.tf" >}} +resource "linode_instance" "WordPress" { + image = "linode/ubuntu18.04" + label = "WPServer" + region = "${var.region}" + type = "g6-standard-1" + authorized_keys = [ "example-key" ] + root_pass = "example-root-pass" } -{{< /file >}} +{{}} -{{< file "terraform.tfvars" >}} -token = ". . ." -authorized_keys = [ ". . ." ] -{{< /file >}} +{{< note >}} +If a variable value is not provided in any of the ways discussed above and the variable is called in a resource configuration, Terraform will prompt you for the value when applying the configuration via a `terraform apply`. +{{}} + +For more information on variables, see [Terraform's documentation](https://www.terraform.io/intro/getting-started/variables.html). + +## Interpolation -Those variables are then used elsewhere, such as your project's main `.tf` file: +HCL supports the [interpolation](https://en.wikipedia.org/wiki/String_interpolation) of values. Interpolations are wrapped in an opening `${` and a closing `}`: -{{< file "terraform.tf" >}} + {{< file "~/terraform/terraform.tf" >}} provider "linode" { token = "${var.token}" } + {{}} -resource "linode_instance" "my_instance" { - authorized_keys = "${var.authorized_keys}" - region = "${var.region}" + This simple example demonstrates a string variable interpolation used to provide a value for the `token` configuration key. Interpolation syntax is powerful and includes the ability to reference attributes of other resources, call built-in functions, and use conditionals and templates. - . . . + {{< file "~/terraform/terraform.tf" >}} +resource "linode_instance" "web" { + tags = ["${var.env == "production" ? var.prod_subnet : var.dev_subnet}"] } -{{< /file >}} + {{< /file >}} -{{< note >}} -Variables in `variables.tf` which have a default value do not rely on the `.tfvars` file, but empty variables do. However, if, for example, a token's value was not defined in a `.tfvars` file and there is no default value, Terraform would ask for it during a `terraform apply` and you would need to enter it manually. If you prefer, you could define default values in `variables.tf` and omit using a `.tfvars` file. -{{< /note >}} - -See [Terraform's documentation](https://www.terraform.io/intro/getting-started/variables.html) for more information. + This resource's configuration uses a conditional to provide a value for the `tag` parameter. If the `env` variable has the value `production`, then the `prod_subnet` variable is used. If not, then the variable `dev_subent` is used. +### Functions -## Functions +Terraform has built-in computational functions that perform a variety of operations, like reading files, concatenating lists, encrypting or creating a checksum of an object, and search and replace capabilities. -Terraform has built-in computational functions you can use to manipulate string data. Some examples are reading a file path into a string , encrypting or creating a checksum of an object, and search and replace capabilities. +{{< file "~/terraform/terraform.tf" >}} +resource "linode_sshkey" "main_key" { + label = "foo" + ssh_key = "${chomp(file("~/.ssh/id_rsa.pub"))}" +} +{{}} -[Terraform's documentation](https://www.terraform.io/docs/configuration/interpolation.html#supported-built-in-functions) gives a full list of available functions and what they do. +In this example, `ssh_key = "${chomp(file("~/.ssh/id_rsa.pub"))}"` uses Terraform’s built-in function `file()` to provide a local file path to the public SSH key’s location. The `chomp()` function removes trailing new lines from the ssh key. Note that the nested functions are wrappted in opening `${` and closing `}` to indicate that the value should be interpolated. {{< note >}} Running `terraform console` creates an environment where you can test interpolation functions. For example: @@ -150,26 +223,11 @@ root@system:~$ terraform console {{< /output >}} {{< /note >}} +For a full list of available functions, refer to [Terraform's documentation](https://www.terraform.io/docs/configuration/interpolation.html#supported-built-in-functions). -## Interpolation - -Terraform supports [interpolation](https://en.wikipedia.org/wiki/String_interpolation) of [variables](https://www.terraform.io/docs/configuration/interpolation.html#available-variables), conditionals, and other values into your configuration file's string data. - -For example, when Terraform parses the example below, if the `env` variable has the value `production`, then the `prod_subnet` variable is used. If not, then the variable `dev_subent` is used. - -{{< file >}} -resource "linode_instance" "web" { - tags = ["${var.env == "production" ? var.prod_subnet : var.dev_subnet}"] -} -{{< /file >}} - - -## Templates - -[Templates](https://www.terraform.io/docs/configuration/interpolation.html#templates) can be used to contain large data strings which are either self-contained in a [data source](https://www.terraform.io/docs/configuration/data-sources.html) block or called as a separate file. Templates can use variables and [meta-parameters](https://www.terraform.io/docs/configuration/resources.html#meta-parameters) just like modules and resources. - -For example, the following template assigns a value for `${web_ip}` anywhere it exists inside the template file `ips.json`. +### Templates +Templates can be used to store large strings of data. The template provider exposes the data-sources for other Terraform resources or outputs to consume. The data-source can be a file or an inline template, while variables are defined to be used during interpolation. {{< file >}} data "template_file" "web" { @@ -181,10 +239,16 @@ data "template_file" "web" { } {{< /file >}} -You could then define an Output to view the template on `terraform apply`: +This template resource assigns a value for `${web_ip}` anywhere it exists inside the template file `ips.json`. You could then define an output variable to view the genrated template on a `terraform apply`: {{< file >}} output "ip" { value = "${data.template_file.web.rendered}" } {{< /file >}} + +For more information on all available components of interpolation syntax, see [Terraform's official documentation](https://www.terraform.io/docs/configuration/interpolation.html). + +## Next Steps + +Now that you are familiar with HCL, you can begin creating your own Linode instance with Terraform by following the [Use Terraform to Provision Linode Environments](/docs/applications/configuration-management/how-to-build-your-infrastructure-using-terraform-and-linode/) guide. From 3e67ae6091f5495b702c9df6038a019d6cc6cbce Mon Sep 17 00:00:00 2001 From: nmelehan Date: Mon, 10 Dec 2018 20:00:53 +0000 Subject: [PATCH 5/6] Copy edit 2 --- .../introduction-to-hcl/index.md | 167 +++++++++++------- 1 file changed, 99 insertions(+), 68 deletions(-) diff --git a/docs/applications/configuration-management/introduction-to-hcl/index.md b/docs/applications/configuration-management/introduction-to-hcl/index.md index bb08b255c1b..71098d941bf 100644 --- a/docs/applications/configuration-management/introduction-to-hcl/index.md +++ b/docs/applications/configuration-management/introduction-to-hcl/index.md @@ -10,15 +10,20 @@ modified_by: name: Linode published: 2018-11-26 title: Introduction to HashiCorp Configuration Language (HCL) +external_resources: + - '[HCL on GitHub](https://github.com/hashicorp/hcl)' + - '[Terraform Official Documentation - Configuration Syntax](https://www.terraform.io/docs/configuration/syntax.html)' --- -HCL is a configuration language built by [HashiCorp](https://www.hashicorp.com/) and is used with their cloud infrastructure automation tools, like [Terraform](/docs/applications/configuration-management/how-to-build-your-infrastructure-using-terraform-and-linode/). This language was created with the goal of being both human and machine friendly. HCL is JSON-compatible, which means it is interoperable with other systems outside of the Terraform product line. This guide provides an introduction to HCL syntax and some commonly used HCL terminology. +HCL is a configuration language authored by [HashiCorp](https://www.hashicorp.com/). HCL is used with HashiCorp's cloud infrastructure automation tools, like [Terraform](/docs/applications/configuration-management/how-to-build-your-infrastructure-using-terraform-and-linode/). The language was created with the goal of being both human and machine friendly. It is JSON compatible, which means it is interoperable with other systems outside of the Terraform product line. -## HCL Syntax +This guide provides an introduction to HCL syntax and some commonly used HCL terminology. -HashiCorp's configuration syntax is easy to read and write. It was created to have clearly visible and defined structure as an improvement upon other well known configuration languages, like YAML. +## HCL Syntax Overview - {{< file "~/terraform/main.tf">}} +HashiCorp's configuration syntax is easy to read and write. It was created to have a more clearly visible and defined structure when compared with other well known configuration languages, like YAML. + +{{< file "~/terraform/main.tf">}} # Linode provider block. Installs Linode plugin. provider "linode" { token = "${var.token}" @@ -40,49 +45,55 @@ resource "linode_instance" "example_linode" { } {{}} - {{< note >}} - You should not include sensitive data in your resource declarations. For more information on secrets management, see the Secrets Management with Terraform guide. - {{}} +{{< note >}} +You should not include sensitive data in your resource declarations. For more information on secrets management, see [Secrets Management with Terraform](/docs/link-terraform-secrets). +{{}} + +### Key Elements of HCL + +- HCL syntax is composed of *stanzas* or *blocks* that define a variety of configurations available to Terraform. [Provider plugins](https://www.terraform.io/docs/configuration/providers.html) expand on the available base Terraform configurations. + +- Stanzas or blocks are comprised of `key = value` pairs. Terraform accepts values of type string, number, boolean, map, and list. + +- Single line comments start with `#`, while multi-line comments use an opening `/*` and a closing `*/`. + +- [Interpolation syntax](https://www.terraform.io/docs/configuration/interpolation.html) can be used to reference values stored outside of a configuration block, like in an [input variable](#input-variables), or from a [Terraform module](#modules)'s output. + + An interpolated variable reference is constructed with the `"${var.region}"` syntax. This example references a variable named `region`, which is prefixed by `var.`. The opening `${` and closing `}` indicate the start of interpolation syntax. - Below are some key elements of HCL syntax: +- You can include multi-line strings by using an opening `<}} +{{< file "~/terraform/terraform.tf" >}} provider "linode" { token = "my-token" } - {{}} +{{}} Once your provider is declared, you can begin configuring resources available from the provider. {{< note >}} -Providers are written as Terraform plugins. Whenever declaring a new provider in your Terraform configuration files, the `terraform init` command should be run. This command will complete several initalization steps, like downloading new provider plugins, to prepare your working directory for use. +Providers are packaged as plugins for Terraform. Whenever declaring a new provider in your Terraform configuration files, the `terraform init` command should be run. This command will complete several initalization steps that are necessary before you can apply your Terraform configuration, including downloading the plugins for any providers you've specified. {{}} - ## Resources -A Terraform resource is any component of your infrastructure that is manageable with your provider. Resources available with the Linode provider range from a Linode instance, to a block storage volume, to a DNS record. Terraform's [Linode Provider documentation](https://www.terraform.io/docs/providers/linode/index.html) contains a full listng of all supported resources. +A Terraform *resource* is any component of your infrastructure that can be managed by your provider. Resources available with the Linode provider range from a Linode instance, to a block storage volume, to a DNS record. Terraform's [Linode Provider](https://www.terraform.io/docs/providers/linode/index.html) documentation contains a full listing of all supported resources. -Resources are declared using a resource block in a `.tf` configuration file. The following example deploys a Linode instance with an Ubuntu 18.04 image. +Resources are declared with a resource block in a `.tf` configuration file. This example block deploys a 2GB Linode instance located in the US East data center from an Ubuntu 18.04 image. Values are also provided for the Linode's label, public SSH key, and root password: {{< file "~/terraform/main.tf" >}} resource "linode_instance" "WordPress" { @@ -95,16 +106,21 @@ resource "linode_instance" "WordPress" { } {{}} -This example deploys a 2GB Linode instance located in the US East data center with an Ubuntu 18.04 image. Values are also provided for a label, Public SSH key and root password to assign to the Linode. +HCL-specific [meta-parameters](https://www.terraform.io/docs/configuration/resources.html#meta-parameters) are available to all resources and are independent of the provider you use. Meta-parameters allow you to do things like customize the lifecycle behavior of the resource, define the number of resources to create, or protect certain resources from being destroyed. See Terraform's [Resource Configuration](https://www.terraform.io/docs/configuration/resources.html) documentation for more information on meta-parameters. -HCL-specific [meta-parameters](https://www.terraform.io/docs/configuration/resources.html#meta-parameters) are available to all resources and are independent of the provider you use. Meta-parameters allow you to do things like customize the lifecycle behavior of the resource, define the number of resources to create, or protect certain resources from being destroyed. See [Terraform's Resource Configuration](https://www.terraform.io/docs/configuration/resources.html) page for more information on meta-parameters. +## Modules +A *module* is an encapsulated set of Terraform configurations used to organize the creation of resources in reusable configurations. -## Modules +The [Terraform Module Registry](https://registry.terraform.io/) is a repository of community modules that can help you get started creating resources for various providers. You can also create your own modules to better organize your Terraform configurations and make them available for reuse. Once you have created your modules, you can distribute them via a remote version control repository, like GitHub. + +### Using Modules -A module is an encapsulated set of Terraform configurations used to organize the creation of resources into reusable configurations. The [Terraform Module Registry](https://registry.terraform.io/) is a repository of community modules that can help you get started creating resources for various providers. You can also create your own modules to better organzie your Terraform configurations and make them available for reuse via remote version control systems, like GitHub. +A module block instructs Terraform to create an instance of a module. This block instantiates any resources defined within that module. -A module block instructs Terraform to create an instance of a module that then instantiates any resources defined within that module. The only required configuration for a module block is the `source` paremeter that indicates the location of the module's source code. All other required configurations will vary from module to module. If you are using a local module you can use a relative path as the `source` value. The source path for a Terraform Registry module will be available on the module's registry page: +The only universally required configuration for all module blocks is the `source` parameter which indicates the location of the module's source code. All other required configurations will vary from module to module. If you are using a local module you can use a relative path as the `source` value. The source path for a Terraform Module Registry module will be available on the module's registry page. + +This example creates an instance of a module named `linode-module-example` and provides a relative path as the location of the module's source code: {{< file "~/terraform/main.tf" >}} module "linode-module-example" { @@ -112,51 +128,59 @@ module "linode-module-example" { } {{}} -This example creates an instance of a module named `linode-example-module` and provides a relative path as the location of the module's source code. - -Creating modules involves defining resource requirements and paremeterizing configurations using input [variables](#variables), variable files and outputs. To learn how to create your own Terraform modules, see the Create a Terraform Module guide. +Authoring modules involves defining resource requirements and parameterizing configurations using [input variables](#input-variables), variable files, and outputs. To learn how to write your own Terraform modules, see [Create a Terraform Module](/docs/link-to-create-a-terraform). ## Input Variables -You can define *input variables* to serve as Terraform module parameters. All input variables are normally defined within a file named `variables.tf`, however, they can be declared inside any `.tf` configuration file. +You can define *input variables* to serve as Terraform configuration parameters. By convention, input variables are normally defined within a file named `variables.tf`. Terraform will load all files ending in `.tf`, so you can also define variables in files with other names. -- Terraform accepts the following variable types: `string`, `map`, `list`, `boolean`. If a variable type is not explicitly defined, Terraform will default to `type = "string"`. +- Terraform accepts variables of type string, number, boolean, map, and list. If a variable type is not explicitly defined, Terraform will default to `type = "string"`. -- It is good practice to provide a meaningful `description` with all your input variables. +- It is good practice to provide a meaningful `description` for all your input variables. -- If a variable does not contain a `default` value or if you would like to override a variable's default value, you must provide a value as an environment variable or with a variable values file. +- If a variable does not contain a `default` value, or if you would like to override a variable's default value, you must provide a value as an environment variable or within a variable values file. - {{< file "~/terraform/variables.tf" >}} +### Variable Declaration Example + +{{< file "~/terraform/variables.tf" >}} variable "token" { description = "This is your Linode APIv4 Token." } variable "region" { - description: " This is the location where the Linode instance is deployed." + description: "This is the location where the Linode instance is deployed." default = "us-east" } - {{}} +{{}} -In the example `variables.tf` file two input variables named `token` and `region` are defined, respectively. The `region` variable defines a `default` value. Both variables will default to `type = "string"`, since a type is not explicitly declared. +Two input variables named `token` and `region` are defined, respectively. The `region` variable defines a `default` value. Both variables will default to `type = "string"`, since a type is not explicitly declared. -Below, values for the previous example's input variables are provided in a variable values file and as environment variables, respectively. +### Supplying Variable Values -- **Variable Values File** +Variable values can be specified in `.tfvars` files. These files use the same syntax as Terraform configuration files: - {{< file "~/terraform/terraform.tfvars" >}} +{{< file "~/terraform/terraform.tfvars" >}} token = "my-token" region = "us-west" - {{}} +{{}} + +Terraform will automatically load values from filenames which match `terraform.tfvars` or `*.auto.tfvars`. If you store values in a file with another name, you need to specify that file with the `-var-file` option when running `terraform apply`. The `-var-file` option can be invoked multiple times: -- **Environment Variable** + terraform apply \ + -var-file="variable-values-1.tfvars" \ + -var-file="variable-values-2.tfvars" - TF_VAR_token=my-token-value TF_VAR_region=us-west terraform apply +Values can also be specified in environment variables when running `terraform apply`. The name of the variable should be prefixed with `TF_VAR_`: + + TF_VAR_token=my-token-value TF_VAR_region=us-west terraform apply + +{{< note >}} +Environment variables can only assign values to variables of `type = "string"` +{{}} - {{< note >}} - Environment variables can only assign values to variables of `type = "string"` - {{}} +### Referencing Variables -You can call existing input variables within your configuration file using Terraform's interpolation syntax. Notice the value of the `linode_instace` resource's `region` parameter: +You can call existing input variables within your configuration file using Terraform's interpolation syntax. Observe the value of the `region` parameter: {{< file "~/terraform/main.tf" >}} resource "linode_instance" "WordPress" { @@ -170,34 +194,36 @@ resource "linode_instance" "WordPress" { {{}} {{< note >}} -If a variable value is not provided in any of the ways discussed above and the variable is called in a resource configuration, Terraform will prompt you for the value when applying the configuration via a `terraform apply`. +If a variable value is not provided in any of the ways discussed above, and the variable is called in a resource configuration, Terraform will prompt you for the value when you run `terraform apply`. {{}} -For more information on variables, see [Terraform's documentation](https://www.terraform.io/intro/getting-started/variables.html). +For more information on variables, see Terraform's [Input Variables](https://www.terraform.io/intro/getting-started/variables.html) documentation. ## Interpolation -HCL supports the [interpolation](https://en.wikipedia.org/wiki/String_interpolation) of values. Interpolations are wrapped in an opening `${` and a closing `}`: +HCL supports the [interpolation](https://en.wikipedia.org/wiki/String_interpolation) of values. Interpolations are wrapped in an opening `${` and a closing `}`. Input variable names are prefixed with `var.`: - {{< file "~/terraform/terraform.tf" >}} +{{< file "~/terraform/terraform.tf" >}} provider "linode" { token = "${var.token}" } - {{}} +{{}} - This simple example demonstrates a string variable interpolation used to provide a value for the `token` configuration key. Interpolation syntax is powerful and includes the ability to reference attributes of other resources, call built-in functions, and use conditionals and templates. +Interpolation syntax is powerful and includes the ability to reference attributes of other resources, call built-in functions, and use conditionals and templates. - {{< file "~/terraform/terraform.tf" >}} +This resource's configuration uses a conditional to provide a value for the `tags` parameter: + +{{< file "~/terraform/terraform.tf" >}} resource "linode_instance" "web" { tags = ["${var.env == "production" ? var.prod_subnet : var.dev_subnet}"] } - {{< /file >}} +{{< /file >}} - This resource's configuration uses a conditional to provide a value for the `tag` parameter. If the `env` variable has the value `production`, then the `prod_subnet` variable is used. If not, then the variable `dev_subent` is used. +If the `env` variable has the value `production`, then the `prod_subnet` variable is used. If not, then the variable `dev_subent` is used. ### Functions -Terraform has built-in computational functions that perform a variety of operations, like reading files, concatenating lists, encrypting or creating a checksum of an object, and search and replace capabilities. +Terraform has built-in computational functions that perform a variety of operations, including reading files, concatenating lists, encrypting or creating a checksum of an object, and searching and replacing. {{< file "~/terraform/terraform.tf" >}} resource "linode_sshkey" "main_key" { @@ -206,13 +232,14 @@ resource "linode_sshkey" "main_key" { } {{}} -In this example, `ssh_key = "${chomp(file("~/.ssh/id_rsa.pub"))}"` uses Terraform’s built-in function `file()` to provide a local file path to the public SSH key’s location. The `chomp()` function removes trailing new lines from the ssh key. Note that the nested functions are wrappted in opening `${` and closing `}` to indicate that the value should be interpolated. +In this example, `ssh_key = "${chomp(file("~/.ssh/id_rsa.pub"))}"` uses Terraform’s built-in function `file()` to provide a local file path to the public SSH key’s location. The `chomp()` function removes trailing new lines from the SSH key. Observe that the nested functions are wrapped in opening `${` and closing `}` to indicate that the value should be interpolated. {{< note >}} Running `terraform console` creates an environment where you can test interpolation functions. For example: + terraform console + {{< output >}} -root@system:~$ terraform console > list("newark", "atlanta", "dallas") [ "newark", @@ -223,11 +250,15 @@ root@system:~$ terraform console {{< /output >}} {{< /note >}} -For a full list of available functions, refer to [Terraform's documentation](https://www.terraform.io/docs/configuration/interpolation.html#supported-built-in-functions). +Terraform's official documentation includes a complete list of [supported built-in functions](https://www.terraform.io/docs/configuration/interpolation.html#supported-built-in-functions). ### Templates -Templates can be used to store large strings of data. The template provider exposes the data-sources for other Terraform resources or outputs to consume. The data-source can be a file or an inline template, while variables are defined to be used during interpolation. +Templates can be used to store large strings of data. The template provider exposes the data sources for other Terraform resources or outputs to consume. The data source can be a file or an inline template. + +The data source can use Terraform's standard interpolation syntax for variables. The template is then rendered with variable values that you supply in the data block. + +This example template resource substitutes in the value from `${linode_instance.web.ip_address}` anywhere `${web_ip}` appears inside the template file `ips.json`: {{< file >}} data "template_file" "web" { @@ -239,7 +270,7 @@ data "template_file" "web" { } {{< /file >}} -This template resource assigns a value for `${web_ip}` anywhere it exists inside the template file `ips.json`. You could then define an output variable to view the genrated template on a `terraform apply`: +You could then define an [*output variable*](https://learn.hashicorp.com/terraform/getting-started/outputs.html) to view the rendered template when you later run `terraform apply`: {{< file >}} output "ip" { @@ -247,7 +278,7 @@ output "ip" { } {{< /file >}} -For more information on all available components of interpolation syntax, see [Terraform's official documentation](https://www.terraform.io/docs/configuration/interpolation.html). +Terraform's official documentation has a list of [all available components](https://www.terraform.io/docs/configuration/interpolation.html) of interpolation syntax. ## Next Steps From dfa10ea56fc098b042586cd8405b3c2c34549c45 Mon Sep 17 00:00:00 2001 From: nmelehan Date: Tue, 11 Dec 2018 22:46:38 +0000 Subject: [PATCH 6/6] Travis fixes, linking to other guides --- ci/vale/dictionary.txt | 1 + .../configuration-management/introduction-to-hcl/index.md | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/ci/vale/dictionary.txt b/ci/vale/dictionary.txt index 047ecfa38ad..d5fac73515f 100644 --- a/ci/vale/dictionary.txt +++ b/ci/vale/dictionary.txt @@ -915,6 +915,7 @@ pagent pagespeed pandoc param +parameterizing paramiko parallelization params diff --git a/docs/applications/configuration-management/introduction-to-hcl/index.md b/docs/applications/configuration-management/introduction-to-hcl/index.md index 71098d941bf..943aaf52b2f 100644 --- a/docs/applications/configuration-management/introduction-to-hcl/index.md +++ b/docs/applications/configuration-management/introduction-to-hcl/index.md @@ -46,7 +46,7 @@ resource "linode_instance" "example_linode" { {{}} {{< note >}} -You should not include sensitive data in your resource declarations. For more information on secrets management, see [Secrets Management with Terraform](/docs/link-terraform-secrets). +You should not include sensitive data in your resource declarations. For more information on secrets management, see [Secrets Management with Terraform](/docs/applications/configuration-management/secrets-management-with-terraform/). {{}} ### Key Elements of HCL @@ -86,7 +86,7 @@ provider "linode" { Once your provider is declared, you can begin configuring resources available from the provider. {{< note >}} -Providers are packaged as plugins for Terraform. Whenever declaring a new provider in your Terraform configuration files, the `terraform init` command should be run. This command will complete several initalization steps that are necessary before you can apply your Terraform configuration, including downloading the plugins for any providers you've specified. +Providers are packaged as plugins for Terraform. Whenever declaring a new provider in your Terraform configuration files, the `terraform init` command should be run. This command will complete several initialization steps that are necessary before you can apply your Terraform configuration, including downloading the plugins for any providers you've specified. {{}} ## Resources @@ -128,7 +128,7 @@ module "linode-module-example" { } {{}} -Authoring modules involves defining resource requirements and parameterizing configurations using [input variables](#input-variables), variable files, and outputs. To learn how to write your own Terraform modules, see [Create a Terraform Module](/docs/link-to-create-a-terraform). +Authoring modules involves defining resource requirements and parameterizing configurations using [input variables](#input-variables), variable files, and outputs. To learn how to write your own Terraform modules, see [Create a Terraform Module](/docs/applications/configuration-management/create-terraform-module/). ## Input Variables