├── .github └── FUNDING.yml ├── README.md ├── m1-setup └── README.md ├── m2-security-group ├── README.md └── wordpress.tf ├── m3-ec2 ├── README.md ├── variables.tf └── wordpress.tf ├── m4-elastic-ip ├── README.md ├── variables.tf └── wordpress.tf ├── m5-user-data ├── README.md ├── variables.tf ├── wordpress-init.sh └── wordpress.tf ├── m6-template ├── README.md ├── variables.tf ├── wordpress-init.sh.tpl └── wordpress.tf ├── m7-module ├── README.md ├── variables.tf ├── vpc │ └── vpc.tf ├── wordpress-init.sh.tpl └── wordpress.tf └── teach ├── cli.sh ├── datasource.tf ├── interpolationsyntax1.tf ├── interpolationsyntax2.tf ├── output.tf ├── provider.tf ├── resource.tf └── variable.tf /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: widdix 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Learn Terraform 2 | 3 | This repository contains modules helping you to get started with Terraform based on a simple example. You will deploy Wordpress with the help of Terraform. 4 | 5 | ## Setup 6 | Clone this repository on your local machine. 7 | 8 | ``git clone https://github.com/widdix/learn-terraform.git`` 9 | 10 | ## Cleaning up 11 | Delete your infrastructure with `AWS_PROFILE=tf-workshop terraform destroy`. 12 | 13 | Open the AWS Management Console of an empty AWS account. 14 | -------------------------------------------------------------------------------- /m1-setup/README.md: -------------------------------------------------------------------------------- 1 | # Module 1: Initial Setup 2 | 3 | ## Documentation 4 | * [Terraform Docs](https://www.terraform.io/docs/index.html) 5 | 6 | ## Initial Setup 7 | 1. Create an IAM user. 8 | 1. Create and download security credentials for your IAM user. 9 | 1. Add another AWS profile: `aws configure --profile tf-workshop`. Choose default region us-east-1. 10 | 1. Run `AWS_PROFILE=tf-workshop aws s3 ls` to verify your setup. 11 | -------------------------------------------------------------------------------- /m2-security-group/README.md: -------------------------------------------------------------------------------- 1 | # Module 2: Creating a Security Group 2 | 3 | ## Documentation 4 | * [Terraform: AWS Provider](https://www.terraform.io/docs/providers/aws/index.html) 5 | * [Terraform: Security Group](https://www.terraform.io/docs/providers/aws/r/security_group.html) 6 | 7 | ## Creating a Security Group 8 | 1. Create a Terraform configuration file `wordpress.tf`. 9 | 1. Add the AWS provider to your configuration file. 10 | 1. Set the region to `us-east-1`. 11 | 1. Create a Security Group resource allowing incoming traffic on TCP 22 and 80 from anywhere and all outgoing traffic. 12 | 1. Apply the Terraform configuration: `AWS_PROFILE=tf-workshop terraform apply`. 13 | -------------------------------------------------------------------------------- /m2-security-group/wordpress.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | region = "us-east-1" 3 | } 4 | 5 | resource "aws_security_group" "webserver" { 6 | name = "wordpress" 7 | description = "Allowing HTTP and SSH access." 8 | vpc_id = "vpc-6bca420d" 9 | 10 | ingress { 11 | protocol = "tcp" 12 | from_port = 22 13 | to_port = 22 14 | cidr_blocks = ["0.0.0.0/0"] 15 | } 16 | 17 | ingress { 18 | protocol = "tcp" 19 | from_port = 80 20 | to_port = 80 21 | cidr_blocks = ["0.0.0.0/0"] 22 | } 23 | 24 | egress { 25 | from_port = 0 26 | to_port = 0 27 | protocol = "-1" 28 | cidr_blocks = ["0.0.0.0/0"] 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /m3-ec2/README.md: -------------------------------------------------------------------------------- 1 | # Module 3: Creating an EC2 Instance 2 | 3 | ## Documentation 4 | * [Terraform: EC2 Instance](https://www.terraform.io/docs/providers/aws/r/instance.html) 5 | * [Terraform: Variables](https://www.terraform.io/docs/configuration/variables.html) 6 | * [Terraform: Dependencies](https://www.terraform.io/intro/getting-started/dependencies.html) 7 | 8 | ## Creating an EC2 Instance 9 | 1. Add an EC2 Instance resource to your Terraform configuration file `wordpress.tf`. 10 | 1. Define `t2.micro` as the instance type. 11 | 1. Create a variable named `ami` with the value `ami-f4cc1de2`. 12 | 1. Use use the variable `ami` to specify the image to start the virtual machine from. 13 | 1. Attach the Security Group already defined within the template to the EC2 instance. 14 | 1. Configure your Key Pair for the EC2 instance. 15 | 1. Apply the Terraform configuration: `AWS_PROFILE=tf-workshop terraform apply`. 16 | -------------------------------------------------------------------------------- /m3-ec2/variables.tf: -------------------------------------------------------------------------------- 1 | variable "ami" { 2 | default = "ami-f4cc1de2" 3 | } -------------------------------------------------------------------------------- /m3-ec2/wordpress.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | region = "us-east-1" 3 | } 4 | 5 | resource "aws_instance" "webserver" { 6 | ami = "${var.ami}" 7 | instance_type = "t2.micro" 8 | vpc_security_group_ids = ["${aws_security_group.webserver.id}"] 9 | key_name = "awittig" 10 | } 11 | 12 | resource "aws_security_group" "webserver" { 13 | name = "wordpress" 14 | description = "Allowing HTTP and SSH access." 15 | vpc_id = "vpc-6bca420d" 16 | 17 | ingress { 18 | protocol = "tcp" 19 | from_port = 22 20 | to_port = 22 21 | cidr_blocks = ["0.0.0.0/0"] 22 | } 23 | 24 | ingress { 25 | protocol = "tcp" 26 | from_port = 80 27 | to_port = 80 28 | cidr_blocks = ["0.0.0.0/0"] 29 | } 30 | 31 | egress { 32 | from_port = 0 33 | to_port = 0 34 | protocol = "-1" 35 | cidr_blocks = ["0.0.0.0/0"] 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /m4-elastic-ip/README.md: -------------------------------------------------------------------------------- 1 | # Module 4: Creating an Elastic IP 2 | 3 | ## Documentation 4 | * [Terraform: Elastic IP](https://www.terraform.io/docs/providers/aws/r/eip.html) 5 | * [Terraform: Outputs](https://www.terraform.io/intro/getting-started/outputs.html) 6 | 7 | ## Creating an Elastic IP 8 | 1. Add an Elastic IP resource to your Terraform configuration file `wordpress.tf`. 9 | 1. Add an output variable containing the public IP address to your configuration file. 10 | 1. Apply the Terraform configuration: `AWS_PROFILE=tf-workshop terraform apply`. 11 | -------------------------------------------------------------------------------- /m4-elastic-ip/variables.tf: -------------------------------------------------------------------------------- 1 | variable "ami" { 2 | default = "ami-f4cc1de2" 3 | } -------------------------------------------------------------------------------- /m4-elastic-ip/wordpress.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | region = "us-east-1" 3 | } 4 | 5 | resource "aws_instance" "webserver" { 6 | ami = "${var.ami}" 7 | instance_type = "t2.micro" 8 | vpc_security_group_ids = ["${aws_security_group.webserver.id}"] 9 | key_name = "awittig" 10 | } 11 | 12 | resource "aws_security_group" "webserver" { 13 | name = "wordpress" 14 | description = "Allowing HTTP and SSH access." 15 | vpc_id = "vpc-6bca420d" 16 | 17 | ingress { 18 | protocol = "tcp" 19 | from_port = 22 20 | to_port = 22 21 | cidr_blocks = ["0.0.0.0/0"] 22 | } 23 | 24 | ingress { 25 | protocol = "tcp" 26 | from_port = 80 27 | to_port = 80 28 | cidr_blocks = ["0.0.0.0/0"] 29 | } 30 | 31 | egress { 32 | from_port = 0 33 | to_port = 0 34 | protocol = "-1" 35 | cidr_blocks = ["0.0.0.0/0"] 36 | } 37 | 38 | } 39 | 40 | resource "aws_eip" "ip" { 41 | instance = "${aws_instance.webserver.id}" 42 | } 43 | 44 | output "ip" { 45 | value = "${aws_eip.ip.public_ip}" 46 | } 47 | -------------------------------------------------------------------------------- /m5-user-data/README.md: -------------------------------------------------------------------------------- 1 | # Module 5: Using User Data to provision the EC2 Instance 2 | 3 | ## Documentation 4 | * [Terraform: EC2 Instance](https://www.terraform.io/docs/providers/aws/r/instance.html) 5 | * [Terraform: Interpolation](https://www.terraform.io/docs/configuration/interpolation.html) 6 | 7 | ## Using User Data to provision the EC2 Instance 8 | 1. Create a file including a bash script to provision the EC2 Instance (e.g. install apache2, download and configure Wordpress, ...). 9 | 1. Use User Data to inject your script to the EC2 Instance during the boot process. 10 | 1. Apply the Terraform configuration: `AWS_PROFILE=tf-workshop terraform apply`. 11 | -------------------------------------------------------------------------------- /m5-user-data/variables.tf: -------------------------------------------------------------------------------- 1 | variable "ami" { 2 | default = "ami-f4cc1de2" 3 | } -------------------------------------------------------------------------------- /m5-user-data/wordpress-init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | apt-get update 4 | DEBIAN_FRONTEND=noninteractive apt-get install -y apache2 libapache2-mod-php7.0 mysql-server php7.0-mysql 5 | service apache2 restart 6 | wget https://wordpress.org/latest.tar.gz 7 | tar xf latest.tar.gz 8 | mv wordpress/ /var/www/html 9 | echo "CREATE DATABASE IF NOT EXISTS wordpress; CREATE USER IF NOT EXISTS 'wordpress'@'localhost' IDENTIFIED BY 'verysecurepassword'; GRANT ALL PRIVILEGES ON *.* TO 'wordpress'@'localhost' WITH GRANT OPTION;" | mysql 10 | 11 | 12 | cat > /var/www/html/wordpress/wp-config.php << "EOF" 13 | /var/www/html/wordpress/wp-config.php << "EOF" 13 | /var/www/html/wordpress/wp-config.php << "EOF" 13 | [args] 3 | 4 | Common commands: 5 | apply Builds or changes infrastructure 6 | destroy Destroy Terraform-managed infrastructure 7 | get Download and install modules for the configuration 8 | output Read an output from a state file 9 | plan Generate and show an execution plan 10 | -------------------------------------------------------------------------------- /teach/datasource.tf: -------------------------------------------------------------------------------- 1 | data "aws_ami" "web" { 2 | 3 | filter { 4 | name = "tag:Component" 5 | values = ["web"] 6 | } 7 | 8 | } 9 | -------------------------------------------------------------------------------- /teach/interpolationsyntax1.tf: -------------------------------------------------------------------------------- 1 | # variable 2 | ${var.NAME 3 | ${var.foo} 4 | 5 | # attributes of other resources 6 | ${TYPE.NAME.ATTRIBUTE} 7 | ${aws_instance.web.id} 8 | 9 | # attributes of your own resource 10 | ${self.ATTRIBUTE} 11 | ${self.private_ip_address} 12 | -------------------------------------------------------------------------------- /teach/interpolationsyntax2.tf: -------------------------------------------------------------------------------- 1 | # attributes of a data source 2 | ${data.TYPE.NAME.ATTRIBUTE} 3 | ${data.aws_ami.ubuntu.id} 4 | 5 | # outputs from a module 6 | ${MODULE.NAME.OUTPUT} 7 | ${module.foo.bar} 8 | -------------------------------------------------------------------------------- /teach/output.tf: -------------------------------------------------------------------------------- 1 | output "address" { 2 | value = "${aws_instance.db.public_dns}" 3 | } 4 | -------------------------------------------------------------------------------- /teach/provider.tf: -------------------------------------------------------------------------------- 1 | provider "aws" { 2 | region = "us-east-1" 3 | } 4 | -------------------------------------------------------------------------------- /teach/resource.tf: -------------------------------------------------------------------------------- 1 | resource "aws_instance" "web" { 2 | ami = "ami-408c7f28" 3 | instance_type = "t1.micro" 4 | } 5 | -------------------------------------------------------------------------------- /teach/variable.tf: -------------------------------------------------------------------------------- 1 | variable "key" { 2 | type = "string" 3 | } 4 | 5 | variable "images" { 6 | type = "map" 7 | 8 | default = { 9 | us-east-1 = "image-1234" 10 | us-west-2 = "image-4567" 11 | } 12 | } 13 | --------------------------------------------------------------------------------