diff --git a/terraform_fundmentals/03-virtual_machine.md b/terraform_fundmentals/03-virtual_machine.md index 7df0ebc..d19d4cc 100644 --- a/terraform_fundmentals/03-virtual_machine.md +++ b/terraform_fundmentals/03-virtual_machine.md @@ -54,4 +54,5 @@ resource "azurerm_virtual_machine" "training" { ``` ### 2. Run `terraform plan` to view the resources that will be created + ### 3. Run `terraform apply` to create the resources specified \ No newline at end of file diff --git a/terraform_fundmentals/11-meta-arguments.md b/terraform_fundmentals/11-meta-arguments.md index e3b545d..bfa92c8 100644 --- a/terraform_fundmentals/11-meta-arguments.md +++ b/terraform_fundmentals/11-meta-arguments.md @@ -12,7 +12,7 @@ So far, we've already used arguments to configure your resources. These argument We are going to reuse the configuration in the `azure` directory from the exercises `02-basic-configuration` and `03-virtual_machine`. If you don't have those configurations, they are in the appendix of this lab. -Add a count argument to the Azure Virtual Machine resource in `main.tf` with a value of 2. Also adjust the value of `name` to incrementally add a number to the end of each instances name: +Add a count argument to the Azure Virtual Machine resource in `main.tf` with a value of 2. Also adjust the value of `name` to incrementally add a number to the end of each instances name: ```hcl # ... @@ -62,7 +62,7 @@ resource "azurerm_network_interface" "training" { ## Task 2: Modify the rest of the configuration to support multiple instances -### Step 8.2.1 +### Step 2.1 If you run `terraform apply` now, you'll get an error. Since we added _count_ to the azure_virtual_machine.training resource, it now refers to multiple resources. Because of this, values like our public_dns output no longer refer to the "public dns" of a single resource. We need to tell terraform which resource we're referring to. @@ -74,9 +74,9 @@ output "public_dns" { } ``` -The syntax `azurerm_public_ip.training[*]...` refers to all of the instances, so this will output a list of all dns entries. +The syntax `azurerm_public_ip.training[*]...` refers to all of the instances, so this will output a list of all dns entries. -### Step 8.2.2 +### Step 2.2 Run `terraform apply` to add the new instance. You will notice that because we changed the name of the Azure Virtual Mahine, that there will be a forced replacement of our previous virutal machine. @@ -92,7 +92,7 @@ Plan: 2 to add, 0 to change, 1 to destroy. ## Task 3: Add variable interpolation to the count argument -### Step 8.3.1 +### Step 3.1 Update `variables.tf` to add a new variable definition, and use it: @@ -130,7 +130,7 @@ Remember to also add the variable declaration to your `terraform.tfvars` accordi num_vms = 2 ``` -### Step 8.3.2 +### Step 3.2 Run `terraform apply` in the terraform directory. No changes should be detected as the _values_ have not changed: diff --git a/terraform_fundmentals/13-azure_auth.md b/terraform_fundmentals/13-azure_auth.md index e69de29..b3efa83 100644 --- a/terraform_fundmentals/13-azure_auth.md +++ b/terraform_fundmentals/13-azure_auth.md @@ -0,0 +1,23 @@ +# Lab: Azure Authentication + +Duration: 5 minutes + +In this lab, you will explore how Terraform is authenticating to Azure. + +- Task 1: View the current environment variables + +## Task 1: View the current environment variables + +From the terminal of you lab environment, run the following command to view the current environment variables: + +```bash +env | grep ARM +``` + +You should see environment variables for the Azure subscription ID, tenant ID, client ID, and client secret. + +From the cloud credentials tab, you can confirm that the values line up to what was provisioned for you. + +## Bonus Task: Override the environment variables + +You can also set the Azure authentication values directly in the provider block. Although this isn't recommended, it can be useful for testing. Add the necessary arguments in the `azurerm` provider block and use input variables to set the values. diff --git a/terraform_fundmentals/14-data_source.md b/terraform_fundmentals/14-data_source.md index 614eced..b7838f8 100644 --- a/terraform_fundmentals/14-data_source.md +++ b/terraform_fundmentals/14-data_source.md @@ -161,4 +161,4 @@ Apply the updated configuration: ```bash terraform apply -``` \ No newline at end of file +``` diff --git a/terraform_fundmentals/15-reading_state.md b/terraform_fundmentals/15-reading_state.md index d586cb3..684c8d7 100644 --- a/terraform_fundmentals/15-reading_state.md +++ b/terraform_fundmentals/15-reading_state.md @@ -1,4 +1,4 @@ -# Lab 12: State +# Lab: State Duration: 10 minutes @@ -7,15 +7,11 @@ This lab demonstrates how to read state from another Terraform project. It uses - Task 1: Create a Terraform configuration that defines an output - Task 2: Read an output value from that project's state -## Prerequisites - -This lab only requires a copy of [Terraform](https://www.terraform.io/downloads.html). It doesn't require any cloud provider credentials. - ## Task 1: Create a Terraform configuration that defines an output For this task, you'll create two Terraform configurations in two separate directories. One will read from the other (using state files). -### Step 1.1.1 +### Step 1.1 In this step, you'll create a Terraform project on disk that does nothing but emit an output. It should emit `public_ip` which can be a hard-coded value (for simplicity). @@ -38,7 +34,7 @@ output "public_ip" { } ``` -### Step 1.1.2 +### Step 1.2 Generate a state file for the project. Within that project, run `terraform init` and `apply`. You should see a `terraform.tfstate` file after running these commands. @@ -54,7 +50,7 @@ terraform apply ## Task 2: Read an output value from that project's state -### Step 1.2.1 +### Step 2.1 Create a new Terraform configuration that uses a data source to read the configuration from the `primary` project. @@ -87,7 +83,7 @@ Initialize the secondary project with `init`. terraform init ``` -### Step 1.2.2 +### Step 2.2 Declare the `public_ip` as an `output`. diff --git a/terraform_fundmentals/17-store-state.md b/terraform_fundmentals/17-store-state.md index fc26fd9..ee3c308 100644 --- a/terraform_fundmentals/17-store-state.md +++ b/terraform_fundmentals/17-store-state.md @@ -11,7 +11,7 @@ You'll setup a new project using Terraform Cloud as your backed and use a second ## Task 1: Sign up for Terraform Cloud -1. Navigate to [the sign up page](https://app.terraform.io/signup) and create an account for Terraform Cloud. If you already have a TFC account +1. Navigate to [the sign up page](https://app.terraform.io/signup) and create an account for Terraform Cloud and an organization called `###-tfc-demo-2023` where `###` is your initials. If you already have an account, just create the organization. 1. Perform a `terraform login` from your workstation @@ -40,7 +40,7 @@ Open the following URL to access the tokens page for app.terraform.io: --------------------------------------------------------------------------------- ``` -1. If the token was entered succesfully you should see the following: +1. If the token was entered successfully you should see the following: ```bash @@ -79,23 +79,23 @@ Retrieved token for user tfcuser For this task, you'll create a Terraform project which stores its state in Terraform Cloud and emits an output. -### Step 2.2.1 +### Step 2.1 In this step, you'll create the project and a configuration. -```shell +```bash mkdir -p ~/workstation/terraform/azure/cloud_state_demo/write_state && cd $_ touch main.tf ``` -### Step 2.2.2 +### Step 2.2 Setup the configuration to utilize the `remote` backend, replacing `ORGANIZATION NAME` with the name of your organization and ```###``` with your initials. ```hcl # write_state/main.tf terraform { - backend "remote" { + cloud { organization = "" workspaces { @@ -105,7 +105,7 @@ terraform { } ``` -### Step 2.2.3 +### Step 2.3 Next, add the ability to generate and emit a `random` output from your configuration: @@ -124,7 +124,7 @@ output "random" { } ``` -### Step 2.2.4 +### Step 2.4 Provision the resource and push the state to Terraform Cloud with: @@ -136,11 +136,10 @@ terraform apply -auto-approve You'll see Terraform confirm it is creating your state remotely as well as your `random` output. If you navigate back to your organization, you will also see a new workspace name `###_write_state`. -### Step 2.2.5 +### Step 2.5 + +Congratulations! You're now storing state remotely. With Terraform Cloud you are able to share your workspace with teammates. -Congratulations! -You're now storing state remotely. -With Terraform Cloud you are able to share your workspace with teammates. Back in the Terraform Cloud UI you'll be able to: * View all your organization's workspaces @@ -151,7 +150,7 @@ Back in the Terraform Cloud UI you'll be able to: Now that we have our state stored in Terraform Cloud in our `###_write_state` workspace, we will create another project, configuration, and workspace to read from it. -### Step 2.3.1 +### Step 3.1 Start by creating a new directory and `main.tf` file: @@ -160,7 +159,7 @@ mkdir -p ~/workstation/terraform/azure/cloud_state_demo/read_state && cd $_ touch main.tf ``` -### Step 2.3.2 +### Step 3.2 Just as we did in Step 2.2.2, we need to setup our configuration to use the `remote` backend, once again replacing `ORGANIZATION NAME`. We will also create a new `random` resource to compare against: @@ -168,7 +167,7 @@ We will also create a new `random` resource to compare against: ```hcl # read_state/main.tf terraform { - backend "remote" { + cloud { organization = "" workspaces { @@ -186,11 +185,12 @@ resource "random_id" "random" { } ``` -### Step 2.3.3 +### Step 3.3 In order to read from our `###_write_state` workspace, we will need to setup a `terraform_remote_state` data source. Data sources are used to retrieve read-only data from sources outside of our project. -It supports several cloud providers, but we'll be using `remote` as the `backend`. + +It supports several cloud providers, but we'll be using `remote` as the `backend`. That is the name of the Terraform Cloud backend. ```hcl # read_state/main.tf @@ -211,7 +211,7 @@ In addition to creating the `terraform_remote_state` data source in your configu From the Terraform Cloud UI, go to the `###_write_state` workspace, and select *Settings->General*. Under the *Remote state sharing* section change the radio button to **Share with all workspaces in this organization**, then click on *Save settings* at the bottom of the page. -### Step 2.3.4 +### Step 3.4 Now that we have access to our remote `###_write_state` workspace, we can retrieve the `random` output contained within it. We'll also output `random` which we created in this configuration, confirming that they are distinct. @@ -227,7 +227,7 @@ output "write_state_random" { } ``` -### Step 2.3.5 +### Step 3.5 To verify that we have successfully retrieved the state from out `###_write_state` workspace, we can run our configuration and validate our outputs. diff --git a/terraform_fundmentals/18-secure_variables.md b/terraform_fundmentals/18-secure_variables.md index 1a50d20..0ab4fcf 100644 --- a/terraform_fundmentals/18-secure_variables.md +++ b/terraform_fundmentals/18-secure_variables.md @@ -28,7 +28,7 @@ terraform { } } - backend "remote" { + cloud { organization = "YOUR_ORGANIZATION_NAME" workspaces { @@ -78,7 +78,7 @@ resource "azurerm_subnet" "training" { ## Task 2: Login to TFC and initialize the configuration -Log into your TFC account: +Log into your TFC account (this is only necessary once per sandbox, you can skip this step if you've already logged into Terraform Cloud): ```bash terraform login @@ -122,4 +122,4 @@ Approve the apply from the Terraform Cloud UI and view the state data when the r ## Task 5: (BONUS) Change the prefix -If you're feeling like a little bonus content, try changing the `prefix` variable value and running a plan directly from the UI. \ No newline at end of file +If you're feeling like a little bonus content, try changing the `prefix` variable value and running a plan directly from the UI. diff --git a/terraform_fundmentals/19-lifecycles.md b/terraform_fundmentals/19-lifecycles.md index a90ca8a..8adc233 100644 --- a/terraform_fundmentals/19-lifecycles.md +++ b/terraform_fundmentals/19-lifecycles.md @@ -7,7 +7,7 @@ This lab demonstrates how to use lifecycle directives to control the order in wh - Task 1: Use `create_before_destroy` with an instance rename - Task 2: Use `prevent_destroy` with an instance -### Create the base Terraform Configuration +## Create the base Terraform Configuration Change directory into a folder specific to this challenge, and create a `main.tf` and `terraform.tfvars` files to hold our configuration. @@ -23,7 +23,7 @@ We will start with a few of the basic resources needed. When you rename a Azure Virtual Machine, terraform will reprovision the resource (delete and then create a new instance). We can leverage `create_before_destroy` to override that default behavior -### Step 6.1.1: Deploy your Azure Virtual Machine +### Step 1.1: Deploy your Azure Virtual Machine Place the following configuration in your `main.tf` file to deploy your virtual machine. @@ -136,7 +136,7 @@ vm_size = "Standard_A2_v2" - Run a `terraform plan` - Run a `terraform apply` -### Step 6.1.2: Rename your Azure Virtual Machine +### Step 1.2: Rename your Azure Virtual Machine Edit your `main.tf` file and add the suffix _renamed_ to the value for `name` as shown below: @@ -170,7 +170,7 @@ Terraform will perform the following actions: Answer `yes` to proceed with the replacement of the instances. -### Step 6.1.3: Use `create_before_destroy` and rename the instances again +### Step 1.3: Use `create_before_destroy` and rename the instances again Add a `lifecycle` configuration to the `azurerm_virtual_machine` resource. Specify that this resource should be created before the existing instance(s) are destroyed. Additionally, rename the instance(s) again, by removing the suffix _renamed_, and replacing it with `new` @@ -189,7 +189,7 @@ resource "azurerm_virtual_machine" "main" { } ``` -Also update the `azurerm_network_interface` with a lifecyle block and new name: +Also update the `azurerm_network_interface` with a lifecycle block and new name: ```hcl resource "azurerm_network_interface" "main" { @@ -245,7 +245,7 @@ Terraform will perform the following actions: We'll demonstrate how `prevent_destroy` can be used to guard an instance from being destroyed. -### Step 6.2.1: Use `prevent_destroy` +### Step 2.1: Use `prevent_destroy` Add `prevent_destroy = true` to the same `lifecycle` stanza where you added `create_before_destroy`. @@ -263,11 +263,11 @@ resource "azurerm_virtual_machine" "main" { Attempt to destroy the existing infrastructure. You should see the error that follows. -```shell +```bash terraform destroy ``` -``` +```bash Error: Instance cannot be destroyed on main.tf line 32: @@ -280,7 +280,7 @@ lifecycle.prevent_destroy or reduce the scope of the plan using the -target flag. ``` -### Step 6.2.2: Destroy cleanly +### Step 2.2: Destroy cleanly Now that you have finished the steps in this lab, destroy the infrastructure you have created. diff --git a/terraform_fundmentals/20-templatefile.md b/terraform_fundmentals/20-templatefile.md index 44813fc..7b31bb3 100644 --- a/terraform_fundmentals/20-templatefile.md +++ b/terraform_fundmentals/20-templatefile.md @@ -5,11 +5,11 @@ Duration: 15 minutes This lab demonstrates the use of the `templatefile` to read a file at the given path and renders its content as a template using a supplied set of template variables. - Task 1: Create a Azure Dashboard via Terraform -- Task 2: Use `templatefile` to render the dasboard layout. - +- Task 2: Use `templatefile` to render the dashboard layout. ## Task 1: Create a Dashboard using Terraform -### Step 1.1.1: Create Azure Dashboard + +### Step 1.1: Create Azure Dashboard Build the dashboard using the Azure Virtual Machine Module @@ -165,20 +165,22 @@ output "dashboard_url" { ``` Then perform an `init`, `plan`, and `apply`. -## Task 2: Use `templatefile` to render the dasboard layout. -### Step 1.2.1: Use `templatefile` +## Task 2: Use `templatefile` to render the dasboard layout + +### Step 2.1: Use `templatefile` 1. Create a `templates` directory in the same directory as your `main.tf` 2. Create a `dash.tpl` file inside the `templates` directory. For example: `/terraform/azure/template_lab` which contains: -```sh + +```bash ├ main.tf └ templates └── dash.tpl ``` -Add the follwing content to the `dash.tpl` file: +Add the following content to the `dash.tpl` file: ```txt { @@ -312,9 +314,10 @@ Replace with the following ``` Initialize the configuration with a `terraform init` followed by a `plan` and `apply`. -### Step 1.2.3: Destroy +### Step 2.3: Destroy + Finally, run `destroy`. -```shell +```bash terraform destroy ``` diff --git a/terraform_fundmentals/21-debug.md b/terraform_fundmentals/21-debug.md index 56b2da6..618d3d0 100644 --- a/terraform_fundmentals/21-debug.md +++ b/terraform_fundmentals/21-debug.md @@ -6,7 +6,7 @@ Duration: 15 minutes ## Task 1: Enable Logging -### Step 18.1.1 +### Step 1.1 Terraform has detailed logs which can be enabled by setting the TF_LOG environment variable to any value. This will cause detailed logs to appear on stderr. @@ -36,7 +36,6 @@ Run Terraform Apply. terraform apply ``` - Example Output ```shell @@ -58,7 +57,7 @@ Example Output 2020/03/20 13:14:41 [TRACE] Executing graph transform *terraform.DiffTransformer ``` -### Step 18.1.2 +### Step 1.2 To persist logged output you can set TF_LOG_PATH in order to force the log to always be appended to a specific file when logging is enabled. Note that even when TF_LOG_PATH is set, TF_LOG must be set in order for any logging to be enabled.