<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>

CC BY-SA 4.0
2022-08-15T12:35:25.453Z
2022-08-15T12:35:25.453Z
Ali
<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>

<amazon-web-services><terraform><amazon-ec2>
What can Terraform be used to configure for hosting a web application?
Tim
# 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:

Containerize your flask application.
Create and configure an EC2 server to deploy your application container on it.



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).


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 = <

Sources:

Terraform module which creates EC2 instance(s) on AWS
Deploy an container to EC2 using Terraform


---

