terraform content cleanup/rewrite

- add missing h1s
- remove `/terraform` pathPrefix from internal links in md
- use <DirectoryListing/> where appropriate
- re-order sidenav
- add missing languages to code blocks
- convert getting started into index
This commit is contained in:
Adam Schwartz 2020-09-10 18:32:31 -04:00
parent 7d4ad0e08f
commit 7d7c4f43b9
15 changed files with 179 additions and 161 deletions

View file

@ -1,15 +1,11 @@
---
title: Importing Cloudflare Resources
alwaysopen: true
weight: 20
---
# Importing Cloudflare resources
An important point to understand about Terraform is that it is only able to manage configuration that it created, or was explicitly told about after the fact. The reason for this limitation is that Terraform expects to be authoritative for the resources its manages. It relies on 2 types of files to understand what resources it controls, and what state they are in. This is how it determines when and how to make changes.
1. A [configuration file](https://www.terraform.io/docs/configuration/index.html) (ending in .tf) that defines the configuration of resources for Terraform to manage. This is what you worked with in the tutorial steps.
1. A [configuration file](https://www.terraform.io/docs/configuration/index.html) (ending in .tf) that defines the configuration of resources for Terraform to manage. This is what you worked with in the tutorial steps.
2. A local [state file](https://www.terraform.io/docs/state/) that maps the resource names defined in your configuration file, e.g., cloudflare_load_balancer.www-lb to the resources that exist in Cloudflare.
When Terraform makes calls to Cloudflare's API to create new resources as illustrated in the [tutorial](/terraform/tutorial), it persists those IDs to a state file. By default, the `terraform.tfstate` file in your directory is used, but this can also be a [remote location](https://www.terraform.io/docs/state/remote.html). These IDs are later looked up and refreshed when you call `terraform plan` and `terraform apply`.
When Terraform makes calls to Cloudflare's API to create new resources as illustrated in the [tutorial](/tutorial), it persists those IDs to a state file. By default, the `terraform.tfstate` file in your directory is used, but this can also be a [remote location](https://www.terraform.io/docs/state/remote.html). These IDs are later looked up and refreshed when you call `terraform plan` and `terraform apply`.
If you've configured Cloudflare through other means, e.g., by logging into the Cloudflare Dashboard or making `curl` calls to api.cloudflare.com, Terraform does not (yet) have these resource IDs in the state file. To manage this preexisting configuration you will need to first i) reproduce the configuration in your config file and; ii) import resources one-by-one by providing their IDs and resource names.
@ -49,7 +45,7 @@ The list of supported resources currently are:
* [zone](https://www.terraform.io/docs/providers/cloudflare/r/zone.html)
* [zone_lockdown](https://www.terraform.io/docs/providers/cloudflare/r/zone_lockdown.html)
* [zone_settings_override](https://www.terraform.io/docs/providers/cloudflare/r/zone_settings_override.html)
## Importing existing Cloudflare resources
As mentioned, to start managing existing Cloudflare resources in Terraform, e.g., DNS records, you need two things:
@ -59,7 +55,8 @@ As mentioned, to start managing existing Cloudflare resources in Terraform, e.g.
### 1. Generate Terraform Configuration with Cf-Terraforming
If you don't have a Terraform configuration file defined, all you need is the provider blocked defined as follows:
```
```tf
provider 'cloudflare' {
# Cloudflare email saved in $CLOUDFLARE_EMAIL
# Cloudflare API key saved in $CLOUDFLARE_TOKEN
@ -70,14 +67,14 @@ Remember to keep your credentials saved in environment variables or terraform au
We start by making a call to Cf-Terraforming to enumerate the Terraform configuration for the DNS records for the zone we want to manage with Terraform.
Note: The below command assumes you run the tool from `{GOPATH}/src/github.com/cloudflare/cf-terraforming`. If pulled with `go get` and if `$GOPATH/bin` is in your `$PATH` you should be able to just run the tool with `$ cf-terraforming <parameters>`.
Note: The below command assumes you run the tool from `{GOPATH}/src/github.com/cloudflare/cf-terraforming`. If pulled with `go get` and if `$GOPATH/bin` is in your `$PATH` you should be able to just run the tool with `$ cf-terraforming <parameters>`.
```
$ go run cmd/cf-terraforming/main.go --email $CLOUDFLARE_EMAIL --key $CLOUDFLARE_TOKEN -z 1109d899a5ff5fd74bc01e581693685a record > importing-example.tf
```
If output to standard out, the result would look like the below. In this case we directly imported the configuration into our Terraform configuration file `importing-state.tf`.
```
```tf
resource "cloudflare_record" "mitigateddos_net_mitigateddos_net" {
domain = "mitigateddos.net"
@ -125,7 +122,7 @@ resource "cloudflare_record" "mitigateddos_net_a123_mitigateddos_net_2" {
Calling terraform `plan` now will attempt to create these resources as if they didn't exist which isn't exactly what we desire.
```
```sh
$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
@ -214,7 +211,7 @@ Soon cf-terraforming will also allow you to import tfstate for the same resource
Hint: If you run cf-terraforming with `-v` to stdout, we will log the resource ids in Cloudflare which can help with running Terraform `import`.
```
```sh
$ terraform import cloudflare_record.mitigateddos_net_mitigateddos_net mitigateddos.net/6702ceac85496311b1fa86a4ecc2fd47
cloudflare_record.mitigateddos_net_mitigateddos_net: Importing from ID "mitigateddos.net/6702ceac85496311b1fa86a4ecc2fd47"...
cloudflare_record.mitigateddos_net_mitigateddos_net: Import complete!
@ -262,7 +259,7 @@ your Terraform state and will henceforth be managed by Terraform.
Now when we run `terraform plan` it no longer wants to (re-)create the above records.
```
```sh
$ terraform plan | grep changes
No changes. Infrastructure is up-to-date.
```

View file

@ -1,15 +1,7 @@
---
title: Advanced Topics
alwaysopen: true
weight: 50
hidden: false
showNew: false
order: 3
---
### [Importing Cloudflare Resources](/terraform/advanced-topics/importing-cloudflare-resources/)
* Working with existing Cloudflare configuration
# Advanced topics
### [Provider Customization](/terraform/advanced-topics/provider-customization/)
* Customizing the Cloudflare Terraform provider, e.g., adjusting speed and backoff of API calls
<DirectoryListing path="/advanced-topics"/>

View file

@ -1,31 +1,24 @@
---
title: Provider Customization
weight: 40
---
# Provider customization
Terraform communicates with cloud and edge provider APIs such as Cloudflare through modules known as "providers". These providers are [installed automatically](/terraform/tutorial/hello-world/#2-initializing-terraform-and-the-cloudflare-provider) when you run `terraform init` in a directory that has a `.tf` file containing a provider. Typically, the only required parameters to the provider are what's requried to authenticate. In many cases, however, it may make sense to customize the provider to your needs. Below we examine some of the [optional settings](https://www.terraform.io/docs/providers/cloudflare/#argument-reference) that can be passed to the Cloudflare Provider.
Terraform communicates with cloud and edge provider APIs such as Cloudflare through modules known as "providers". These providers are [installed automatically](/tutorial/hello-world/#2-initializing-terraform-and-the-cloudflare-provider) when you run `terraform init` in a directory that has a `.tf` file containing a provider. Typically, the only required parameters to the provider are what's requried to authenticate. In many cases, however, it may make sense to customize the provider to your needs. Below we examine some of the [optional settings](https://www.terraform.io/docs/providers/cloudflare/#argument-reference) that can be passed to the Cloudflare Provider.
## Adjusting the default Cloudflare provider settings
<Aside>
The examples below build on the <a href="https://developers.cloudflare.com/terraform/tutorial/">Cloudflare Terraform Tutorial</a>.
The examples below build on the [Cloudflare Terraform tutorial](/tutorial).
</Aside>
The Cloudflare Terraform provider can be customized through the use of configuration parameters, specified either in your `.tf` configuration files or via environment variables, e.g., `$CLOUDFLARE_RPS`. Using environment variables may make sense when running Terraform from a CI/CD system, or when the change is temporary and doesn't need to be persisted in your configuration history.
### i. Increasing the frequency of API requests
The `api.cloudflare.com` endpoint has a default rate limit of 1200 calls per 5 minute period (as of time of writing; see rate limiting section under [Requests](https://api.cloudflare.com/#getting-started-requests) for updates). Enterprise customers may request this limit be increased by contacting their Customer Success Manager.
Even with an updated rate limit, Terraform will need to stay under this threshold otherwise the Cloudflare API will respond with `HTTP 429/Too Many Requests` responses. When it does, the Cloudflare Terraform provider will back off before retrying. All of these figures can be customized, as shown below.
```
```sh
$ export CLOUDFLARE_RPS=
$ export CLOUDFLARE_API_CLIENT_LOGGING=true
```

View file

@ -1,5 +0,0 @@
---
title: Sharing State
---
_TBD_

View file

@ -1,9 +0,0 @@
---
title: Getting Started
alwaysopen: true
weight: 10
---
See [Installing Terraform](/terraform/getting-started/installing/).
Report Terraform config issues via [Github](https://github.com/terraform-providers/terraform-provider-cloudflare/issues).

View file

@ -1,7 +1,27 @@
---
title: Welcome
order: 0
type: overview
---
# Welcome
<ContentColumn>
TODO...
# Cloudflare Terraform documentation
Configure Cloudflare using HashiCorp's “Infrastructure as Code” tool, Terraform.
With Cloudflares Terraform provider, you can manage your edge using the same familiar tools you use to automate the rest of your infrastructure. Define and store configuration in source code repositories like GitHub, track and version changes over time, and roll back when needed—all without needing to learn the Cloudflare APIs.
--------------------------------
## Installing
See [Installing Terraform](/installing/).
--------------------------------
## Issues
Report Terraform config issues via [Github](https://github.com/terraform-providers/terraform-provider-cloudflare/issues).
</ContentColumn>

View file

@ -1,16 +1,19 @@
---
title: Installing Terraform
alwaysopen: true
weight: 10
title: Installing
order: 1
---
# Installing Terraform
The installation process for Terraform is extremely simple as it ships as a single binary file. Official instructions for installing Terraform can be found [here](https://www.terraform.io/intro/getting-started/install.html), with some examples provided below for popular operating systems.
--------------------------------
## Mac
The easiest way to install Terraform on macOS is with Homebrew:
```
```sh
$ brew install terraform
==> Downloading https://homebrew.bintray.com/bottles/terraform-0.11.6.sierra.bottle.tar.gz
@ -22,16 +25,18 @@ $ terraform version
Terraform v0.11.6
```
--------------------------------
## Linux
On Linux, you just need to download and place the binary in your $PATH:
```
```sh
$ wget -q https://releases.hashicorp.com/terraform/0.11.6/terraform_0.11.6_linux_amd64.zip
$ unzip terraform_0.11.6_linux_amd64.zip
Archive: terraform_0.11.6_linux_amd64.zip
inflating: terraform
inflating: terraform
$ sudo mv terraform /usr/local/bin/terraform
@ -39,12 +44,15 @@ $ terraform version
Terraform v0.11.6
```
--------------------------------
## Windows
1. Download the 32 or 64-bit executable from the [Terraform Download](https://www.terraform.io/downloads.html) page.
2. Unzip and place terraform.exe somewhere in your path.
--------------------------------
## Other
Additional installers can be found at https://www.terraform.io/downloads.html.
Additional installers can be found at https://www.terraform.io/downloads.html.

View file

@ -1,17 +1,19 @@
---
title: Step 1 - Hello World
weight: 10
title: 1 Hello World
order: 1
---
# Hello World
Let's say you have a web server for your domain thats accessible on 203.0.113.10. You just signed up your domain, example.com, on Cloudflare and want to manage everything in Terraform.
This tutorial step shows you how to get started. Before you do so, make sure you've completed the [Getting Started](/terraform/getting-started/) steps.
This tutorial step shows you how to get started. Before you do so, make sure you've completed the [Getting Started](/getting-started/) steps.
## 1. Defining your first Terraform config file
First we'll create a initial Terraform config file. Any files ending in `.tf` will be processed by Terraform. As you configuration gets more complex you'll want to split the config into separate files and modules, but for now we'll proceed with a single file:
```bash
```sh
$ cat > cloudflare.tf <<'EOF'
provider "cloudflare" {
email = "you@example.com"
@ -36,7 +38,7 @@ EOF
Now that youve created your basic configuration in HCL, lets initialize Terraform and ask it to apply the configuration to Cloudflare.
```
```sh
$ terraform init
Initializing provider plugins...
@ -66,7 +68,7 @@ commands will detect it and remind you to do so if necessary.
When you run terraform init, any plugins required, such as the Cloudflare Terraform provider, are automatically downloaded and saved locally to a .terraform directory:
```
```sh
$ find .terraform/
.terraform/
.terraform//plugins
@ -78,7 +80,7 @@ $ find .terraform/
## 3. Reviewing the execution plan
With the Cloudflare provider installed, lets ask Terraform what changes its planning to make to your Cloudflare account so it matches the configuration you previously defined:
```
```sh
$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
@ -124,7 +126,7 @@ As you can see in the above “execution plan”, Terraform is going to create a
The plan command is important, as it allows you to preview the changes for accuracy before actually making them. Once youre comfortable with the execution plan, its time to apply it:
```
```sh
$ terraform apply --auto-approve
cloudflare_record.www: Creating...
created_on: "" => "<computed>"
@ -154,7 +156,7 @@ Logging back into the Cloudflare Dashboard and selecting the DNS tab, I can see
If youd like to see the full results returned from the API call (including the default values that you didnt specify but let Terraform compute), you can run terraform show:
```
```sh
$ terraform show
cloudflare_record.www:
id = c38d3103767284e7cd14d5dad3ab8668
@ -176,8 +178,7 @@ cloudflare_record.www:
zone_id = e2e6391340be87a3726f91fc4148b122
```
```
```sh
$ curl https://www.example.com
Hello, this is 203.0.113.10!
```

View file

@ -1,46 +1,50 @@
---
title: Tutorial
alwaysopen: true
weight: 15
order: 2
---
_This tutorial assumes that you have installed Terraform. If you havent, please visit the Terraform Downloads page._
# Tutorial
<Aside>
This tutorial assumes that you have [installed Terraform](/installing).
</Aside>
Each example builds on the last, so you should start from the top. Here are the topics and resources covered per tutorial step:
### [Step 1 - Hello World](/terraform/tutorial/hello-world/)
## [1 Hello World](/tutorial/hello-world/)
* Brief intro
* Introduction of terraform init, plan, apply, and show.
* Resources covered: DNS
- Brief intro
- Introduction of terraform init, plan, apply, and show.
- Resources covered: DNS
### [Step 2 - Tracking your history](/terraform/tutorial/source-control/)
## [2 Tracking your history](/tutorial/source-control/)
* Storing Cloudflare configuration in source control
- Storing Cloudflare configuration in source control
### [Step 3 - HTTPS all the things](/terraform/tutorial/zone-settings/)
## [3 HTTPS all the things](/tutorial/zone-settings/)
* Modifying zone settings
* Resources covered: [zone settings override](https://www.terraform.io/docs/providers/cloudflare/r/zone_settings_override.html)
- Modifying zone settings
- Resources covered: [zone settings override](https://www.terraform.io/docs/providers/cloudflare/r/zone_settings_override.html)
### [Step 4 - Woah, slow down there](/terraform/tutorial/rate-limit/)
## [4 Woah, slow down there](/tutorial/rate-limit/)
* Adding rate limiting rules
* Resource covered: [rate limit](https://www.terraform.io/docs/providers/cloudflare/r/rate_limit.html)
- Adding rate limiting rules
- Resource covered: [rate limit](https://www.terraform.io/docs/providers/cloudflare/r/rate_limit.html)
### [Step 5 - Sharing the load](/terraform/tutorial/load-balance/)
## [5 Sharing the load](/tutorial/load-balance/)
* Adding load balancing rules
* Resources covered: [load balancer](https://www.terraform.io/docs/providers/cloudflare/r/load_balancer.html), [load balancer pool](https://www.terraform.io/docs/providers/cloudflare/r/load_balancer_pool.html), [load balancer monitor](https://www.terraform.io/docs/providers/cloudflare/r/load_balancer_monitor.html)
- Adding load balancing rules
- Resources covered: [load balancer](https://www.terraform.io/docs/providers/cloudflare/r/load_balancer.html), [load balancer pool](https://www.terraform.io/docs/providers/cloudflare/r/load_balancer_pool.html), [load balancer monitor](https://www.terraform.io/docs/providers/cloudflare/r/load_balancer_monitor.html)
### [Step 6 - Making some exceptions](/terraform/tutorial/page-rules/)
* Add page rule
* Resources covered: [page rules](https://www.terraform.io/docs/providers/cloudflare/r/page_rule.html)
## [6 Making some exceptions](/tutorial/page-rules/)
* WAF off for specific path: /abuse-report
* Forwarding URL (301) from blog to example.com/blog
- Add page rule
- Resources covered: [page rules](https://www.terraform.io/docs/providers/cloudflare/r/page_rule.html)
- WAF off for specific path: /abuse-report
- Forwarding URL (301) from blog to example.com/blog
### [Step 7 - On final thought, let's roll some of that back](/terraform/tutorial/roll-back/)
## [7 On final thought, lets roll some of that back](/tutorial/roll-back/)
* Reviewing change history
* Rolling back changes
- Reviewing change history
- Rolling back changes

View file

@ -1,10 +1,11 @@
---
title: Step 5 - Sharing the load
weight: 50
title: 5 Sharing the load
order: 5
---
# Sharing the load
Thanks to the rate limiting set up in the [previous step](/terraform/tutorial/rate-limit), our login page is protected against credential brute force attacks. Now it's time to focus on performance and reliability. Imagine organic traffic has grown, and is increasingly global. It's time to spread these requests over multiple data centers.
Thanks to the rate limiting set up in the [previous step](/tutorial/rate-limit), our login page is protected against credential brute force attacks. Now it's time to focus on performance and reliability. Imagine organic traffic has grown, and is increasingly global. It's time to spread these requests over multiple data centers.
In this tutorial step, we'll add a second origin for some basic round robining, and then use the [Cloudflare Load Balancing](https://www.cloudflare.com/load-balancing/) product to fail traffic over as needed. We'll then enhance our load balancing configuration through the use of "geo steering" to serve results from an origin server that is geographically closest to your end users.
@ -12,7 +13,7 @@ In this tutorial step, we'll add a second origin for some basic round robining,
To get started, we'll add a DNS record for a second web server, which is located in Asia. The IP address for this server is 198.51.100.15.
```
```sh
$ git checkout -b step5-loadbalance
Switched to a new branch 'step5-loadbalance'
@ -33,7 +34,7 @@ Note that while the name of the _resource_ is different as Terraform resources o
Below we'll check the `terraform plan`, merge and apply the changes.
```
```sh
$ terraform plan | grep -v "<computed>"
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
@ -86,7 +87,7 @@ Fast-forward
Let's add the second DNS record for www.example.com:
```
```sh
$ terraform apply --auto-approve
cloudflare_record.www: Refreshing state... (ID: c38d3103767284e7cd14d5dad3ab8668)
cloudflare_zone_settings_override.example-com-settings: Refreshing state... (ID: e2e6491340be87a3726f91fc4148b126)
@ -111,7 +112,7 @@ Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
With the second DNS record in place, let's try making some requests to see where the traffic is served from:
```
```sh
$ for curl https://www.example.com
Hello, this is 203.0.113.10!
@ -144,7 +145,7 @@ As described in the [load balancing tutorial](https://support.cloudflare.com/hc/
To monitor our origins we're going to create a basic health check that makes a GET request to each origin on the URL https://www.example.com. If the origin returns the `200/OK` status code within 5 seconds, we'll consider it healthy. If it fails to do so three (3) times in a row, we'll consider it unhealthy. This health check will be run once per minute from several regions, and send an email notification to you@example.com if any failures are detected.
```
```sh
$ git checkout step5-loadbalance
Switched to branch 'step5-loadbalance'
@ -169,7 +170,7 @@ We will call our pool "www-servers" and add two origins to it: `www-us` (203.0.1
Note that we reference the monitor we added in the last step. When applying this confirmation, Terraform will figure out that it first needs to create the monitor so that it can look up the ID and provide to the pool we wish to create.
```
```sh
$ cat >> cloudflare.tf <<'EOF'
resource "cloudflare_load_balancer_pool" "www-servers" {
name = "www-servers"
@ -194,7 +195,7 @@ EOF
Note that when you create a load balancer (LB), it will [replace any existing DNS records with the same name](https://support.cloudflare.com/hc/en-us/articles/115004954407-How-Does-a-Load-Balancer-Interact-with-Existing-DNS-Records-). For example, when we create the "www.example.com" LB below, it will supersede the two www DNS records that you have previously defined. One benefit of leaving this DNS records in place is that if you temporarily disable load balancing, connections to this hostname will still be possible as shown in Step #2 above.
```
```sh
$ cat >> cloudflare.tf <<'EOF'
resource "cloudflare_load_balancer" "www-lb" {
zone = "example.com"
@ -211,7 +212,7 @@ EOF
As usual, we take a look at the proposed plan before we apply any changes:
```
```sh
$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
@ -296,7 +297,7 @@ can't guarantee that exactly these actions will be performed if
The plan looks good so let's go ahead, merge it in, and apply it.
```
```sh
$ git add cloudflare.tf
$ git commit -m "Step 5 - Create load balancer (LB) monitor, LB pool, and LB."
[step5-loadbalance bc9aa9a] Step 5 - Create load balancer (LB) monitor, LB pool, and LB.
@ -367,7 +368,7 @@ Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
With load balancing in place, let's run those `curl` requests again to see where the traffic is served from:
```
```sh
$ for i in {1..4}; do curl https://www.example.com && sleep 5; done
Hello, this is 198.51.100.15!
@ -378,4 +379,4 @@ Hello, this is 198.51.100.15!
Hello, this is 203.0.113.10!
```
Great, we're now seeing each request load balanced evenly across the two origins we defined.
Great, we're now seeing each request load balanced evenly across the two origins we defined.

View file

@ -1,9 +1,11 @@
---
title: Step 6 - Making some exceptions
weight: 60
title: 6 Making some exceptions
order: 6
---
In [step 3](/terraform/tutorial/zone-settings) we configured zone settings that apply to all of example.com. In this step we're going to add an exception to these settings by using [Page Rules](https://www.cloudflare.com/features-page-rules/).
# Making some exceptions
In [step 3](/tutorial/zone-settings) we configured zone settings that apply to all of example.com. In this step we're going to add an exception to these settings by using [Page Rules](https://www.cloudflare.com/features-page-rules/).
Specifically, we're going to turn increase the security level for a URL we know is expensive to render (and cannot be cached): https://www.example.com/expensive-db-call. Additionally, we're going to add a redirect from the previous URL we used to host this page.
@ -11,7 +13,7 @@ Specifically, we're going to turn increase the security level for a URL we know
As usual we'll create a new branch and append our configuration.
```
```sh
$ git checkout -b step6-pagerule
Switched to a new branch 'step6-pagerule'
@ -44,7 +46,8 @@ EOF
## 2. Preview and merge the changes
You know the drill: preview the changes Terraform is going to make and then merge them into the master branch.
```
```sh
$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
@ -115,7 +118,7 @@ $ git commit -m "Step 6 - Add two Page Rules."
$ git checkout master
Switched to branch 'master'
$ git merge step6-pagerule
$ git merge step6-pagerule
Updating 7a2ac34..d4fec16
Fast-forward
cloudflare.tf | 23 +++++++++++++++++++++++
@ -125,14 +128,15 @@ Fast-forward
## 3. Apply and verify the changes
First we'll test requesting the (now missing) old location of the expensive-to-render page.
```
```sh
$ curl -vso /dev/null https://www.example.com/old-location.php 2>&1 | grep "< HTTP\|Location"
< HTTP/1.1 404 Not Found
```
As expected, it can't be found. Let's apply the Page Rules, including the redirect that should fix this error.
```
```sh
$ terraform apply --auto-approve
cloudflare_record.www-asia: Refreshing state... (ID: fda39d8c9bf909132e82a36bab992864)
cloudflare_load_balancer_monitor.get-root-https: Refreshing state... (ID: 4238142473fcd48e89ef1964be72e3e0)
@ -175,7 +179,7 @@ Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
With the Page Rules in place, let's try that call again, along with the I'm Under Attack Mode test:
```
```sh
$ curl -vso /dev/null https://www.example.com/old-location.php 2>&1 | grep "< HTTP\|Location"
< HTTP/1.1 301 Moved Permanently
< Location: https://www.upinatoms.com/expensive-db-call
@ -184,4 +188,4 @@ $ curl -vso /dev/null https://www.upinatoms.com/expensive-db-call 2>&1 | grep "<
< HTTP/1.1 503 Service Temporarily Unavailable
```
Great, they work as expected! In the first case the Cloudflare edge responds with a `301` redirecting the browser to the new location. In the second case it initially responds with a `503` (as is consistent with the "I Am Under Attack" mode).
Great, they work as expected! In the first case the Cloudflare edge responds with a `301` redirecting the browser to the new location. In the second case it initially responds with a `503` (as is consistent with the "I Am Under Attack" mode).

View file

@ -1,8 +1,10 @@
---
title: Step 4 - Woah, slow down there
weight: 40
title: 4 Woah, slow down there
order: 4
---
# Woah, slow down there
With our zone settings locked down, and our site starting to get some more attention, it's unfortunately begun attracting some of the less scrupulous characters on the internet. Our server access logs show attempts to brute force our login page at https://www.example.com/login. Let's see what we can do with Cloudflare's [rate limiting product](https://www.cloudflare.com/rate-limiting/) to put a stop to these efforts.
## 1. Create a new branch and append the rate limiting settings
@ -210,7 +212,7 @@ Error: Error applying plan:
* cloudflare_rate_limit.login-limit: error creating rate limit for zone: error from makeRequest: HTTP status 400: content "{\n \"result\": null,\n \"success\": false,\n \"errors\": [\n {\n \"code\": 10021,\n \"message\": \"ratelimit.api.not_entitled.account\"\n }\n ],\n \"messages\": []\n}\n"
```
## 3. Update the rule to ban (not just simulate)
## 3. Update the rule to ban (not just simulate)
After confirming that the rule is triggering as planned in logs (but not yet enforcing), it's time to switch from `simulate` to `ban`:

View file

@ -1,8 +1,10 @@
---
title: Step 7 - On final thought, lets roll some of that back
weight: 70
title: 7 On final thought...
order: 7
---
# On final thought, lets roll some of that back
We've come a long way! Now it's time to tear it all down. Well, maybe just part of it.
Sometimes when you deploy configuration changes you later determine that they need to be rolled back. You could be performance testing a new configuration and want to revert to your previous configuration when done testing. Or maybe you fat-fingered an IP address and brought your entire site down (#hugops).
@ -12,7 +14,8 @@ Either way, if you've determined you want to revert your configuration, all you
## 1. Reviewing your configuration history
Before we figure out how far back in time we want to rollback, let's take a look at our (git) versioned history.
```
```sh
$ git log
commit d4fec164581bec44684a4d59bb80aec1f1da5a6e
Author: Me
@ -68,7 +71,8 @@ Another nice benefit of storing your Cloudflare configuration in git is that you
## 2. Examining specific historical changes
To begin with, let's see what the last change we made was.
```
```sh
$ git show
commit d4fec164581bec44684a4d59bb80aec1f1da5a6e
Author: Me
@ -110,10 +114,11 @@ index 0b39450..ef11d8a 100644
```
Now let's look at the past few changes:
```
```sh
$ git log -p -3
...
...
// page rule config from above
...
@ -190,14 +195,15 @@ index 9f25a0c..b92cb6f 100644
+}
```
## 3. Redeploying the previous configuration
Imagine that shortly after we deployed the Page Rules from [step 6](/terraform/tutorial/page-rules), we got a call from the Product team that manages this page: "The URL was only being used by one customer and is no longer needed, let's drop the security setting and redirect."
Imagine that shortly after we deployed the Page Rules from [step 6](/tutorial/page-rules), we got a call from the Product team that manages this page: "The URL was only being used by one customer and is no longer needed, let's drop the security setting and redirect."
While you could always edit the config file directly and delete those entries, it's easier to let `git` do it for us. To begin with, let's ask git to revert the last commit (without rewriting history).
### i. Revert the branch to the previous commit
```
```sh
$ git revert HEAD~1..HEAD
[master f9a6f7d] Revert "Step 6 - Bug fix."
1 file changed, 1 insertion(+), 1 deletion(-)
@ -208,7 +214,7 @@ Author: Me
Date: Wed Apr 18 23:28:09 2018 -0700
Revert "Step 6 - Add two Page Rules."
This reverts commit d4fec164581bec44684a4d59bb80aec1f1da5a6e.
commit d4fec164581bec44684a4d59bb80aec1f1da5a6e
@ -222,7 +228,7 @@ Date: Wed Apr 18 22:04:52 2018 -0700
As expected, Terraform is indicating it will remove the two Page Rules we created in the previous step.
```
```sh
$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
@ -264,7 +270,7 @@ can't guarantee that exactly these actions will be performed if
The changes look good, so let's ask Terraform to roll our Cloudflare configuration back.
```
```sh
$ terraform apply --auto-approve
cloudflare_page_rule.redirect-to-new-db-page: Refreshing state... (ID: c5c40ff2dc12416b5fe4d0541980c591)
cloudflare_page_rule.increase-security-on-expensive-page: Refreshing state... (ID: 1c13fdb84710c4cc8b11daf7ffcca449)
@ -283,4 +289,4 @@ cloudflare_page_rule.redirect-to-new-db-page: Destruction complete after 1s
Apply complete! Resources: 0 added, 0 changed, 2 destroyed.
```
Two resources destroyed, as expected. We've rolled back to the previous version.
Two resources destroyed, as expected. We've rolled back to the previous version.

View file

@ -1,12 +1,14 @@
---
title: Step 2 - Tracking your history
weight: 20
title: 2 Tracking your history
order: 2
---
In the [first step](/terraform/tutorial/hello-world) of the tutorial, you created and applied some basic Cloudflare configuration. Terraform was able to apply this configuration to your account because you provided your email address and API token at the top of the `cloudflare.tf` file:
# Tracking your history
```
$ head -n4 cloudflare.tf
In the [first step](/tutorial/hello-world) of the tutorial, you created and applied some basic Cloudflare configuration. Terraform was able to apply this configuration to your account because you provided your email address and API token at the top of the `cloudflare.tf` file:
```sh
$ head -n4 cloudflare.tf
provider "cloudflare" {
email = "you@example.com"
token = "your-api-key"
@ -19,11 +21,11 @@ In this step of the tutorial, were going to store your configuration in GitHu
As a good security practice we need to remove your Cloudflare credentials from anything that will be committed to a repository. The Cloudflare Terraform provider supports reading these values from the `CLOUDFLARE_EMAIL` and `CLOUDFLARE_TOKEN` environment variables, so all we need to do is:
```
```sh
$ sed -ie 's/^.*email =.*$/ # email pulled from $CLOUDFLARE_EMAIL/' cloudflare.tf
$ sed -ie 's/^.*token =.*$/ # token pulled from $CLOUDFLARE_TOKEN/' cloudflare.tf
$ head -n4 cloudflare.tf
$ head -n4 cloudflare.tf
provider "cloudflare" {
# email pulled from $CLOUDFLARE_EMAIL
# token pulled from $CLOUDFLARE_TOKEN
@ -37,7 +39,7 @@ Note that you need to leave the empty provider definition in the file, so that T
After completing the above step, it's a good idea to make sure that you can still authenticate to Cloudflare. By running `terraform plan` we can get Terraform to pull the current state (which requires a valid email and API key):
```
```sh
$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
@ -60,7 +62,7 @@ Now that credentials have been removed, it's time to initialize a git repository
First we'll create the GitHub repository to store the config. This can be done via the GitHub UI or with a simple API call:
```
```sh
$ export GITHUB_USER=your-github-user
$ export GITHUB_TOKEN=your-github-token
@ -73,7 +75,7 @@ git@github.com:$GITHUB_USER/cf-config.git
Now we'll initialize a git repository and make our first commit:
```
```sh
$ git init
Initialized empty Git repository in /Users/username/cf-config/.git/
@ -86,11 +88,11 @@ $ git commit -m "Step 2 - Initial commit with webserver definition."
create mode 100644 cloudflare.tf
```
An astute reader may have noticed that we did _not_ commit the `.terraform` directory nor did we commit the `terraform.tfstate` file. The former was not committed because this repository may be used on a different architecture, and the plugins contained in this directory are built for the system on which `terraform init` was run. The latter was not committed as i) it may eventually contain sensitive strings and ii) it is not a good way to keep state in sync, as explained in [Sharing State](/terraform/advanced-topics/sharing-state).
An astute reader may have noticed that we did _not_ commit the `.terraform` directory nor did we commit the `terraform.tfstate` file. The former was not committed because this repository may be used on a different architecture, and the plugins contained in this directory are built for the system on which `terraform init` was run. The latter was not committed as i) it may eventually contain sensitive strings and ii) it is not a good way to keep state in sync, as explained in [Sharing State](/advanced-topics/sharing-state).
To prevent git from bugging us about these files, let's add them to a new .gitignore file, commit it, and push everything to GitHub:
```
```sh
$ cat > .gitignore <<'EOF'
.terraform/
terraform.tfstate*
@ -111,4 +113,4 @@ Writing objects: 100% (6/6), 762 bytes | 0 bytes/s, done.
Total 6 (delta 0), reused 0 (delta 0)
To git@github.com:$GITHUB_USER/cf-config.git
* [new branch] master -> master
```
```

View file

@ -1,8 +1,10 @@
---
title: Step 3 - HTTPS all the things
weight: 30
title: 3 HTTPS all the things
order: 3
---
# HTTPS all the things
Now that you've got a basic website proxied through Cloudflare, it's time to use Terraform to adjust some of the settings on your zone. In this tutorial step we'll configure some optional HTTPS settings, and then push the updated configuration to GitHub for posterity.
We'll use a new git branch for the changes, and then merge it into master before applying. On a team, you might consider using this step as an opportunity for others to review your change before merging and deploying it. Or you may integrate Terraform into your CI/CD system to perform tests automatically using another Cloudflare domain.
@ -11,7 +13,7 @@ We'll use a new git branch for the changes, and then merge it into master before
Here we modify the Terraform configuration to enable the following settings: [TLS 1.3](https://www.cloudflare.com/learning-resources/tls-1-3/), [Always Use HTTPS](https://blog.cloudflare.com/how-to-make-your-site-https-only/), [Strict SSL mode](https://blog.cloudflare.com/introducing-strict-ssl-protecting-against-a-man-in-the-middle-attack-on-origin-traffic/), and the [Cloudflare WAF](https://www.cloudflare.com/waf/). Strict mode requires a valid SSL certificate on your origin, so be sure to use the [Cloudflare Origin CA](https://blog.cloudflare.com/cloudflare-ca-encryption-origin/) to generate one.
```
```sh
$ git checkout -b step3-https
Switched to a new branch 'step3-https'
@ -34,7 +36,7 @@ EOF
Let's take a look at what Terraform is proposing before we apply it. We filter the `terraform plan` output to ignore those values that will be "computed"—in this case, settings that will be left at their default values.
```
```sh
$ terraform plan | grep -v "<computed>"
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
@ -70,7 +72,7 @@ can't guarantee that exactly these actions will be performed if
The proposed changes look good, so we'll merge them into master and then apply them with `terraform apply`. When working on a team, you may want to require pull requests and use this opportunity to peer review any proposed configuration changes.
```
```sh
$ git add cloudflare.tf
$ git commit -m "Step 3 - Enable TLS 1.3, Always Use HTTPS, and SSL Strict mode."
[step3-https d540600] Step 3 - Enable TLS 1.3, Always Use HTTPS, and SSL Strict mode.
@ -98,9 +100,9 @@ To git@github.com:$GITHUB_USER/cf-config.git
## 3. Apply and verify the changes
Before applying the changes, let's see if we can connect with TLS 1.3. Hint: we shouldn't be able to with default settings. If you want to follow along with this test, you'll need to [compile curl against BoringSSL](https://ec.haxx.se/building-boringssl.html).
Before applying the changes, let's see if we can connect with TLS 1.3. Hint: we shouldn't be able to with default settings. If you want to follow along with this test, you'll need to [compile curl against BoringSSL](https://ec.haxx.se/building-boringssl.html).
```
```sh
$ curl -v --tlsv1.3 https://www.upinatoms.com 2>&1 | grep "SSL connection\|error"
* error:1000042e:SSL routines:OPENSSL_internal:TLSV1_ALERT_PROTOCOL_VERSION
curl: (35) error:1000042e:SSL routines:OPENSSL_internal:TLSV1_ALERT_PROTOCOL_VERSION
@ -108,7 +110,7 @@ curl: (35) error:1000042e:SSL routines:OPENSSL_internal:TLSV1_ALERT_PROTOCOL_VER
As shown above, we receive an error as TLS 1.3 is not yet enabled on your zone. Let's enable it by running `terraform apply` and try again:
```
```sh
$ terraform apply --auto-approve
cloudflare_record.www: Refreshing state... (ID: c38d3103767284e7cd14d5dad3ab8668)
cloudflare_zone_settings_override.example-com-settings: Creating...
@ -168,7 +170,7 @@ Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Now we can try the same command as above, and see that it succeeds. Nice, TLS 1.3!
```
```sh
$ curl -v --tlsv1.3 https://www.example.com 2>&1 | grep "SSL connection\|error"
* SSL connection using TLSv1.3 / AEAD-AES128-GCM-SHA256
```