During these workshops, we will use the default local backend. A backend is a place where the state of your infrastructure is stored.
The state is kept in JSON format in a file with tfstate extension. It stores all information about your infrastructure, including sensitive data like database credentials. Due to this fact, the state shouldn't be kept in a version control system. An example .gitignore file for Terraform is available here.
Create a directory on your computer for these workshops. I will refer to this directory as a root directory.
In your root directory create terraform directory. Inside it, create webserver directory with main.tf file and add the following code to it:
The terraform {} block contains settings, including AWS provider installed from Terraform Registry. Providers are plugins that implement resource types. We will use AWS provider to create resources on AWS Cloud in eu-central-1 region (Europe, Frankfurt).
In the webserver directory, run terraform fmt command to format the code.
$terraformfmt
Next, run terraform init command to install providers.
$terraforminit
Now you can use terraform validate command to validate the configuration
$terraformvalidate
Once validation succeeded you can use terraform plan command to see what Terraform needs to do to achieve described infrastructure.
$terraformplan
Run terraform apply command to deploy your resources. Verify displayed execution plan and type yes to confirm.
Depending on the type of change you want to do, Terraform will perform an update in-place (e.g tag change) or destroy and then create a replacement (e.g AMI change).
$terraformplanaws_instance.webserver:Refreshingstate... [id=i-08839e4a788d49081]Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
~updatein-placeTerraformwillperformthefollowingactions:# aws_instance.webserver will be updated in-place~resource"aws_instance""webserver"{id="i-08839e4a788d49081"~tags={~"Name"="TerraformWorkshops" ->"TerraformWorkshops2021" }~tags_all={~"Name"="TerraformWorkshops" ->"TerraformWorkshops2021" }# (27 unchanged attributes hidden)# (5 unchanged blocks hidden) }Plan:0toadd,1tochange,0todestroy.
Go to EC2 Dashboard on AWS Console to see created EC2 instance.
The EC2 instance is created in the default VPC and assigned to the default Security Group (you can think about it as a virtual firewall) that controls incoming and outgoing traffic. By default Security Group has rules that allow communication between resources in this Security Group.
Let's create SSH key pair and use it to connect to the EC2 instance.
Make the following update to add key pair and security group with ingress and egress rules and use them with the EC2 instance:
terraform/webserver/main.tf
@@-14,9+14,44@@provider"aws"{region="eu-central-1" }+resource"aws_security_group""webserver"{+description="Security group for webserver"++ingress{+description="Allow SSH from everywhere"+protocol="tcp"+from_port=22+to_port=22+cidr_blocks= ["0.0.0.0/0"]+}++ingress{+description="Allow inbound on port 5000"+protocol="tcp"+from_port=5000+to_port=5000+cidr_blocks= ["0.0.0.0/0"]+}++egress{+description="Allow outboud traffic on all ports"+protocol="-1"+from_port=0+to_port=0+cidr_blocks= ["0.0.0.0/0"]+}+}++resource"aws_key_pair""my_ec2_key_pair"{+key_name="my-ec2-key-pair"+public_key=file("~/myEC2KeyPair.pub")+}+resource"aws_instance""webserver"{-ami="ami-091f21ecba031b39a"-instance_type="t2.micro"+ami="ami-091f21ecba031b39a"+instance_type="t2.micro"+key_name=aws_key_pair.my_ec2_key_pair.key_name+vpc_security_group_ids= [aws_security_group.webserver.id]tags={Name="TerraformWorkshops"
Run terraform apply command to update your resources.
Once changes are done, go to AWS Console and find the public IP address of your instance and connect via SSH (make sure to use your EC2 instance IP address instead of 3.120.139.14):
$ssh-i~/myEC2KeyPairubuntu@3.120.139.14WelcometoUbuntu20.04.3LTS (GNU/Linux 5.11.0-1017-awsx86_64)*Documentation:https://help.ubuntu.com*Management:https://landscape.canonical.com*Support:https://ubuntu.com/advantageSysteminformationasofThuOct720:23:51UTC2021Systemload:0.08Processes:97Usageof/:16.9%of7.69GBUsersloggedin:0Memoryusage:19%IPv4addressforeth0:172.31.40.78Swapusage:0%1updatecanbeappliedimmediately.Toseetheseadditionalupdatesrun:aptlist--upgradableThelistofavailableupdatesismorethanaweekold.Tocheckfornewupdatesrun:sudoaptupdateTheprogramsincludedwiththeUbuntusystemarefreesoftware;theexactdistributiontermsforeachprogramaredescribedintheindividualfilesin/usr/share/doc/*/copyright.UbuntucomeswithABSOLUTELYNOWARRANTY,totheextentpermittedbyapplicablelaw.Torunacommandasadministrator (user "root"), use "sudo <command>".See"man sudo_root"fordetails.ubuntu@ip-172-31-40-78:~$
Verify if the instance can connect to the Internet by running sudo apt-get update command: