What can Terraform be used to configure for hosting a web application?
-
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.
-
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. https://hub.docker.com/ ).
- 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.idingress {
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.idtags = { Name = "${var.env_prefix}-internet-gateway"
}
}resource "aws_route_table" "myapp-route-table" {
vpc_id = aws_vpc.myapp-vpc.idroute {
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_zonetags = {
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:
- https://registry.terraform.io/modules/terraform-aws-modules/ec2-instance/aws/latest
- https://gitlab.com/nanuchi/terraform-learn/-/tree/feature/deploy-to-ec2