{"id":15580,"date":"2021-02-03T22:13:53","date_gmt":"2021-02-03T21:13:53","guid":{"rendered":"https:\/\/www.dbi-services.com\/blog\/aws-ec2-instance-deployment-with-terraform\/"},"modified":"2021-02-03T22:13:53","modified_gmt":"2021-02-03T21:13:53","slug":"aws-ec2-instance-deployment-with-terraform","status":"publish","type":"post","link":"https:\/\/www.dbi-services.com\/blog\/aws-ec2-instance-deployment-with-terraform\/","title":{"rendered":"AWS EC2 instance deployment with Terraform"},"content":{"rendered":"<p>When it comes to quickly provision a server in the Cloud, using an Infrastructure as Code (IaC) tool is a solution to consider.<br \/>\nThere are many IaC products available and among them, Terraform seems to be the most popular.<\/p>\n<p>The following is a non-exhaustive list of Terraform advantages :<br \/>\n&#8211; Terraform can deploy infrastructure to multiple cloud service providers simultaneously<br \/>\n&#8211; With Terraform, you can easily preview and validate infrastructure changes before they are applied<br \/>\n&#8211; The code is written in a declarative way. Not procedural<br \/>\n&#8211; Terraform creates immutable infrastructure (using configuration snapshots)<\/p>\n<p><a href=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/download-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-46927\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/download-1.png\" alt=\"\" width=\"459\" height=\"110\" \/><\/a><br \/>\nIn this post, we are going to deploy an AWS EC2 instance and all the related network components (and their features) required to access it through SSH.<br \/>\nFor that it&#8217;s necessary to deploy following AWS services :<br \/>\n&#8211; VPC (Virtual Private Cloud)<br \/>\n&#8211; Security Group<br \/>\n&#8211; Subnet<br \/>\n&#8211; Route Table<br \/>\n&#8211; Internet Gateway<br \/>\n&#8211; And finally the EC2 instance<\/p>\n<p>For a better manageability I do recommend to create one dedicated file per service listed above. This will also give a good overview what the Terraform Configuration is made of :<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1\">joc@joc:$ tree\n.\n\u251c\u2500\u2500 aws-config.tf\n\u251c\u2500\u2500 create-igw.tf\n\u251c\u2500\u2500 create-instance.tf\n\u251c\u2500\u2500 create-rt.tf\n\u251c\u2500\u2500 create-sbn.tf\n\u251c\u2500\u2500 create-sg.tf\n\u251c\u2500\u2500 create-vpc.tf\n\u251c\u2500\u2500 variables_output.tf\n\u2514\u2500\u2500 variables.tf\n\n0 directories, 9 files<\/pre>\n<p>&nbsp;<\/p>\n<h3>Variables<\/h3>\n<p>Using variables in a Terraform Configuration is a good practice. Like with all other tools and programming languages, their purpose is to create a value only once and to reuse it across the whole deployment configuration.<br \/>\nThe best is to create a dedicated file to store them. Here&#8217;s what mine looks like :<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1\"># variables.tf\n\n# Variables for general information\n######################################\n\nvariable \"aws_region\" {\n  description = \"AWS region\"\n  type        = string\n  default     = \"eu-central-1\"\n}\n\nvariable \"owner\" {\n  description = \"Configuration owner\"\n  type        = string\n}\n\nvariable \"aws_region_az\" {\n  description = \"AWS region availability zone\"\n  type        = string\n  default     = \"a\"\n}\n\n\n# Variables for VPC\n######################################\n\nvariable \"vpc_cidr_block\" {\n  description = \"CIDR block for the VPC\"\n  type        = string\n  default     = \"10.0.0.0\/16\"\n}\n\nvariable \"vpc_dns_support\" {\n  description = \"Enable DNS support in the VPC\"\n  type        = bool\n  default     = true\n}\n\nvariable \"vpc_dns_hostnames\" {\n  description = \"Enable DNS hostnames in the VPC\"\n  type        = bool\n  default     = true\n}\n\n\n# Variables for Security Group\n######################################\n\nvariable \"sg_ingress_proto\" {\n  description = \"Protocol used for the ingress rule\"\n  type        = string\n  default     = \"tcp\"\n}\n\nvariable \"sg_ingress_ssh\" {\n  description = \"Port used for the ingress rule\"\n  type        = string\n  default     = \"22\"\n}\n\nvariable \"sg_egress_proto\" {\n  description = \"Protocol used for the egress rule\"\n  type        = string\n  default     = \"-1\"\n}\n\nvariable \"sg_egress_all\" {\n  description = \"Port used for the egress rule\"\n  type        = string\n  default     = \"0\"\n}\n\nvariable \"sg_egress_cidr_block\" {\n  description = \"CIDR block for the egress rule\"\n  type        = string\n  default     = \"0.0.0.0\/0\"\n}\n\n\n# Variables for Subnet\n######################################\n\nvariable \"sbn_public_ip\" {\n  description = \"Assign public IP to the instance launched into the subnet\"\n  type        = bool\n  default     = true\n}\n\nvariable \"sbn_cidr_block\" {\n  description = \"CIDR block for the subnet\"\n  type        = string\n  default     = \"10.0.1.0\/24\"\n}\n\n\n# Variables for Route Table\n######################################\n\nvariable \"rt_cidr_block\" {\n  description = \"CIDR block for the route table\"\n  type        = string\n  default     = \"0.0.0.0\/0\"\n}\n\n\n# Variables for Instance\n######################################\n\nvariable \"instance_ami\" {\n  description = \"ID of the AMI used\"\n  type        = string\n  default     = \"ami-0211d10fb4a04824a\"\n}\n\nvariable \"instance_type\" {\n  description = \"Type of the instance\"\n  type        = string\n  default     = \"t2.medium\"\n}\n\nvariable \"key_pair\" {\n  description = \"SSH Key pair used to connect\"\n  type        = string\n  default     = \"joc-key-pair\"\n}\n\nvariable \"root_device_type\" {\n  description = \"Type of the root block device\"\n  type        = string\n  default     = \"gp2\"\n}\n\nvariable \"root_device_size\" {\n  description = \"Size of the root block device\"\n  type        = string\n  default     = \"50\"\n}<\/pre>\n<p>Each of these variable will be used to describe our environment and they will need to be prefixed by <em>var.<\/em> when we will be using them.<br \/>\nLet&#8217;s start with the first step.<\/p>\n<h3>Provider<\/h3>\n<p>As already said, Terraform supports infrastructure deployment to several Cloud providers. Thus, the first things to do in our Configuration is to define the provider we want to use.<br \/>\nAs the providers&#8217; API have several versions available, it&#8217;s important to define a version constraint to force Terraform to select a single version<br \/>\nthat all parts of your configuration are compatible with. If you don&#8217;t do that you take the risk to use a newer version that might not be compatible with your Configuration.<br \/>\nA good way to force the maximum version we want to work with is to use the ~&gt; operator. This will allow to use only patch releases within a specific minor release :<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1\"># aws_config.tf\n\nterraform {\n  required_providers {\n    aws = {\n      source  = \"hashicorp\/aws\"\n      version = \"~&gt; 3.26\"\n    }\n  }\n}\n\nprovider \"aws\" {\n  profile = \"default\"\n  region  = var.aws_region\n}<\/pre>\n<p>As I don&#8217;t set my AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY (security), Terraform will use the one coming from my environment variables.<\/p>\n<h3>VPC<\/h3>\n<p>VPC (Virtual Private Cloud) is one of the fundamental component to create when starting an AWS project. It allows to launch resources in a virtual and isolated network. Creating a VPC is optional, but it becomes mandatory when you want to create interconnections with others networks or if you want to isolate some EC2 instances in a subnet unreachable from outside :<\/p>\n<div>\n<pre class=\"brush: bash; gutter: true; first-line: 1\"># create-vpc.tf\n\nresource \"aws_vpc\" \"vpc\" {\n  cidr_block           = var.vpc_cidr_block\n  enable_dns_hostnames = var.vpc_dns_hostnames\n  enable_dns_support   = var.vpc_dns_support\n\n  tags = {\n    \"Owner\" = var.owner\n    \"Name\"  = \"${var.owner}-vpc\"\n  }\n}<\/pre>\n<p>This defines the IP range that will be used and enable DNS support and hostname so the instance can get a DNS name.<\/p>\n<h3 class=\"brush: bash; gutter: true; first-line: 1\">Security Group<\/h3>\n<\/div>\n<p>To control inbound and outbound access to an EC2 instance, it&#8217;s required to create a Security Group.<br \/>\nA Security Group is like the local firewall of the instance. If we want to be able to connect to the instance via SSH we need to create an ingress rule allowing our IP to connect to TCP port 22.<br \/>\nIn order to be able to connect to the instance from wherever we are located (home, office, &#8230;), let&#8217;s store our current public IP using the <a href=\"https:\/\/www.terraform.io\/docs\/language\/data-sources\/index.html\" target=\"_blank\" rel=\"noopener\">data sources<\/a> module of Terraform. Then it can be used as a variable to define the value of the <em>cidr_blocks<\/em> argument in the <em>ingress<\/em> attributes :<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1\"># create-sg.tf\n\ndata \"http\" \"myip\" {\n  url = \"http:\/\/ipv4.icanhazip.com\"\n}\n\nresource \"aws_security_group\" \"sg\" {\n  name        = \"${var.owner}-sg\"\n  description = \"Allow inbound traffic via SSH\"\n  vpc_id      = aws_vpc.vpc.id\n\n  ingress = [{\n    description      = \"My public IP\"\n    protocol         = var.sg_ingress_proto\n    from_port        = var.sg_ingress_ssh\n    to_port          = var.sg_ingress_ssh\n    cidr_blocks      = [\"${chomp(data.http.myip.body)}\/32\"]\n    ipv6_cidr_blocks = []\n    prefix_list_ids  = []\n    security_groups  = []\n    self             = false\n\n  }]\n\n  egress = [{\n    description      = \"All traffic\"\n    protocol         = var.sg_egress_proto\n    from_port        = var.sg_egress_all\n    to_port          = var.sg_egress_all\n    cidr_blocks      = [var.sg_egress_cidr_block]\n    ipv6_cidr_blocks = []\n    prefix_list_ids  = []\n    security_groups  = []\n    self             = false\n\n  }]\n\n  tags = {\n    \"Owner\" = var.owner\n    \"Name\"  = \"${var.owner}-sg\"\n  }\n}<\/pre>\n<p>A second rules exists in this Security Group to allow the instance to connect outside.<\/p>\n<h3>Subnet<\/h3>\n<p>A subnet must be created inside the VPC, with its own CIDR block, which is a subset of the VPC CIDR block :<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1\">#create-sbn.tf\n\nresource \"aws_subnet\" \"subnet\" {\n  vpc_id                  = aws_vpc.vpc.id\n  cidr_block              = var.sbn_cidr_block\n  map_public_ip_on_launch = var.sbn_public_ip\n  availability_zone       = \"${var.aws_region}${var.aws_region_az}\"\n\n  tags = {\n    \"Owner\" = var.owner\n    \"Name\"  = \"${var.owner}-subnet\"\n  }\n}\n<\/pre>\n<p>If you plan to create more than one subnet, think about deploying them into different Availability Zones.<\/p>\n<h3>Internet Gateway<\/h3>\n<p>We also need an Internet Gateway to enable access over the Internet.<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1\"># create-igw.tf\n\nresource \"aws_internet_gateway\" \"igw\" {\n  vpc_id = aws_vpc.vpc.id\n\n  tags = {\n    \"Owner\" = var.owner\n    \"Name\"  = \"${var.owner}-igw\"\n  }\n}<\/pre>\n<p>If the traffic of a subnet is routed to the Internet Gateway, the subnet is known as a <em>public subnet<\/em>. That means that all instances connected to this subnet can connect the Internet through the Internet Gateway.<br \/>\nTo define this association, we need a Route Table :<\/p>\n<h3>Route Table<\/h3>\n<pre class=\"brush: bash; gutter: true; first-line: 1\">#create-rt.tf\n\nresource \"aws_route_table\" \"rt\" {\n  vpc_id = aws_vpc.vpc.id\n\n  route {\n    cidr_block = var.rt_cidr_block\n    gateway_id = aws_internet_gateway.igw.id\n  }\n\n  tags = {\n    \"Owner\" = var.owner\n    \"Name\"  = \"${var.owner}-rt\"\n  }\n\n}<\/pre>\n<p>The link between the subnet and the route table is done by creating an association :<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1\">resource \"aws_route_table_association\" \"rt_sbn_asso\" {\n  subnet_id      = aws_subnet.subnet.id\n  route_table_id = aws_route_table.rt.id\n}<\/pre>\n<p>&nbsp;<\/p>\n<h3>Instance<\/h3>\n<p>The network layer is now ready. We can create the EC2 instance in the subnet of our VPC :<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1\"># create-instance.tf\n\nresource \"aws_instance\" \"instance\" {\n  ami                         = var.instance_ami\n  availability_zone           = \"${var.aws_region}${var.aws_region_az}\"\n  instance_type               = var.instance_type\n  associate_public_ip_address = true\n  vpc_security_group_ids      = [aws_security_group.sg.id]\n  subnet_id                   = aws_subnet.subnet.id\n  key_name                    = var.key_pair\n\n  root_block_device {\n    delete_on_termination = true\n    encrypted             = false\n    volume_size           = var.root_device_size\n    volume_type           = var.root_device_type\n  }\n\n  tags = {\n    \"Owner\"               = var.owner\n    \"Name\"                = \"${var.owner}-instance\"\n    \"KeepInstanceRunning\" = \"false\"\n  }\n}<\/pre>\n<p>&nbsp;<\/p>\n<h3>Init<\/h3>\n<p>Everything is ready. To start the deployment, we need first of all to initialize our working directory :<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1\">joc@joc:$ terraform init\n\nInitializing the backend...\n\nInitializing provider plugins...\n- Finding latest version of hashicorp\/http...\n- Finding hashicorp\/aws versions matching \"~&gt; 3.26\"...\n- Installing hashicorp\/http v2.0.0...\n- Installed hashicorp\/http v2.0.0 (signed by HashiCorp)\n- Installing hashicorp\/aws v3.26.0...\n- Installed hashicorp\/aws v3.26.0 (signed by HashiCorp)\n\nTerraform has created a lock file .terraform.lock.hcl to record the provider\nselections it made above. Include this file in your version control repository\nso that Terraform can guarantee to make the same selections by default when\nyou run \"terraform init\" in the future.\n\nTerraform has been successfully initialized!\n\nYou may now begin working with Terraform. Try running \"terraform plan\" to see\nany changes that are required for your infrastructure. All Terraform commands\nshould now work.\n\nIf you ever set or change modules or backend configuration for Terraform,\nrerun this command to reinitialize your working directory. If you forget, other\ncommands will detect it and remind you to do so if necessary.\njoc@joc:$<\/pre>\n<p>&nbsp;<\/p>\n<h3>Validate<\/h3>\n<p>Then we can check if the code of our Configuration is syntactically valid :<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1\">joc@joc:$ terraform validate\nSuccess! The configuration is valid.\n\njoc@joc:$<\/pre>\n<p>&nbsp;<\/p>\n<h3>Plan<\/h3>\n<p>Terraform can show what will be deployed using the <em>plan<\/em> command. This is very useful to check all the resources before creating them.<br \/>\nAs the output is quite long I&#8217;ll truncate it and keep only some lines :<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1; highlight: [5]\">joc@joc:$ terraform plan\nvar.owner\n  Configuration owner\n\n  Enter a value: joc\n\n\nAn execution plan has been generated and is shown below.\nResource actions are indicated with the following symbols:\n  + create\n\nTerraform will perform the following actions:\n...\n...\n...\nPlan: 7 to add, 0 to change, 0 to destroy.\n\nChanges to Outputs:\n  + public_ip = (known after apply)\n\n------------------------------------------------------------------------\n\nNote: You didn't specify an \"-out\" parameter to save this plan, so Terraform\ncan't guarantee that exactly these actions will be performed if\n\"terraform apply\" is subsequently run.\n\njoc@joc:~$<\/pre>\n<p>At line n\u00b0 5 we are prompted to give a name to the owner of the Configuration. This is because we didn&#8217;t set a default value to the variable &#8220;owner&#8221; (see variables.tf). As you may have noticed, this variable is regularly used to name the resources as well as to tag them. This will be helpful when working with these resources.<\/p>\n<h3>Apply<\/h3>\n<p>Finally we can apply the execution plan and everything will be created in few minutes only :<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1; highlight: [38]\">joc@joc:$ terraform apply\nvar.owner\n  Configuration owner\n\n  Enter a value: joc\n\n\nAn execution plan has been generated and is shown below.\nResource actions are indicated with the following symbols:\n  + create\n\nTerraform will perform the following actions:\n...\n...\n...\naws_vpc.vpc: Creating...\naws_vpc.vpc: Creation complete after 3s [id=vpc-00aa8a9136306adf2]\naws_internet_gateway.igw: Creating...\naws_subnet.subnet: Creating...\naws_security_group.sg: Creating...\naws_internet_gateway.igw: Creation complete after 1s [id=igw-069cde646f3d4967f]\naws_route_table.rt: Creating...\naws_subnet.subnet: Creation complete after 1s [id=subnet-07034f2432203028e]\naws_route_table.rt: Creation complete after 0s [id=rtb-06fd67d98d0d8d24c]\naws_route_table_association.rt_sbn_asso: Creating...\naws_route_table_association.rt_sbn_asso: Creation complete after 1s [id=rtbassoc-04b8fd0f0984d648b]\naws_security_group.sg: Creation complete after 2s [id=sg-0c3547bc9189af478]\naws_instance.instance: Creating...\naws_instance.instance: Still creating... [10s elapsed]\naws_instance.instance: Still creating... [20s elapsed]\naws_instance.instance: Still creating... [30s elapsed]\naws_instance.instance: Creation complete after 33s [id=i-0c102b97c854bbb80]\n\nApply complete! Resources: 7 added, 0 changed, 0 destroyed.\n\nOutputs:\n\npublic_ip = \"18.194.28.183\"\njoc@joc:$<\/pre>\n<p>The last line displays the public IP of the newly created instance. The is done thanks to the output variable defined into the file <em>variables_output.tf<\/em> :<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1\"># variable_output.tf\n\n# Variables to show after the deployment\n#########################################\n\noutput \"public_ip\" {\n  value = aws_instance.instance.public_ip\n}<\/pre>\n<p>&nbsp;<\/p>\n<p>We should now be able to connect to the instance :<\/p>\n<pre class=\"brush: bash; gutter: true; first-line: 1\">joc@joc:$ ssh -i \"~\/joc-key-pair.pem\" ec2-user@18.194.28.183\nThe authenticity of host '18.194.28.183 (18.194.28.183)' can't be established.\nECDSA key fingerprint is SHA256:aFg3EBxHgGENRKvFyMpZbfFPbAqz0RRiZqpsXM8T1po.\nAre you sure you want to continue connecting (yes\/no\/[fingerprint])? yes\nWarning: Permanently added '18.194.28.183' (ECDSA) to the list of known hosts.\n[ec2-user@ip-10-0-1-194 ~]$<\/pre>\n<p>&nbsp;<\/p>\n<p>That&#8217;s it ! Let&#8217;s see what it looks like from the AWS Console&#8230;<\/p>\n<p>VPC :<\/p>\n<p><a href=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/vpc.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-47119\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/vpc.jpg\" alt=\"\" width=\"849\" height=\"137\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>Security Group :<\/p>\n<p><a href=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/sg.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-47120\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/sg.png\" alt=\"\" width=\"1350\" height=\"137\" \/><\/a><\/p>\n<p>Subnet :<\/p>\n<p><a href=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/subnet.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-47122\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/subnet.png\" alt=\"\" width=\"1011\" height=\"139\" \/><\/a><\/p>\n<p>Internet Gateway :<\/p>\n<p><a href=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/igw.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-47123\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/igw.jpg\" alt=\"\" width=\"992\" height=\"126\" \/><\/a><\/p>\n<p>Route Table :<\/p>\n<p><a href=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/rt.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-47124\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/rt.jpg\" alt=\"\" width=\"1155\" height=\"115\" \/><\/a><\/p>\n<p>Instance :<\/p>\n<p><a href=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/inst.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-47128\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/inst.png\" alt=\"\" width=\"948\" height=\"143\" \/><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>When it comes to quickly provision a server in the Cloud, using an Infrastructure as Code (IaC) tool is a solution to consider. There are many IaC products available and among them, Terraform seems to be the most popular. The following is a non-exhaustive list of Terraform advantages : &#8211; Terraform can deploy infrastructure to [&hellip;]<\/p>\n","protected":false},"author":30,"featured_media":15581,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1865,955],"tags":[133,135,769,1883,2242,1340],"type_dbi":[],"class_list":["post-15580","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-aws","category-cloud","tag-aws","tag-cloud","tag-deployment","tag-ec2","tag-iac","tag-terraform"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.2 (Yoast SEO v27.2) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>AWS EC2 instance deployment with Terraform - dbi Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.dbi-services.com\/blog\/aws-ec2-instance-deployment-with-terraform\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"AWS EC2 instance deployment with Terraform\" \/>\n<meta property=\"og:description\" content=\"When it comes to quickly provision a server in the Cloud, using an Infrastructure as Code (IaC) tool is a solution to consider. There are many IaC products available and among them, Terraform seems to be the most popular. The following is a non-exhaustive list of Terraform advantages : &#8211; Terraform can deploy infrastructure to [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.dbi-services.com\/blog\/aws-ec2-instance-deployment-with-terraform\/\" \/>\n<meta property=\"og:site_name\" content=\"dbi Blog\" \/>\n<meta property=\"article:published_time\" content=\"2021-02-03T21:13:53+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/download-1.png\" \/>\n\t<meta property=\"og:image:width\" content=\"459\" \/>\n\t<meta property=\"og:image:height\" content=\"110\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Jo\u00ebl Cattin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jo\u00ebl Cattin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/aws-ec2-instance-deployment-with-terraform\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/aws-ec2-instance-deployment-with-terraform\/\"},\"author\":{\"name\":\"Jo\u00ebl Cattin\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/2c774f00321ee734515f0c2f6a96b780\"},\"headline\":\"AWS EC2 instance deployment with Terraform\",\"datePublished\":\"2021-02-03T21:13:53+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/aws-ec2-instance-deployment-with-terraform\/\"},\"wordCount\":986,\"commentCount\":1,\"image\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/aws-ec2-instance-deployment-with-terraform\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/download-1.png\",\"keywords\":[\"AWS\",\"Cloud\",\"Deployment\",\"EC2\",\"iac\",\"Terraform\"],\"articleSection\":[\"AWS\",\"Cloud\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.dbi-services.com\/blog\/aws-ec2-instance-deployment-with-terraform\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/aws-ec2-instance-deployment-with-terraform\/\",\"url\":\"https:\/\/www.dbi-services.com\/blog\/aws-ec2-instance-deployment-with-terraform\/\",\"name\":\"AWS EC2 instance deployment with Terraform - dbi Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/aws-ec2-instance-deployment-with-terraform\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/aws-ec2-instance-deployment-with-terraform\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/download-1.png\",\"datePublished\":\"2021-02-03T21:13:53+00:00\",\"author\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/2c774f00321ee734515f0c2f6a96b780\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/aws-ec2-instance-deployment-with-terraform\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.dbi-services.com\/blog\/aws-ec2-instance-deployment-with-terraform\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/aws-ec2-instance-deployment-with-terraform\/#primaryimage\",\"url\":\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/download-1.png\",\"contentUrl\":\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/download-1.png\",\"width\":459,\"height\":110},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/aws-ec2-instance-deployment-with-terraform\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\/\/www.dbi-services.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"AWS EC2 instance deployment with Terraform\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#website\",\"url\":\"https:\/\/www.dbi-services.com\/blog\/\",\"name\":\"dbi Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.dbi-services.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/2c774f00321ee734515f0c2f6a96b780\",\"name\":\"Jo\u00ebl Cattin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/secure.gravatar.com\/avatar\/a4271811924694263d4de5a469f8bd4a90b14d3d90e6ad819b9e2e5ac035a2dc?s=96&d=mm&r=g\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/a4271811924694263d4de5a469f8bd4a90b14d3d90e6ad819b9e2e5ac035a2dc?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/a4271811924694263d4de5a469f8bd4a90b14d3d90e6ad819b9e2e5ac035a2dc?s=96&d=mm&r=g\",\"caption\":\"Jo\u00ebl Cattin\"},\"description\":\"Jo\u00ebl Cattin has more than three years of experience in databases management. He is specialized in Oracle solutions such as Data Guard and RMAN and has a good background knowledge of Oracle Database Appliance (ODA), Real Application Cluster (RAC) and applications development on APEX. Jo\u00ebl Cattin\u2019s experience includes other RDBMS, such as PostgreSQL and MySQL. He is Oracle Database 12c Administrator Certified Professional, EDB Postgres Advanced Server 9.5 Certified Professional, RedHat Certified System Administrator and ITILv3 Foundation for Service Management Certified. Jo\u00ebl Cattin holds a degree from the \u00c9cole Sup\u00e9rieure d\u2019Informatique de Gestion (ESIG) in Del\u00e9mont and a Federal Certificate of Proficiency in Computer Science (Certificat f\u00e9d\u00e9ral de Capacit\u00e9 \u2013 CFC).\",\"url\":\"https:\/\/www.dbi-services.com\/blog\/author\/joel-cattin\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"AWS EC2 instance deployment with Terraform - dbi Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.dbi-services.com\/blog\/aws-ec2-instance-deployment-with-terraform\/","og_locale":"en_US","og_type":"article","og_title":"AWS EC2 instance deployment with Terraform","og_description":"When it comes to quickly provision a server in the Cloud, using an Infrastructure as Code (IaC) tool is a solution to consider. There are many IaC products available and among them, Terraform seems to be the most popular. The following is a non-exhaustive list of Terraform advantages : &#8211; Terraform can deploy infrastructure to [&hellip;]","og_url":"https:\/\/www.dbi-services.com\/blog\/aws-ec2-instance-deployment-with-terraform\/","og_site_name":"dbi Blog","article_published_time":"2021-02-03T21:13:53+00:00","og_image":[{"width":459,"height":110,"url":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/download-1.png","type":"image\/png"}],"author":"Jo\u00ebl Cattin","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Jo\u00ebl Cattin","Est. reading time":"11 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.dbi-services.com\/blog\/aws-ec2-instance-deployment-with-terraform\/#article","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/aws-ec2-instance-deployment-with-terraform\/"},"author":{"name":"Jo\u00ebl Cattin","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/2c774f00321ee734515f0c2f6a96b780"},"headline":"AWS EC2 instance deployment with Terraform","datePublished":"2021-02-03T21:13:53+00:00","mainEntityOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/aws-ec2-instance-deployment-with-terraform\/"},"wordCount":986,"commentCount":1,"image":{"@id":"https:\/\/www.dbi-services.com\/blog\/aws-ec2-instance-deployment-with-terraform\/#primaryimage"},"thumbnailUrl":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/download-1.png","keywords":["AWS","Cloud","Deployment","EC2","iac","Terraform"],"articleSection":["AWS","Cloud"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.dbi-services.com\/blog\/aws-ec2-instance-deployment-with-terraform\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.dbi-services.com\/blog\/aws-ec2-instance-deployment-with-terraform\/","url":"https:\/\/www.dbi-services.com\/blog\/aws-ec2-instance-deployment-with-terraform\/","name":"AWS EC2 instance deployment with Terraform - dbi Blog","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/aws-ec2-instance-deployment-with-terraform\/#primaryimage"},"image":{"@id":"https:\/\/www.dbi-services.com\/blog\/aws-ec2-instance-deployment-with-terraform\/#primaryimage"},"thumbnailUrl":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/download-1.png","datePublished":"2021-02-03T21:13:53+00:00","author":{"@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/2c774f00321ee734515f0c2f6a96b780"},"breadcrumb":{"@id":"https:\/\/www.dbi-services.com\/blog\/aws-ec2-instance-deployment-with-terraform\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.dbi-services.com\/blog\/aws-ec2-instance-deployment-with-terraform\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.dbi-services.com\/blog\/aws-ec2-instance-deployment-with-terraform\/#primaryimage","url":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/download-1.png","contentUrl":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/download-1.png","width":459,"height":110},{"@type":"BreadcrumbList","@id":"https:\/\/www.dbi-services.com\/blog\/aws-ec2-instance-deployment-with-terraform\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/www.dbi-services.com\/blog\/"},{"@type":"ListItem","position":2,"name":"AWS EC2 instance deployment with Terraform"}]},{"@type":"WebSite","@id":"https:\/\/www.dbi-services.com\/blog\/#website","url":"https:\/\/www.dbi-services.com\/blog\/","name":"dbi Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.dbi-services.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/2c774f00321ee734515f0c2f6a96b780","name":"Jo\u00ebl Cattin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/a4271811924694263d4de5a469f8bd4a90b14d3d90e6ad819b9e2e5ac035a2dc?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/a4271811924694263d4de5a469f8bd4a90b14d3d90e6ad819b9e2e5ac035a2dc?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/a4271811924694263d4de5a469f8bd4a90b14d3d90e6ad819b9e2e5ac035a2dc?s=96&d=mm&r=g","caption":"Jo\u00ebl Cattin"},"description":"Jo\u00ebl Cattin has more than three years of experience in databases management. He is specialized in Oracle solutions such as Data Guard and RMAN and has a good background knowledge of Oracle Database Appliance (ODA), Real Application Cluster (RAC) and applications development on APEX. Jo\u00ebl Cattin\u2019s experience includes other RDBMS, such as PostgreSQL and MySQL. He is Oracle Database 12c Administrator Certified Professional, EDB Postgres Advanced Server 9.5 Certified Professional, RedHat Certified System Administrator and ITILv3 Foundation for Service Management Certified. Jo\u00ebl Cattin holds a degree from the \u00c9cole Sup\u00e9rieure d\u2019Informatique de Gestion (ESIG) in Del\u00e9mont and a Federal Certificate of Proficiency in Computer Science (Certificat f\u00e9d\u00e9ral de Capacit\u00e9 \u2013 CFC).","url":"https:\/\/www.dbi-services.com\/blog\/author\/joel-cattin\/"}]}},"_links":{"self":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/15580","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/users\/30"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/comments?post=15580"}],"version-history":[{"count":0,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/15580\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/media\/15581"}],"wp:attachment":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/media?parent=15580"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/categories?post=15580"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/tags?post=15580"},{"taxonomy":"type","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/type_dbi?post=15580"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}