Skip to content
Snippets Groups Projects
Commit d3571c83 authored by marcoemi.poleggi's avatar marcoemi.poleggi
Browse files

WIP: new tutorial

parent f2d5bfbd
Branches
No related tags found
No related merge requests found
# Lab-Terraform
# # Lab: Cloud provisioning/orchestration - Terraform and AWS
Lab with Terraform and any Cloud
Lab template for a Cloud provisioning/orchestration exercise with Terraform
(TF) and AWS. Originally written by Marcel Graf (HEIG-VD).
## Pedagogical objectives ##
* Become familiar with a Cloud provisioning/orchestration tool
* Provision Cloud resources in an automated fashion
## Tasks ##
In this lab you will perform a number of tasks and document your progress in a
lab report. Each task specifies one or more deliverables to be
produced. Collect all the deliverables in your lab report.
**N.B.** Some tasks require interacting with your local machine's OS: any
related commands are supposed to be run into a terminal with the following
conventions about the *command line prompt*:
* `#`: execution with super user's (root) privileges
* `$`: execution with normal user's privileges
* `lcl`: your local machine
* `ins`: your VM instance
### Task #1: install Terraform CLI and AWS CLI ###
**Goal:** install the Terraform CLI and AWS CLI on your local machine.
Please, refer to your OS documentation for the proper way to do so
1. [Terraform
CLI](https://learn.hashicorp.com/tutorials/terraform/install-cli)
v1.1.4. Skip the TF "Quick start tutorial" (Docker).
1. [AWS CLI](https://aws.amazon.com/cli/) v1.22..
1. Create a new [AWS Access
Key](https://console.aws.amazon.com/iam/home?#/security_credentials).
1. Configure the AWS CLI:
``` shell
lcl$ aws configure
```
The following tasks are based on TF's tutorial [build an example
infrastructure on
AWS](https://learn.hashicorp.com/tutorials/terraform/aws-build).
### Task #2: configure TF for AWS ###
**Goal:** instruct TF to handle a single AWS EC2 instance.
Create a "sandbox" directory on your local machine `~/terraform/AWS/`. Inside
it, create a file called `main.tf` (written in HCL language), the
infrastructure *definition* file, with the following content:
``` hcl
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 3.27"
}
}
required_version = ">= 0.14.9"
}
provider "aws" {
profile = "default"
region = "us-east-1"
}
resource "aws_instance" "app_server" {
ami = "<your-AWS-AMI-ID>"
instance_type = "t2.micro"
tags = {
Name = "ExampleAppServerInstance"
}
}
```
To find `<your-AWS-AMI-ID>`, you can query the AMI Catalog via
a. [AWS dashboard](https://console.aws.amazon.com/ec2/v2/home?region=us-east-1#AMICatalog:), searching "Ubuntu", selecting "Quickstart AMIs" and filtering by "Free-tier",
b. or with CLI, and get the most recent AMI:
``` shell
lcl$ aws ec2 describe-images --region us-east-1 \
--filters "Name=root-device-type,Values=ebs" \
"Name=name,Values= ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server*" \
--query "reverse(sort_by(Images, &ImageId))[:1].[ImageId]" --output text
```
Initialize your sandbox with:
``` shell
lcl$ terraform init
Initializing the backend...
Initializing provider plugins...
- Finding hashicorp/aws versions matching "~> 3.27"...
- Installing hashicorp/aws v3.27.0...
- Installed hashicorp/aws v3.27.0 (signed by HashiCorp)
Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository so
that Terraform can guarantee to make the same selections by default when you run
"terraform init" in the future.
Terraform has been successfully initialized!
...
```
Take note of what the file` .terraform.lock.hcl` is used for.
Have a look inside the newly created sub-directory
`~/terraform/AWS/.terraform/`, you'll find the required `aws` provider module
that has been downloaded during the initialization.
It's good practice to format and validate your configuration:
``` shell
lcl$ terraform fmt
main.tf
lcl$ terraform validate
Success! The configuration is valid.
```
### Task #3: deploy your AWS infrastructure ###
**Goal:** provision your AWS EC2 instance via TF.
Run the following command, confirm by typing "yes" and observe it's output:
``` shell
lcl$ terraform apply
Terraform used the selected providers to generate the following execution plan.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# aws_instance.app_server will be created
+ resource "aws_instance" "app_server" {
+ ami = "ami-0fa37863afb290840"
+ arn = (known after apply)
...
+ instance_type = "t2.micro"
...
+ tags = {
+ "Name" = "ExampleAppServerInstance"
}
...
Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
aws_instance.app_server: Creating...
aws_instance.app_server: Still creating... [10s elapsed]
aws_instance.app_server: Still creating... [20s elapsed]
aws_instance.app_server: Still creating... [30s elapsed]
aws_instance.app_server: Creation complete after 38s [id=i-0155ba9d77ee0a854]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
```
The information shown above before the prompt for action is the `execution
plan`: the `+` prefix mark things to add. Of course, many details are unknown
until the corresponding resource is instantiated.
:question: How many resources were created?
You can verify via the AWS dashboard that one EC2 instance has been created.
The state of the resources acted upon is locally stored. Let's see what's in
our sandbox:
``` shell
$ tree -a
.
├── .terraform
│ └── providers
...
├── .terraform.lock.hcl
├── main.tf
└── terraform.tfstate
```
:question: What's in file `terraform.tfstate`? The answer comes from the
following commands:
``` shell
$ terraform state list
aws_instance.app_server
```
It confirms that we're tracking one AWS instance. Let's dig a bit more:
``` shell
$ terraform show
# aws_instance.app_server:
resource "aws_instance" "app_server" {
ami = "ami-0fa37863afb290840"
arn = "arn:aws:ec2:us-east-1:768034348959:instance/i-0155ba9d77ee0a854"
associate_public_ip_address = true
availability_zone = "us-east-1e"
...
id = "i-0155ba9d77ee0a854"
instance_initiated_shutdown_behavior = "stop"
instance_state = "running"
instance_type = "t2.micro"
...
private_dns = "ip-172-31-94-207.ec2.internal"
private_ip = "172.31.94.207"
public_dns = "ec2-3-94-184-169.compute-1.amazonaws.com"
public_ip = "3.94.184.169"
...
tags = {
"Name" = "ExampleAppServerInstance"
}
...
vpc_security_group_ids = [
"sg-0c420780b4f729d3e",
]
...
}
```
The above command output provides useful runtime (state) information, like the
instance IP's address.
:question: Is that instance accessible via SSH? Give it a try. If not, why?
### Task #4: change your infrastructure ###
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment