From 6b9259513d677bcfc92d43497871fd78e15ee259 Mon Sep 17 00:00:00 2001 From: leslitagordita Date: Wed, 29 Jul 2020 15:44:47 -0400 Subject: [PATCH 01/11] Add updated link to Haschicorp security page --- .../index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/applications/configuration-management/terraform/how-to-build-your-infrastructure-using-terraform-and-linode/index.md b/docs/applications/configuration-management/terraform/how-to-build-your-infrastructure-using-terraform-and-linode/index.md index 4ce33666d72..281dd06d259 100644 --- a/docs/applications/configuration-management/terraform/how-to-build-your-infrastructure-using-terraform-and-linode/index.md +++ b/docs/applications/configuration-management/terraform/how-to-build-your-infrastructure-using-terraform-and-linode/index.md @@ -72,7 +72,7 @@ The Terraform Provider for Linode requires [Terraform version 0.12.0+](https://w ### Verify the Download -1. Import the HashiCorp Security GPG key (listed on the [HashiCorp Security](https://www.hashicorp.com/security.html) page under *Secure Communications*): +1. Import the HashiCorp Security GPG key (listed on the [HashiCorp Security](https://www.hashicorp.com/security) page under *Secure Communications*): gpg --recv-keys 51852D87348FFC4C From 36243dbb5e3ddb458c0830ca928d5189af01fe94 Mon Sep 17 00:00:00 2001 From: leslitagordita Date: Tue, 4 Aug 2020 19:13:07 -0400 Subject: [PATCH 02/11] Initial Draft --- .../index.md | 466 ++++++++++++++++++ 1 file changed, 466 insertions(+) create mode 100644 docs/applications/configuration-management/terraform/how-to-create-a-cloud-firewall-and-assign-it-to-a-linode-using-terraform/index.md diff --git a/docs/applications/configuration-management/terraform/how-to-create-a-cloud-firewall-and-assign-it-to-a-linode-using-terraform/index.md b/docs/applications/configuration-management/terraform/how-to-create-a-cloud-firewall-and-assign-it-to-a-linode-using-terraform/index.md new file mode 100644 index 00000000000..f77018afc7d --- /dev/null +++ b/docs/applications/configuration-management/terraform/how-to-create-a-cloud-firewall-and-assign-it-to-a-linode-using-terraform/index.md @@ -0,0 +1,466 @@ +--- +author: + name: Linode Community + email: docs@linode.com +description: 'This guide will use Terraform to deploy Linode instances with Cloud Firewalls assigned to them. You will create your own Terraform module to store reusable firewall rules that can be shared with your team. To complete this guide you need some familiarity with Terraform.' +og_description: 'This guide will use Terraform to deploy Linode instances with Cloud Firewalls assigned to them. You will create your own Terraform module to store reusable firewall rules that can be shared with your team. To complete this guide you need some familiarity with Terraform.' +keywords: ['terraform','infrastructure','firewalls','orchestration'] +license: '[CC BY-ND 4.0](https://creativecommons.org/licenses/by-nd/4.0)' +published: 2020-07-29 +modified_by: + name: Linode +title: "How To Deploy Secure Linodes using Cloud Firewalls and Terraform" +h1_title: "Deploying Secure Linodes using Cloud Firewalls and Terraform" +contributor: + name: Leslie Salazar + link: https://github.com/leslitagordita/ +external_resources: +- '[Terraform Linode Provider Official Documentation](https://registry.terraform.io/providers/linode/linode/latest/docs)' +--- + +Terraform modules allow you to better organize your configuration code and make the code reusable. You can host your Terraform modules on remote version control services, like GitHub, for others to use. The Terraform Module Registry hosts community modules that you can reuse for your own Terraform configurations, or you can publish your own modules for consumption by the Terraform community. + +In this guide, you will create a Linode Firewalls module which declares commonly used Cloud Firewall configurations. You will then use the module to create a Linode instance and assign the Linode to the Cloud Firewall. You can adopt the example configurations in this guide to create your own reusable Cloud Firewall configurations. + +{{< disclosure-note "What are Cloud Firewalls?" >}} +Linode Cloud Firewalls is a free service used to create, configure, and add stateful network-based firewalls to Linode services. A Cloud Firewall is independent of the service it is attached to, so you can apply a single Firewall to multiple Linode services. Linode Cloud Firewalls analyze traffic against a set of predefined rules at the network layer and determine if the traffic will be permitted to communicate with the Linode Service it secures. Cloud Firewalls work as a whitelist with an implicit deny rule– it will block all traffic by default and only pass through network traffic that meets the parameters of the configured rules. + +A Cloud Firewall can be configured with Inbound and Outbound rules. Inbound rules limit incoming network connections to a Linode service based on the port(s) and sources you configure. Outbound rules limit the outgoing network connections coming from a Linode service based on the port(s) and destinations you configure. +{{}} + +## Before You Begin + +1. If you are new to Terraform, read through our [A Beginner's Guide to Terraform](/docs/applications/configuration-management/beginners-guide-to-terraform/) guide to familiarize yourself with key concepts. + +1. See [Create a Terraform Module](/docs/applications/configuration-management/terraform/create-terraform-module/) for a deeper dive into Terraform's standard module structure and other helpful details. + +1. You need a [Linode’s API v4](https://developers.linode.com/api/v4) personal access token to use with Terraform. This token will allow you to create, update, and destroy Linode resources. Follow the [Getting Started with the Linode API](/docs/platform/api/getting-started-with-the-linode-api-new-manager/#get-an-access-token) to get a token. + {{< note >}}When you create a personal access token ensure that you set **Read/Write** access permissions for Linode instances and Cloud Firewalls. + {{}} + +1. [Install Terraform](/docs/applications/configuration-management/how-to-build-your-infrastructure-using-terraform-and-linode/#install-terraform) on your local computer. + + {{< note >}} +This guide was written using [Terraform version 0.12.29](https://www.hashicorp.com/blog/announcing-terraform-0-12/). + {{}} + +1. Install Git on your computer and complete the steps in the **Configure Git** section of the [Getting Started with Git guide](/docs/development/version-control/how-to-configure-git/#configure-git). + +## Create Your Cloud Firewalls Module + +The Cloud Firewalls module includes child modules that split up the required resources between the *root module*, an `inbound_ssh` module, a `mysql` module, and a `web-server` module. The root module is the directory that holds the Terraform configuration files that are applied to build your desired infrastructure. These files provide an entry point into any child modules. Each child module uses the `linode_firewall` resource to create reusable Cloud Firewall rules for specific use cases. + +{{< note >}} +You can apply up to three Cloud Firewalls per Linode instance. +{{}} + +{{< note >}} +You can view the files created throughout this tutorial in the [author's GitHub repository](https://github.com/leslitagordita/main-firewalls). You can clone the repository and use it as a foundation to create your own custom Cloud Firewalls module. +{{}} + +### Create Your Module's Directory Structure + +After completing all the sections in [Create Your Cloud Firewalls Module](/docs/applications/configuration-management/terraform/how-to-create-a-cloud-firewall-and-assign-it-to-a-linode-using-terraform/#create-your-cloud-firewalls-module), you will have the directory structure outlined below. In this section, you will create this directory structure. + +{{< output >}} +main_firewalls/ +├── main.tf +├── outputs.tf +├── secrets.tfvars +├── terraform +├── terraform.tfvars +├── variables.tf +└── modules/ +    ├── inbound_ssh/ +    │   ├── main.tf +    │   ├── variables.tf +    │   └── outputs.tf +    └── mysql/ +    │   ├── main.tf +    │   ├── variables.tf +    │   └── outputs.tf +    └── web_server/ +        ├── main.tf +        ├── variables.tf +        └── outputs.tf +{{}} + +1. Move into your `terraform` directory. + + cd ~/terraform + +1. From your `terraform` directory, create the directory structure outlined above. + + mkdir -p main_firewalls/{inbound_ssh,mysql,web_server} + + {{< note >}} +If you followed our [install Terraform](/docs/applications/configuration-management/how-to-build-your-infrastructure-using-terraform-and-linode/#install-terraform) steps, then your Terraform executable will be located in the `terraform` directory. If this is not the case, ensure that you can execute Terraform commands from the `main_firewalls` directory. + {{}} + +### Create the Inbound SSH Child Module + +When applied to a Terraform configuration, the `inbound_ssh` module will create a Cloud Firewall with inbound rules to allow `TCP` connections to port `22` from all sources. Port `22` is typically used for secure shell (SSH) connections, secure logins, file transfers (scp, sftp), and port forwarding. + +1. Using your preferred text editor, create the `inbound_ssh` module's `main.tf` file. Copy and save the contents of the example below. + + {{< file "~/main_firewalls/inbound_ssh/main.tf">}} +resource "linode_firewall" "ssh_inbound" { + label = var.firewall_label + tags = var.tags + + inbound { + protocol = "TCP" + ports = ["22"] + addresses = ["0.0.0.0/0"] + } + + linodes = var.linodes +} + {{}} + + - This file uses the Terraform Linode Provider's `linode_firewall` resource to create a Cloud Firewall with the inbound rules described above. + - The `linodes` argument expects a list of Linode IDs. When a Linode ID is passed to the `linodes` argument, the `inbound_ssh` firewall will be assigned to it. + - The arguments `label`, `tags`, and `linodes` make use of [input variables](https://www.terraform.io/docs/configuration/variables.html), which allow these values to be customized when using the module for your resource configurations. + +1. Create the `variables.tf` file to declare the `inbout_ssh` module's input variables. Copy and save the contents of the example below. + + {{< file "~/main_firewalls/inbound_ssh/variables.tf">}} +variable "linodes" { + description = "List of Linode ids to which the rule sets will be applied" + type = list(string) + default = [] +} + +variable "firewall_label" { + description = "This firewall's human-readable firewall_label" + type = string + default = "my-firewall" +} + +variable "tags" { + description = "List of tags to apply to this Firewall" + type = list(string) + default = [] +} + {{}} + + The input variables declared in this file correspond to the `linode_firewalls` resource arguments that the `inbound_ssh` module exposes for customization. In a similar way, you can expose different arguments for your Cloud Firewall child modules as needed. + +### Create the MySQL Child Module + +The `mysql` child module creates a Cloud Firewall with an inbound rule commonly suited for client connections to a MySQL server. The inbound rule allows `TCP` connections to port `3306`. The `addressses` argument accepts in input variable so that it can be customized to restrict access to a specific IP address(es) or CIDR block. + +1. Using your preferred text editor, create the `inbound_ssh` module's `main.tf` file. Copy and save the contents of the example below. + + {{< file "~/main_firewalls/mysql/main.tf">}} +resource "linode_firewall" "mysql" { + label = var.firewall_label + tags = var.tags + + inbound { + protocol = "TCP" + ports = ["3306"] + addresses = var.addresses + } + linodes = var.linodes +} + {{}} + + - This file uses the Terraform Linode Provider's `linode_firewall` resource to create a Cloud Firewall with the inbound rules described above. + - The `linodes` argument expects a list of Linode IDs. When a Linode ID is passed to the `linodes` argument, the `mysql` firewall will be assigned to it. + - The arguments `label`, `tags`, `linodes`, and `addresses` make use of [input variables](https://www.terraform.io/docs/configuration/variables.html), which allow these values to be customized when using the module for your resource configurations. + +1. Create the `variables.tf` file to declare the `inbout_ssh` module's input variables. Copy and save the contents of the example below. + + {{< file "~/main_firewalls/mysql/variables.tf">}} +variable "linodes" { + description = "List of Linode ids to which the rule sets will be applied" + type = list(string) + default = [] +} + +variable "firewall_label" { + description = "This firewall's human-readable firewall_label" + type = string + default = "my-firewall" +} + +variable "tags" { + description = "List of tags to apply to this Firewall" + type = list(string) + default = [] +} + +variable "addresses" { + description = "A list of IP addresses, CIDR blocks, or 0.0.0.0/0 (to allow all) this rule applies to." + type = list(string) + default = ["0.0.0.0/0"] +} + {{}} + + The input variables declared in this file correspond to the `linode_firewalls` resource arguments that the `mysql` module exposes for customization. + +### Create the Web Server Child Module + +The `web_server` child module, when applied, creates a Cloud Firewall with inbound and outbound rules allowing incoming and outgoing connections from all sources and destinations to ports `80` and `443` over `TCP`. These ports are commonly associated with [HTTP](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol) and [HTTPS](https://en.wikipedia.org/wiki/HTTPS), respectively. + +1. Using your preferred text editor, create the `web_server` module's `main.tf` file. Copy and save the contents of the example below. + + {{< file "~/main_firewalls/web_server/main.tf">}} +resource "linode_firewall" "web_server" { + label = var.firewall_label + tags = var.tags + + inbound { + protocol = "TCP" + ports = ["80"] + addresses = ["0.0.0.0/0"] + } + + outbound { + protocol = "TCP" + ports = ["80"] + addresses = ["0.0.0.0/0"] + } + + inbound { + protocol = "TCP" + ports = ["443"] + addresses = ["0.0.0.0/0"] + } + + outbound { + protocol = "TCP" + ports = ["443"] + addresses = ["0.0.0.0/0"] + } + + linodes = var.linodes +} + {{}} + + - This file uses the Terraform Linode Provider's `linode_firewall` resource to create a Cloud Firewall with the inbound and outbound rules described above. + - The `linodes` argument expects a list of Linode IDs. When a Linode ID is passed to the `linodes` argument, the `web_server` firewall will be assigned to it. + - The arguments `label`, `tags`, and `linodes` make use of [input variables](https://www.terraform.io/docs/configuration/variables.html), which allow these values to be customized when using the module for your resource configurations. + +1. Create the `variables.tf` file to declare the `web_server` module's input variables. Copy and save the contents of the example below. + + {{< file "~/main_firewalls/web_server/variables.tf">}} +variable "linodes" { + description = "List of Linode ids to which the rule sets will be applied" + type = list(string) + default = [] +} + +variable "firewall_label" { + description = "This firewall's human-readable firewall_label" + type = string + default = "my-firewall" +} + +variable "tags" { + description = "List of tags to apply to this Firewall" + type = list(string) + default = [] +} + {{}} + + The input variables declared in this file correspond to the `linode_firewalls` resource arguments that the `web_server` module exposes for customization. + +### Create the Root Module + +Now that all the Cloud Firewalls child modules have been created, you can create your root module. The root module is in charge of defining the infrastructure to be built by Terraform. The root module has access to all the child modules and can make use of all or none of them. In this section, you will create a root module that can create a Cloud Firewall using the rules defined in the `web_server` child module. It also creates two Linode instance and assigns the Cloud Firewall to both Linode instances. + +1. Using your preferred text editor, create the root module's `main.tf` file. Copy and save the contents of the example below. + + {{< file "~/main_firewalls/main.tf">}} +provider "linode" { + api_version = "v4beta" + token = var.token +} + +locals { + key = var.key + linode_ids = linode_instance.linode_base[*].id +} + +module "firewalls_web" { + source = "./modules/web_server" + firewall_label = var.firewall_label_map["web"] + tags = var.tags + linodes = local.linode_ids +} + +resource "linode_sshkey" "main_key" { + label = var.key_label + ssh_key = chomp(file(local.key)) +} + +resource "linode_instance" "linode_base" { + count = var.linode_count + image = var.image + label = "${var.label}_${count.index}" + region = var.region + type = var.type + authorized_keys = [ linode_sshkey.main_key.ssh_key ] + root_pass = var.root_pass +} + {{}} + + - The `provider` block is a requirement to use the Linode provider. Since Cloud Firewalls is currently in an open beta, you must use the `api_version` argument to tell Terraform to use Linode's beta [API v4 endpoints](https://developers.linode.com/api/v4). + - The `locals` block declares a local variable `key` whose value will be provided by an input variable. The `linode_ids` local variable is used by the `web_server` module instance in the next block to retrieve the Linode ids for the Linodes to be assigned to the Cloud Firewall that will be created. + - The `module "firewalls_web"` block creates an instance of the `web_server` child module, which when applied will create a new Cloud Firewall with the configurations provided by the child module and input variable values you will provide in a later step. + + The `source` argument provides the location of the child module’s source code and is required whenever you create an instance of a module. + + All other arguments are determined by the child module. Since the `web_server` child module exposes the `firewall_label`, `tags`, and `linodes` values must be provided for them. Input variables are used in the root module to make it reusable. Depending on the child module that you are using, and the label you'd like to assign to the Cloud Firewall, you should replace the key value for the `var.firewall_label_map["web"]`. Refer to the `variables.tf` file for details. + + The `linodes` argument retrieves its value from the local variable defined in the previous block. + + - The `linode_sshkey` resource will create Linode SSH Keys tied to your Linode account. These keys can be reused for future Linode deployments once the resource has been created. + + `ssh_key = chomp(file(local.key))` uses Terraform’s built-in function `file()` to provide a local file path to your public SSH key’s location. The location of the file path is the value of the local variable `key`. The `chomp()` built-in function removes trailing new lines from the SSH key. + + - The `linode_instance` resource creates two Linode instances with configurations provided by its arguments. + + The `count` argument controls how many Linode instances will be created with the configurations provided in the resource block's arguments. + + Since Linode labels must be unique, the `label` argument will create a label based on a value provided to the `var.label` input variable and the index number representing the Linode instance that is created. + + - The `authorized_keys` argument uses the SSH public key provided by the `linode_sshkey` resource in the previous resource block. + +1. Create the `variables.tf` file to declare the root module's input variables. These input variables are a combination of the all the values required by the various resources used in the `main.tf` file. You can update the default values to your own preferences. + + {{< file "~/main_firewalls/variables.tf" >}} +variable "token" { + description = " Linode API token" +} + +variable "key" { + description = "Public SSH Key's path." +} + +variable "key_label" { + description = "New SSH key label." +} + +variable "linode_count" { + description = "The number of Linode instances to deploy." + type = number + default = 1 +} + +variable "image" { + description = "Image to use for Linode instance." + default = "linode/ubuntu18.04" +} + +variable "label" { + description = "The Linode's label is for display purposes only, but must be unique." + default = "default-linode" +} + +variable "region" { + description = "The region where your Linode will be located." + default = "us-east" +} + +variable "type" { + description = "Your Linode's plan type." + default = "g6-standard-1" +} + +variable "root_pass" { + description = "Your Linode's root user's password." +} + +variable "linodes" { + description = "List of Linode ids to which the rule sets will be applied" + type = list(string) + default = [] +} + +variable "firewall_label_map" { + type = "map" + default = { + "web" = "firewall_web_server" + "mysql" = "firewall_mysql" + "ssh" = "firewall_ssh" + } +} + +variable "tags" { + description = "List of tags to apply to this Firewall" + type = list(string) + default = [] +} + + {{}} + + The variable declaration for `firewall_label_map`, by default, creates a map with default keys `web`, `mysql`, and `ssh`. You can use these keys to provide the map's default values to the `firewall_label` argument. Alternatively, you can override the default values in the `terraform.tfvars` file that you will create in a later step. + +1. Create the `outputs.tf` file. This file exposes the IDs of the Linode instances that are created by the `linode_instance` resource block and will be printed to your console when the root module's configurations are applied. + + {{< file "~/main_firewalls/output.tf" >}} + output "linode_id" { + value = linode_instance.linode_base[*].id +} + {{}} + +1. Create the `terraform.tfvars` file to provide values for all input variables defined in the `variables.tf` file. This file will exclude any values that provide sensitive data, like passwords and API tokens. A file containing sensitive values will be created in the next step. You can replace any of these values with your own. + + {{< file "~/main_firewalls/terraform.tfvars" >}} +key = "~/.ssh/id_rsa.pub" +linode_count = 3 +key_label = "my-ssh-key" +label = "linode" +tags = ["my-example-tag"] +firewall_label_map = { + "web" = "firewall_webserver_http_https" +} + {{}} + +1. Create a file named `secrets.tfvars` to store any sensitive values. Replace the example values with your own. + + {{< file "~/main_firewalls/secrets.tfvars">}} +token = "my-api-v4-token" +root_pass = "my-super-strong-root-password" + {{}} + + {{< note >}} +This file should never be tracked in version control software and should be listed in your `.gitignore` file if using GitHub. + {{}} + +You are now ready to apply your `main_firewalls` module’s Terraform configuration. These steps will be completed in the next section. + +## Initialize, Plan and Apply the Terraform Configuration + +Whenever a new provider is used in a Terraform configuration, it must first be initialized. The initialization process downloads and installs the provider’s plugin and performs any other steps needed for its use. Before applying your configuration, it is also useful to view your configuration’s execution plan before making any actual changes to your infrastructure. In this section, you will complete all these steps. + +1. Initialize the Linode provider. Ensure you are in the `linode_stackscripts` directory before running this command: + + terraform init + + You will see a message that confirms that the provider plugins have been successfully initialized. + +1. Run the Terraform plan command: + + terraform plan -var-file="secrets.tfvars" -var-file="terraform.tfvars" + + Terraform plan won’t take any action or make any changes on your Linode account. Instead, an analysis is done to determine which actions (i.e. Linode instance creations, deletions, or modifications) are required to achieve the state described in your configuration. + +1. You are now ready to create the infrastructure defined in your root module's `main.tf` configuration file: + + terraform apply -var-file="secrets.tfvars" -var-file="terraform.tfvars" + + Since you are using multiple variable value files, you must call each file individually using the `var-file` argument. You will be prompted to confirm the `apply` action. Type *yes* and hit **enter**. Terraform will begin to create the resources you’ve defined throughout this guide. This process will take a couple of minutes to complete. Once the infrastructure has been successfully built you will see a similar output: + + {{< output >}} + Apply complete! Resources: 3 added, 0 changed, 0 destroyed. + {{}} + +1. You can verify that your Cloud Firewalls have been created and applied to your new Linode instances by logging into the [Linode Cloud Manager](https://cloud.linode.com/) and navigating to the **Firewalls** section of the manager. + +## Next Steps + +To learn how to [version control](/docs/applications/configuration-management/terraform/create-terraform-module/#version-control-your-terraform-module) the `main-firewalls` module that you created in this guide, see the [Create a Terraform Module](/docs/applications/configuration-management/terraform/create-terraform-module/) guide. \ No newline at end of file From b60f9ca3935405eae931cc05eacd95bf83d1c079 Mon Sep 17 00:00:00 2001 From: leslitagordita Date: Tue, 4 Aug 2020 19:14:24 -0400 Subject: [PATCH 03/11] Update guide URL --- .../index.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/applications/configuration-management/terraform/{how-to-create-a-cloud-firewall-and-assign-it-to-a-linode-using-terraform => how-to-deploy-secure-linodes-using-cloud-firewalls-and-terraform}/index.md (100%) diff --git a/docs/applications/configuration-management/terraform/how-to-create-a-cloud-firewall-and-assign-it-to-a-linode-using-terraform/index.md b/docs/applications/configuration-management/terraform/how-to-deploy-secure-linodes-using-cloud-firewalls-and-terraform/index.md similarity index 100% rename from docs/applications/configuration-management/terraform/how-to-create-a-cloud-firewall-and-assign-it-to-a-linode-using-terraform/index.md rename to docs/applications/configuration-management/terraform/how-to-deploy-secure-linodes-using-cloud-firewalls-and-terraform/index.md From d532b16dd5026d3586e030deb9b6a8fd26f9bacd Mon Sep 17 00:00:00 2001 From: leslitagordita Date: Wed, 5 Aug 2020 18:56:32 -0400 Subject: [PATCH 04/11] Fix 404 small copy fix --- .../index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/applications/configuration-management/terraform/how-to-deploy-secure-linodes-using-cloud-firewalls-and-terraform/index.md b/docs/applications/configuration-management/terraform/how-to-deploy-secure-linodes-using-cloud-firewalls-and-terraform/index.md index f77018afc7d..be25f450a57 100644 --- a/docs/applications/configuration-management/terraform/how-to-deploy-secure-linodes-using-cloud-firewalls-and-terraform/index.md +++ b/docs/applications/configuration-management/terraform/how-to-deploy-secure-linodes-using-cloud-firewalls-and-terraform/index.md @@ -18,7 +18,7 @@ external_resources: - '[Terraform Linode Provider Official Documentation](https://registry.terraform.io/providers/linode/linode/latest/docs)' --- -Terraform modules allow you to better organize your configuration code and make the code reusable. You can host your Terraform modules on remote version control services, like GitHub, for others to use. The Terraform Module Registry hosts community modules that you can reuse for your own Terraform configurations, or you can publish your own modules for consumption by the Terraform community. +Terraform modules allow you to better organize your configuration code and to distribute and reuse it. You can host your Terraform modules on remote version control services, like GitHub, for others to use. The Terraform Module Registry hosts community modules that you can reuse for your own Terraform configurations, or you can publish your own modules for consumption by the Terraform community. In this guide, you will create a Linode Firewalls module which declares commonly used Cloud Firewall configurations. You will then use the module to create a Linode instance and assign the Linode to the Cloud Firewall. You can adopt the example configurations in this guide to create your own reusable Cloud Firewall configurations. @@ -60,7 +60,7 @@ You can view the files created throughout this tutorial in the [author's GitHub ### Create Your Module's Directory Structure -After completing all the sections in [Create Your Cloud Firewalls Module](/docs/applications/configuration-management/terraform/how-to-create-a-cloud-firewall-and-assign-it-to-a-linode-using-terraform/#create-your-cloud-firewalls-module), you will have the directory structure outlined below. In this section, you will create this directory structure. +After completing all the sections in [Create Your Cloud Firewalls Module](/docs/applications/configuration-management/terraform/how-to-deploy-secure-linodes-using-cloud-firewalls-and-terraform/#create-your-cloud-firewalls-module), you will have the directory structure outlined below. In this section, you will create this directory structure. {{< output >}} main_firewalls/ From bdc15adea13c29be2ca6f9366abe07d1a8b9e099 Mon Sep 17 00:00:00 2001 From: Ryan Syracuse Date: Wed, 12 Aug 2020 15:20:50 -0400 Subject: [PATCH 05/11] Remove whitelist language --- .../index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/applications/configuration-management/terraform/how-to-deploy-secure-linodes-using-cloud-firewalls-and-terraform/index.md b/docs/applications/configuration-management/terraform/how-to-deploy-secure-linodes-using-cloud-firewalls-and-terraform/index.md index be25f450a57..647ed528a9f 100644 --- a/docs/applications/configuration-management/terraform/how-to-deploy-secure-linodes-using-cloud-firewalls-and-terraform/index.md +++ b/docs/applications/configuration-management/terraform/how-to-deploy-secure-linodes-using-cloud-firewalls-and-terraform/index.md @@ -23,7 +23,7 @@ Terraform modules allow you to better organize your configuration code and to di In this guide, you will create a Linode Firewalls module which declares commonly used Cloud Firewall configurations. You will then use the module to create a Linode instance and assign the Linode to the Cloud Firewall. You can adopt the example configurations in this guide to create your own reusable Cloud Firewall configurations. {{< disclosure-note "What are Cloud Firewalls?" >}} -Linode Cloud Firewalls is a free service used to create, configure, and add stateful network-based firewalls to Linode services. A Cloud Firewall is independent of the service it is attached to, so you can apply a single Firewall to multiple Linode services. Linode Cloud Firewalls analyze traffic against a set of predefined rules at the network layer and determine if the traffic will be permitted to communicate with the Linode Service it secures. Cloud Firewalls work as a whitelist with an implicit deny rule– it will block all traffic by default and only pass through network traffic that meets the parameters of the configured rules. +Linode Cloud Firewalls is a free service used to create, configure, and add stateful network-based firewalls to Linode services. A Cloud Firewall is independent of the service it is attached to, so you can apply a single Firewall to multiple Linode services. Linode Cloud Firewalls analyze traffic against a set of predefined rules at the network layer and determine if the traffic will be permitted to communicate with the Linode Service it secures. Cloud Firewalls work as a firewall with an implicit deny rule– it will block all traffic by default and only pass through network traffic that meets the parameters of the configured rules. A Cloud Firewall can be configured with Inbound and Outbound rules. Inbound rules limit incoming network connections to a Linode service based on the port(s) and sources you configure. Outbound rules limit the outgoing network connections coming from a Linode service based on the port(s) and destinations you configure. {{}} From b04194fa48c4c3830f8e9ba2b61ce62303eaf508 Mon Sep 17 00:00:00 2001 From: Ryan Syracuse Date: Wed, 12 Aug 2020 16:01:35 -0400 Subject: [PATCH 06/11] allowlist change --- .../index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/applications/configuration-management/terraform/how-to-deploy-secure-linodes-using-cloud-firewalls-and-terraform/index.md b/docs/applications/configuration-management/terraform/how-to-deploy-secure-linodes-using-cloud-firewalls-and-terraform/index.md index 647ed528a9f..d7b3466017c 100644 --- a/docs/applications/configuration-management/terraform/how-to-deploy-secure-linodes-using-cloud-firewalls-and-terraform/index.md +++ b/docs/applications/configuration-management/terraform/how-to-deploy-secure-linodes-using-cloud-firewalls-and-terraform/index.md @@ -23,7 +23,7 @@ Terraform modules allow you to better organize your configuration code and to di In this guide, you will create a Linode Firewalls module which declares commonly used Cloud Firewall configurations. You will then use the module to create a Linode instance and assign the Linode to the Cloud Firewall. You can adopt the example configurations in this guide to create your own reusable Cloud Firewall configurations. {{< disclosure-note "What are Cloud Firewalls?" >}} -Linode Cloud Firewalls is a free service used to create, configure, and add stateful network-based firewalls to Linode services. A Cloud Firewall is independent of the service it is attached to, so you can apply a single Firewall to multiple Linode services. Linode Cloud Firewalls analyze traffic against a set of predefined rules at the network layer and determine if the traffic will be permitted to communicate with the Linode Service it secures. Cloud Firewalls work as a firewall with an implicit deny rule– it will block all traffic by default and only pass through network traffic that meets the parameters of the configured rules. +Linode Cloud Firewalls is a free service used to create, configure, and add stateful network-based firewalls to Linode services. A Cloud Firewall is independent of the service it is attached to, so you can apply a single Firewall to multiple Linode services. Linode Cloud Firewalls analyze traffic against a set of predefined rules at the network layer and determine if the traffic will be permitted to communicate with the Linode Service it secures. Cloud Firewalls work as an allowlist with an implicit deny rule– it will block all traffic by default and only pass through network traffic that meets the parameters of the configured rules. A Cloud Firewall can be configured with Inbound and Outbound rules. Inbound rules limit incoming network connections to a Linode service based on the port(s) and sources you configure. Outbound rules limit the outgoing network connections coming from a Linode service based on the port(s) and destinations you configure. {{}} From ea60ac9a95d3bdb4a075cd23c237d9c5b2d1bc29 Mon Sep 17 00:00:00 2001 From: Ryan Syracuse Date: Mon, 17 Aug 2020 18:57:29 -0400 Subject: [PATCH 07/11] tech/copy edit --- .../index.md | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/applications/configuration-management/terraform/how-to-deploy-secure-linodes-using-cloud-firewalls-and-terraform/index.md b/docs/applications/configuration-management/terraform/how-to-deploy-secure-linodes-using-cloud-firewalls-and-terraform/index.md index d7b3466017c..0f633ee3ddc 100644 --- a/docs/applications/configuration-management/terraform/how-to-deploy-secure-linodes-using-cloud-firewalls-and-terraform/index.md +++ b/docs/applications/configuration-management/terraform/how-to-deploy-secure-linodes-using-cloud-firewalls-and-terraform/index.md @@ -30,7 +30,7 @@ A Cloud Firewall can be configured with Inbound and Outbound rules. Inbound rule ## Before You Begin -1. If you are new to Terraform, read through our [A Beginner's Guide to Terraform](/docs/applications/configuration-management/beginners-guide-to-terraform/) guide to familiarize yourself with key concepts. +1. If you are new to Terraform, read through our [A Beginner's Guide to Terraform](/docs/applications/configuration-management/terraform/beginners-guide-to-terraform/) guide to familiarize yourself with key concepts. 1. See [Create a Terraform Module](/docs/applications/configuration-management/terraform/create-terraform-module/) for a deeper dive into Terraform's standard module structure and other helpful details. @@ -41,14 +41,14 @@ A Cloud Firewall can be configured with Inbound and Outbound rules. Inbound rule 1. [Install Terraform](/docs/applications/configuration-management/how-to-build-your-infrastructure-using-terraform-and-linode/#install-terraform) on your local computer. {{< note >}} -This guide was written using [Terraform version 0.12.29](https://www.hashicorp.com/blog/announcing-terraform-0-12/). +This guide was written using [Terraform version 0.13.0](https://www.hashicorp.com/blog/announcing-the-terraform-0-13-beta/). {{}} 1. Install Git on your computer and complete the steps in the **Configure Git** section of the [Getting Started with Git guide](/docs/development/version-control/how-to-configure-git/#configure-git). ## Create Your Cloud Firewalls Module -The Cloud Firewalls module includes child modules that split up the required resources between the *root module*, an `inbound_ssh` module, a `mysql` module, and a `web-server` module. The root module is the directory that holds the Terraform configuration files that are applied to build your desired infrastructure. These files provide an entry point into any child modules. Each child module uses the `linode_firewall` resource to create reusable Cloud Firewall rules for specific use cases. +The following steps will create the Cloud Firewalls module, which includes several child modules that split up the required resources between the *root module*, an `inbound_ssh` module, a `mysql` module, and a `web-server` module. The root module is the directory that holds the Terraform configuration files that are applied to build your desired infrastructure. These files provide an entry point into any child modules. Each child module uses the `linode_firewall` resource to create reusable Cloud Firewall rules for specific use cases. {{< note >}} You can apply up to three Cloud Firewalls per Linode instance. @@ -60,7 +60,7 @@ You can view the files created throughout this tutorial in the [author's GitHub ### Create Your Module's Directory Structure -After completing all the sections in [Create Your Cloud Firewalls Module](/docs/applications/configuration-management/terraform/how-to-deploy-secure-linodes-using-cloud-firewalls-and-terraform/#create-your-cloud-firewalls-module), you will have the directory structure outlined below. In this section, you will create this directory structure. +In this section, you will create the directory structure outlined below, which will contain the module and child module configuration files that you will create in later steps. {{< output >}} main_firewalls/ @@ -122,7 +122,7 @@ resource "linode_firewall" "ssh_inbound" { - The `linodes` argument expects a list of Linode IDs. When a Linode ID is passed to the `linodes` argument, the `inbound_ssh` firewall will be assigned to it. - The arguments `label`, `tags`, and `linodes` make use of [input variables](https://www.terraform.io/docs/configuration/variables.html), which allow these values to be customized when using the module for your resource configurations. -1. Create the `variables.tf` file to declare the `inbout_ssh` module's input variables. Copy and save the contents of the example below. +1. Create the `variables.tf` file to declare the `inbound_ssh` module's input variables. Copy and save the contents of the example below. {{< file "~/main_firewalls/inbound_ssh/variables.tf">}} variable "linodes" { @@ -148,7 +148,7 @@ variable "tags" { ### Create the MySQL Child Module -The `mysql` child module creates a Cloud Firewall with an inbound rule commonly suited for client connections to a MySQL server. The inbound rule allows `TCP` connections to port `3306`. The `addressses` argument accepts in input variable so that it can be customized to restrict access to a specific IP address(es) or CIDR block. +The `mysql` child module creates a Cloud Firewall with an inbound rule commonly suited for client connections to a MySQL database server. The inbound rule allows `TCP` connections to port `3306`. The `addressses` argument accepts an input variable so that it can be customized to restrict access to a specific IP address(es) or CIDR block. 1. Using your preferred text editor, create the `inbound_ssh` module's `main.tf` file. Copy and save the contents of the example below. @@ -170,7 +170,7 @@ resource "linode_firewall" "mysql" { - The `linodes` argument expects a list of Linode IDs. When a Linode ID is passed to the `linodes` argument, the `mysql` firewall will be assigned to it. - The arguments `label`, `tags`, `linodes`, and `addresses` make use of [input variables](https://www.terraform.io/docs/configuration/variables.html), which allow these values to be customized when using the module for your resource configurations. -1. Create the `variables.tf` file to declare the `inbout_ssh` module's input variables. Copy and save the contents of the example below. +1. Create the `variables.tf` file to declare the `inbound_ssh` module's input variables. Copy and save the contents of the example below. {{< file "~/main_firewalls/mysql/variables.tf">}} variable "linodes" { @@ -311,21 +311,21 @@ resource "linode_instance" "linode_base" { - The `locals` block declares a local variable `key` whose value will be provided by an input variable. The `linode_ids` local variable is used by the `web_server` module instance in the next block to retrieve the Linode ids for the Linodes to be assigned to the Cloud Firewall that will be created. - The `module "firewalls_web"` block creates an instance of the `web_server` child module, which when applied will create a new Cloud Firewall with the configurations provided by the child module and input variable values you will provide in a later step. - The `source` argument provides the location of the child module’s source code and is required whenever you create an instance of a module. + - The `source` argument provides the location of the child module’s source code and is required whenever you create an instance of a module. - All other arguments are determined by the child module. Since the `web_server` child module exposes the `firewall_label`, `tags`, and `linodes` values must be provided for them. Input variables are used in the root module to make it reusable. Depending on the child module that you are using, and the label you'd like to assign to the Cloud Firewall, you should replace the key value for the `var.firewall_label_map["web"]`. Refer to the `variables.tf` file for details. + - All other arguments are determined by the child module. Since the `web_server` child module exposes the `firewall_label`, `tags`, and `linodes`, values must be provided for them. Input variables are used in the root module to make it reusable. Depending on the child module that you are using, and the label you'd like to assign to the Cloud Firewall, you should replace the key value for the `var.firewall_label_map["web"]`. Refer to the `variables.tf` file for details. - The `linodes` argument retrieves its value from the local variable defined in the previous block. + - The `linodes` argument retrieves its value from the local variable defined in the previous block. - The `linode_sshkey` resource will create Linode SSH Keys tied to your Linode account. These keys can be reused for future Linode deployments once the resource has been created. - `ssh_key = chomp(file(local.key))` uses Terraform’s built-in function `file()` to provide a local file path to your public SSH key’s location. The location of the file path is the value of the local variable `key`. The `chomp()` built-in function removes trailing new lines from the SSH key. + - `ssh_key = chomp(file(local.key))` uses Terraform’s built-in function `file()` to provide a local file path to your public SSH key’s location. The location of the file path is the value of the local variable `key`. The `chomp()` built-in function removes trailing new lines from the SSH key. - The `linode_instance` resource creates two Linode instances with configurations provided by its arguments. - The `count` argument controls how many Linode instances will be created with the configurations provided in the resource block's arguments. + - The `count` argument controls how many Linode instances will be created with the configurations provided in the resource block's arguments. - Since Linode labels must be unique, the `label` argument will create a label based on a value provided to the `var.label` input variable and the index number representing the Linode instance that is created. + - Since Linode labels must be unique, the `label` argument will create a label based on a value provided to the `var.label` input variable and the index number representing the Linode instance that is created. - The `authorized_keys` argument uses the SSH public key provided by the `linode_sshkey` resource in the previous resource block. From c6008b11c3a13e294ff00353dd55365d78d0a3a3 Mon Sep 17 00:00:00 2001 From: Ryan Syracuse Date: Tue, 18 Aug 2020 12:13:32 -0400 Subject: [PATCH 08/11] copy fix --- .../index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/applications/configuration-management/terraform/how-to-deploy-secure-linodes-using-cloud-firewalls-and-terraform/index.md b/docs/applications/configuration-management/terraform/how-to-deploy-secure-linodes-using-cloud-firewalls-and-terraform/index.md index 0f633ee3ddc..eae035faa1d 100644 --- a/docs/applications/configuration-management/terraform/how-to-deploy-secure-linodes-using-cloud-firewalls-and-terraform/index.md +++ b/docs/applications/configuration-management/terraform/how-to-deploy-secure-linodes-using-cloud-firewalls-and-terraform/index.md @@ -34,7 +34,7 @@ A Cloud Firewall can be configured with Inbound and Outbound rules. Inbound rule 1. See [Create a Terraform Module](/docs/applications/configuration-management/terraform/create-terraform-module/) for a deeper dive into Terraform's standard module structure and other helpful details. -1. You need a [Linode’s API v4](https://developers.linode.com/api/v4) personal access token to use with Terraform. This token will allow you to create, update, and destroy Linode resources. Follow the [Getting Started with the Linode API](/docs/platform/api/getting-started-with-the-linode-api-new-manager/#get-an-access-token) to get a token. +1. You need a [Linode API v4](https://developers.linode.com/api/v4) personal access token to use with Terraform. This token will allow you to create, update, and destroy Linode resources. Follow the [Getting Started with the Linode API](/docs/platform/api/getting-started-with-the-linode-api-new-manager/#get-an-access-token) guide for steps to create a token. {{< note >}}When you create a personal access token ensure that you set **Read/Write** access permissions for Linode instances and Cloud Firewalls. {{}} From 1cdf777128b587c9e6379ecb0988644633081b0a Mon Sep 17 00:00:00 2001 From: Ryan Syracuse Date: Wed, 19 Aug 2020 12:20:10 -0400 Subject: [PATCH 09/11] dictionary update --- ci/vale/dictionary.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ci/vale/dictionary.txt b/ci/vale/dictionary.txt index 5d5f2b3bec9..6c51c0af9a2 100644 --- a/ci/vale/dictionary.txt +++ b/ci/vale/dictionary.txt @@ -22,6 +22,8 @@ alef alexey alives allmasquerade +allowlist +allowlisting alphanumerics amavis amavisd From 012ad9d676a840fb05f5dc04d4d9c3b8c6076370 Mon Sep 17 00:00:00 2001 From: leslitagordita Date: Tue, 25 Aug 2020 14:52:51 -0400 Subject: [PATCH 10/11] Review fixes --- .../index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/applications/configuration-management/terraform/how-to-deploy-secure-linodes-using-cloud-firewalls-and-terraform/index.md b/docs/applications/configuration-management/terraform/how-to-deploy-secure-linodes-using-cloud-firewalls-and-terraform/index.md index eae035faa1d..afe76d65813 100644 --- a/docs/applications/configuration-management/terraform/how-to-deploy-secure-linodes-using-cloud-firewalls-and-terraform/index.md +++ b/docs/applications/configuration-management/terraform/how-to-deploy-secure-linodes-using-cloud-firewalls-and-terraform/index.md @@ -223,7 +223,7 @@ resource "linode_firewall" "web_server" { addresses = ["0.0.0.0/0"] } - inbound { + inbound { protocol = "TCP" ports = ["443"] addresses = ["0.0.0.0/0"] @@ -269,7 +269,7 @@ variable "tags" { ### Create the Root Module -Now that all the Cloud Firewalls child modules have been created, you can create your root module. The root module is in charge of defining the infrastructure to be built by Terraform. The root module has access to all the child modules and can make use of all or none of them. In this section, you will create a root module that can create a Cloud Firewall using the rules defined in the `web_server` child module. It also creates two Linode instance and assigns the Cloud Firewall to both Linode instances. +Now that all the Cloud Firewalls child modules have been created, you can create your root module. The root module is in charge of defining the infrastructure to be built by Terraform. The root module has access to all the child modules and can make use of all or none of them. In this section, you will create a root module that can create a Cloud Firewall using the rules defined in the `web_server` child module. It also creates two Linode instances and assigns the Cloud Firewall to both Linode instances. 1. Using your preferred text editor, create the root module's `main.tf` file. Copy and save the contents of the example below. From 7fca66175ad36edd7b83cb97a98a201273b8f805 Mon Sep 17 00:00:00 2001 From: leslitagordita Date: Tue, 25 Aug 2020 15:02:58 -0400 Subject: [PATCH 11/11] Add Terraform 0.13 provider stanza to main config files --- .../index.md | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/docs/applications/configuration-management/terraform/how-to-deploy-secure-linodes-using-cloud-firewalls-and-terraform/index.md b/docs/applications/configuration-management/terraform/how-to-deploy-secure-linodes-using-cloud-firewalls-and-terraform/index.md index afe76d65813..551b6d1404a 100644 --- a/docs/applications/configuration-management/terraform/how-to-deploy-secure-linodes-using-cloud-firewalls-and-terraform/index.md +++ b/docs/applications/configuration-management/terraform/how-to-deploy-secure-linodes-using-cloud-firewalls-and-terraform/index.md @@ -41,7 +41,7 @@ A Cloud Firewall can be configured with Inbound and Outbound rules. Inbound rule 1. [Install Terraform](/docs/applications/configuration-management/how-to-build-your-infrastructure-using-terraform-and-linode/#install-terraform) on your local computer. {{< note >}} -This guide was written using [Terraform version 0.13.0](https://www.hashicorp.com/blog/announcing-the-terraform-0-13-beta/). +This guide was written using [Terraform version 0.13.0](https://github.com/hashicorp/terraform/releases). {{}} 1. Install Git on your computer and complete the steps in the **Configure Git** section of the [Getting Started with Git guide](/docs/development/version-control/how-to-configure-git/#configure-git). @@ -104,6 +104,15 @@ When applied to a Terraform configuration, the `inbound_ssh` module will create 1. Using your preferred text editor, create the `inbound_ssh` module's `main.tf` file. Copy and save the contents of the example below. {{< file "~/main_firewalls/inbound_ssh/main.tf">}} +terraform { + required_providers { + linode = { + source = "terraform-providers/linode" + } + } + required_version = ">= 0.13" +} + resource "linode_firewall" "ssh_inbound" { label = var.firewall_label tags = var.tags @@ -153,6 +162,15 @@ The `mysql` child module creates a Cloud Firewall with an inbound rule commonly 1. Using your preferred text editor, create the `inbound_ssh` module's `main.tf` file. Copy and save the contents of the example below. {{< file "~/main_firewalls/mysql/main.tf">}} +terraform { + required_providers { + linode = { + source = "terraform-providers/linode" + } + } + required_version = ">= 0.13" +} + resource "linode_firewall" "mysql" { label = var.firewall_label tags = var.tags @@ -207,6 +225,15 @@ The `web_server` child module, when applied, creates a Cloud Firewall with inbou 1. Using your preferred text editor, create the `web_server` module's `main.tf` file. Copy and save the contents of the example below. {{< file "~/main_firewalls/web_server/main.tf">}} +terraform { + required_providers { + linode = { + source = "terraform-providers/linode" + } + } + required_version = ">= 0.13" +} + resource "linode_firewall" "web_server" { label = var.firewall_label tags = var.tags @@ -274,6 +301,15 @@ Now that all the Cloud Firewalls child modules have been created, you can create 1. Using your preferred text editor, create the root module's `main.tf` file. Copy and save the contents of the example below. {{< file "~/main_firewalls/main.tf">}} +terraform { + required_providers { + linode = { + source = "terraform-providers/linode" + } + } + required_version = ">= 0.13" +} + provider "linode" { api_version = "v4beta" token = var.token