DEV Community

Cover image for Automated Deployments of Meteor.js bundle using Terraform
Purvesh Panchal
Purvesh Panchal

Posted on

Automated Deployments of Meteor.js bundle using Terraform

Automating Deployment on EC2 Instance with Terraform and Docker

Hey buddy! Tech can be tricky, but you’ve got this. Think of this as a tech chat over coffee...or my personal favorite, chaay (tea).

Let’s dive into how to automate deploying your Meteor.js project on AWS. By the end of this, you’ll feel like a cloud deployment ninja. Ready? Let’s go!

What You’ll Need

Before we roll up our sleeves, let’s gather our stuffff. Here's the checklist:

  1. AWS Credentials: Ensure you have the AWS CLI configured and ready to roll.

  2. Terraform: Download and install Terraform if you haven’t already.

  3. SSH Key Pair: Generate an SSH key pair. Keep the private key handy to connect to your instance later.

  4. Domain Name: Got a domain? Great! Make sure you can update its A records.

  5. Meteor Bundle: Prep your Meteor.js project bundle using this command:

   meteor build --server-only --directory ~/path/to/Dockerfile
Enter fullscreen mode Exit fullscreen mode
  1. Setup Scripts: You’ll need three scripts to set up the server:

Got everything? Awesome! Let’s start building.

The Game Plan

Here’s the journey we’re about to go on:

  1. Use Terraform to spin up an EC2 instance on AWS.
  2. Run some scripts to configure the server, install MongoDB, and deploy your Meteor.js app using Docker.
  3. Tweak your DNS settings to point your domain to the server’s IP.
  4. Finalize everything with SSL setup via Certbot.

Easy enough, right? Let’s break it down step by step.


Setting Up Terraform

Start by organizing your Terraform project. Create a directory structure like this:

project-directory/
├── main.tf
├── variables.tf
├── outputs.tf
├── run.sh
Enter fullscreen mode Exit fullscreen mode

Step 1: Variables Configuration

In variables.tf, define all the variables we’ll need. These make the setup flexible:

variable "server_name" {
  description = "Server created by Terraform"
  type        = string
  default     = "AutomatedDeployment"
}

variable "key_pair_name" {
  description = "Key pair name"
  type        = string
  default     = "tf-key-pair"
}

variable "domain_name" {
  description = "Your domain name"
  type        = string
  default     = "xyz.domain.com"
}
Enter fullscreen mode Exit fullscreen mode

Step 2: The Heart — main.tf

Here’s where the magic happens. This file sets up everything: EC2 instance, security groups, and provisioning steps.

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.16"
    }
  }
  required_version = ">= 1.2.0"
}

provider "aws" {
  region = "ca-central-1"
}

resource "aws_security_group" "tf-security-group" {
  name        = var.server_name
  description = "Security group for ${var.server_name}"

  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
  ingress {
    from_port   = 443
    to_port     = 443
    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"]
  }
}

resource "aws_instance" "tf-created-instance" {
  ami           = "ami-0083d3f8b2a6c7a81"
  instance_type = "t2.micro"
  key_name      = var.key_pair_name
  tags = {
    Name = var.server_name
  }
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Outputs

Define what Terraform should output after running:

output "public_ip" {
  value       = aws_instance.tf-created-instance.public_ip
  description = "The public IP address of the instance"
}
Enter fullscreen mode Exit fullscreen mode

Step 4: Automation Script

In run.sh, write a script to automate Terraform commands and handle DNS propagation:

#!/bin/bash
set -e
DOMAIN="your.domain.com"

terraform apply -auto-approve

echo "Waiting for DNS propagation..."
OLD_IP=$(dig +short $DOMAIN)
while true; do
  sleep 10
  NEW_IP=$(dig +short $DOMAIN)
  [ "$NEW_IP" != "$OLD_IP" ] && break
  echo "DNS records not updated yet. Retrying..."
done

terraform apply -auto-approve
Enter fullscreen mode Exit fullscreen mode

Dockerfile for Meteor

Here’s a sample Dockerfile to package your Meteor.js app:

FROM node:14.21.3-alpine

WORKDIR /app
COPY bundle/ .
EXPOSE 3000

ENV PORT=3000 \
    ROOT_URL="http://localhost:3000" \
    MONGO_URL="<your-MongoDB-url>"

WORKDIR /app/programs/server
RUN npm install

CMD ["sh", "-c", "MONGO_URL=mongodb://user:password@${MONGO_HOST}:27017/wp node /app/main.js"]
Enter fullscreen mode Exit fullscreen mode

Steps to Deploy

  1. Initialize Terraform: Run this command to set up Terraform:
   terraform init
Enter fullscreen mode Exit fullscreen mode
  1. Deploy with Automation: Run the script to deploy:
   ./run.sh
Enter fullscreen mode Exit fullscreen mode
  1. DNS Update:
    Update your domain’s A record to point to the EC2 instance’s public IP.

  2. Verify:
    Once DNS propagation is complete, verify your deployment by visiting the domain in a browser.


And there you have it! A fully automated Meteor.js app deployment on AWS using Terraform and Docker. Remember, every challenge is just another opportunity to learn. If you hit a rock, take a sip of chaay and troubleshoot like the tech pro you are. Celebrate your deployment success and post it everywhere!😉

Top comments (0)