Answers: <p>I think it is better if you containerize your flask application. So:</p>
  <ol>
  <li>Containerize your flask application.</li>
  <li>Create and configure an EC2 server to deploy your application container on it.</li>
  </ol>
  <hr />
  <ol>
  <li>Containerize your flask application.</li>
  </ol>
  <p>I'm not gonna walk you through this but basically you should create a <code>Dockerfile</code> and create an image based on that. then push it to any repo you like (e.g. <a href="https://hub.docker.com/" rel="nofollow noreferrer">Docker Hub</a>).</p>
  <hr />
  <ol start="2">
  <li>Create and configure an EC2 server to deploy your application container on it.</li>
  </ol>
  <p>Here is an example that will create and config an EC2 server, install Docker on it and then run an container from your image (in this example: Nginx)</p>
  <pre><code>provider &quot;aws&quot; {
    region = &quot;eu-central-1&quot;
  }
  
  variable vpc_cidr_block {}
  variable subnet_1_cidr_block {}
  variable avail_zone {}
  variable env_prefix {}
  variable instance_type {}
  variable ssh_key {}
  variable my_ip {}
  
  data &quot;aws_ami&quot; &quot;amazon-linux-image&quot; {
    most_recent = true
    owners      = [&quot;amazon&quot;]
  
    filter {
      name   = &quot;name&quot;
      values = [&quot;amzn2-ami-hvm-*-x86_64-gp2&quot;]
    }
  
    filter {
      name   = &quot;virtualization-type&quot;
      values = [&quot;hvm&quot;]
    }
  }
  
  output &quot;ami_id&quot; {
    value = data.aws_ami.amazon-linux-image.id
  }
  
  resource &quot;aws_vpc&quot; &quot;myapp-vpc&quot; {
    cidr_block = var.vpc_cidr_block
    tags = {
        Name = &quot;${var.env_prefix}-vpc&quot;
    }
  }
  
  resource &quot;aws_subnet&quot; &quot;myapp-subnet-1&quot; {
    vpc_id = aws_vpc.myapp-vpc.id
    cidr_block = var.subnet_1_cidr_block
    availability_zone = var.avail_zone
    tags = {
        Name = &quot;${var.env_prefix}-subnet-1&quot;
    }
  }
  
  resource &quot;aws_security_group&quot; &quot;myapp-sg&quot; {
    name   = &quot;myapp-sg&quot;
    vpc_id = aws_vpc.myapp-vpc.id
  
    ingress {
      from_port   = 22
      to_port     = 22
      protocol    = &quot;tcp&quot;
      cidr_blocks = [var.my_ip]
    }
  
    ingress {
      from_port   = 8080
      to_port     = 8080
      protocol    = &quot;tcp&quot;
      cidr_blocks = [&quot;0.0.0.0/0&quot;]
    }
  
    egress {
      from_port       = 0
      to_port         = 0
      protocol        = &quot;-1&quot;
      cidr_blocks     = [&quot;0.0.0.0/0&quot;]
      prefix_list_ids = []
    }
  
    tags = {
      Name = &quot;${var.env_prefix}-sg&quot;
    }
  }
  
  resource &quot;aws_internet_gateway&quot; &quot;myapp-igw&quot; {
      vpc_id = aws_vpc.myapp-vpc.id
      
      tags = {
       Name = &quot;${var.env_prefix}-internet-gateway&quot;
     }
  }
  
  resource &quot;aws_route_table&quot; &quot;myapp-route-table&quot; {
     vpc_id = aws_vpc.myapp-vpc.id
  
     route {
       cidr_block = &quot;0.0.0.0/0&quot;
       gateway_id = aws_internet_gateway.myapp-igw.id
     }
  
     # default route, mapping VPC CIDR block to &quot;local&quot;, created implicitly and cannot be specified.
  
     tags = {
       Name = &quot;${var.env_prefix}-route-table&quot;
     }
   }
  
  # Associate subnet with Route Table
  resource &quot;aws_route_table_association&quot; &quot;a-rtb-subnet&quot; {
    subnet_id      = aws_subnet.myapp-subnet-1.id
    route_table_id = aws_route_table.myapp-route-table.id
  }
  
  resource &quot;aws_key_pair&quot; &quot;ssh-key&quot; {
    key_name   = &quot;myapp-key&quot;
    public_key = file(var.ssh_key)
  }
  
  output &quot;server-ip&quot; {
      value = aws_instance.myapp-server.public_ip
  }
  
  resource &quot;aws_instance&quot; &quot;myapp-server&quot; {
    ami                         = data.aws_ami.amazon-linux-image.id
    instance_type               = var.instance_type
    key_name                    = &quot;myapp-key&quot;
    associate_public_ip_address = true
    subnet_id                   = aws_subnet.myapp-subnet-1.id
    vpc_security_group_ids      = [aws_security_group.myapp-sg.id]
    availability_zone               = var.avail_zone
  
    tags = {
      Name = &quot;${var.env_prefix}-server&quot;
    }
  
    user_data = &lt;&lt;EOF
                   #!/bin/bash
                   apt-get update &amp;&amp; apt-get install -y docker-ce
                   systemctl start docker
                   usermod -aG docker ec2-user
                   docker run -p 8080:8080 nginx
                EOF
  }
  </code></pre>
  <hr />
  <p>Sources:</p>
  <ul>
  <li><a href="https://registry.terraform.io/modules/terraform-aws-modules/ec2-instance/aws/latest" rel="nofollow noreferrer">Terraform module which creates EC2 instance(s) on AWS</a></li>
  <li><a href="https://gitlab.com/nanuchi/terraform-learn/-/tree/feature/deploy-to-ec2" rel="nofollow noreferrer">Deploy an container to EC2 using Terraform</a></li>
  </ul>
  
