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:

    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. https://hub.docker.com/ ).


    1. 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:

    • https://registry.terraform.io/modules/terraform-aws-modules/ec2-instance/aws/latest
    • https://gitlab.com/nanuchi/terraform-learn/-/tree/feature/deploy-to-ec2


Suggested Topics

  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2