Answers: CC BY-SA 4.0
Answers: 2022-08-15T12:35:25.453Z
Answers: 2022-08-15T12:35:25.453Z
Answers: Ali
Body: <p>I am new to Terraform. How can I use Terraform to configure EC2 instance for hosting a flask web application?</p>
  <ul>
  <li><p>Is it to configure a security group for the instance? How is that done in Terraform?</p>
  </li>
  <li><p>what else can Terraform be used to configure for hosting a web application?</p>
  </li>
  <li><p>Does Terraform also perform deployment of web application to the infrastructure, besides creating the infrastructure?</p>
  </li>
  </ul>
  <p>I also wonder how? (links to documents are also appreciated.)</p>
  <p>Thanks.</p>
  
Tags: <amazon-web-services><terraform><amazon-ec2>
Title: What can Terraform be used to configure for hosting a web application?
UserDisplayName: Tim
ThreadText: # What can Terraform be used to configure for hosting a web application?
  
  (Asked by: username_0 on 2022-08-15)
  
  I am new to Terraform. How can I use Terraform to configure EC2 instance for hosting a flask web application?
  
  * Is it to configure a security group for the instance? How is that done in Terraform?
  * what else can Terraform be used to configure for hosting a web application?
  * Does Terraform also perform deployment of web application to the infrastructure, besides creating the infrastructure?
  
  I also wonder how? (links to documents are also appreciated.)
  
  Thanks.
  
  **Tags:** amazon-web-services, terraform, amazon-ec2
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2022-08-15. Score: 3
  
  I think it is better if you containerize your flask application. So:
  
  1. Containerize your flask application.
  2. Create and configure an EC2 server to deploy your application container on it.
  
  ---
  
  1. Containerize your flask application.
  
  I'm not gonna walk you through this but basically you should create a `Dockerfile` and create an image based on that. then push it to any repo you like (e.g. [Docker Hub](https://hub.docker.com/)).
  
  ---
  
  2. Create and configure an EC2 server to deploy your application container on it.
  
  Here is an example that will create and config an EC2 server, install Docker on it and then run an container from your image (in this example: Nginx)
  
  ```
  provider "aws" {
    region = "eu-central-1"
  }
  
  variable vpc_cidr_block {}
  variable subnet_1_cidr_block {}
  variable avail_zone {}
  variable env_prefix {}
  variable instance_type {}
  variable ssh_key {}
  variable my_ip {}
  
  data "aws_ami" "amazon-linux-image" {
    most_recent = true
    owners      = ["amazon"]
  
    filter {
      name   = "name"
      values = ["amzn2-ami-hvm-*-x86_64-gp2"]
    }
  
    filter {
      name   = "virtualization-type"
      values = ["hvm"]
    }
  }
  
  output "ami_id" {
    value = data.aws_ami.amazon-linux-image.id
  }
  
  resource "aws_vpc" "myapp-vpc" {
    cidr_block = var.vpc_cidr_block
    tags = {
        Name = "${var.env_prefix}-vpc"
    }
  }
  
  resource "aws_subnet" "myapp-subnet-1" {
    vpc_id = aws_vpc.myapp-vpc.id
    cidr_block = var.subnet_1_cidr_block
    availability_zone = var.avail_zone
    tags = {
        Name = "${var.env_prefix}-subnet-1"
    }
  }
  
  resource "aws_security_group" "myapp-sg" {
    name   = "myapp-sg"
    vpc_id = aws_vpc.myapp-vpc.id
  
    ingress {
      from_port   = 22
      to_port     = 22
      protocol    = "tcp"
      cidr_blocks = [var.my_ip]
    }
  
    ingress {
      from_port   = 8080
      to_port     = 8080
      protocol    = "tcp"
      cidr_blocks = ["0.0.0.0/0"]
    }
  
    egress {
      from_port       = 0
      to_port         = 0
      protocol        = "-1"
      cidr_blocks     = ["0.0.0.0/0"]
      prefix_list_ids = []
    }
  
    tags = {
      Name = "${var.env_prefix}-sg"
    }
  }
  
  resource "aws_internet_gateway" "myapp-igw" {
      vpc_id = aws_vpc.myapp-vpc.id
      
      tags = {
       Name = "${var.env_prefix}-internet-gateway"
     }
  }
  
  resource "aws_route_table" "myapp-route-table" {
     vpc_id = aws_vpc.myapp-vpc.id
  
     route {
       cidr_block = "0.0.0.0/0"
       gateway_id = aws_internet_gateway.myapp-igw.id
     }
  
     # default route, mapping VPC CIDR block to "local", created implicitly and cannot be specified.
  
     tags = {
       Name = "${var.env_prefix}-route-table"
     }
   }
  
  # Associate subnet with Route Table
  resource "aws_route_table_association" "a-rtb-subnet" {
    subnet_id      = aws_subnet.myapp-subnet-1.id
    route_table_id = aws_route_table.myapp-route-table.id
  }
  
  resource "aws_key_pair" "ssh-key" {
    key_name   = "myapp-key"
    public_key = file(var.ssh_key)
  }
  
  output "server-ip" {
      value = aws_instance.myapp-server.public_ip
  }
  
  resource "aws_instance" "myapp-server" {
    ami                         = data.aws_ami.amazon-linux-image.id
    instance_type               = var.instance_type
    key_name                    = "myapp-key"
    associate_public_ip_address = true
    subnet_id                   = aws_subnet.myapp-subnet-1.id
    vpc_security_group_ids      = [aws_security_group.myapp-sg.id]
    availability_zone               = var.avail_zone
  
    tags = {
      Name = "${var.env_prefix}-server"
    }
  
    user_data = <<EOF
                   #!/bin/bash
                   apt-get update && apt-get install -y docker-ce
                   systemctl start docker
                   usermod -aG docker ec2-user
                   docker run -p 8080:8080 nginx
                EOF
  }
  
  ```
  
  ---
  
  Sources:
  
  * [Terraform module which creates EC2 instance(s) on AWS](https://registry.terraform.io/modules/terraform-aws-modules/ec2-instance/aws/latest)
  * [Deploy an container to EC2 using Terraform](https://gitlab.com/nanuchi/terraform-learn/-/tree/feature/deploy-to-ec2)
  
  
  ---
  
  