MATTERMOST – ROCKETCHAT – Deploying

Introduction

In this post, I document the deployment of 5 instances on AWS using Terraform, an Infrastructure as Code (IaC) tool that automates the provisioning and management of infrastructure resources.

My project started with the use of Terraform to create instances on Amazon Web Services (AWS) which were Mattermost server, Rocketchat server, JMeter, Jenkins, and Zabbix.

Once the instances were set up, I brought in Ansible to do the setup and configuration. I needed to know how well Mattermost and Rocketchat servers could handle lots of users at the same time. So, I used JMeter to perform load testing on the Mattermost and Rocketchat servers. Jenkins was used to run the load test jobs created in JMeter. Lastly, I wanted to gain experience in server monitoring through the use of Zabbix.

Step 1: Define Terraform Configuration

I started by creating a provider.tf file in the project directory to specify the AWS provider and credentials:

terraform {
  required_providers {
    aws = {
        source  = "hashicorp/aws"
        version = "~> 5.0"
    }
  }
}
provider "aws" {
  region = "eu-central-1"
  profile = "quangcaoiam"
}

To handle the variations among the 5 instances, each with unique variables and security groups, I organized my project using modules. Separate directories were created for each instance, such as Jenkins, JMeter, Mattermost, RocketChat, etc., within the modules directory.

── main.tf
├── modules
│   ├── jenkins
│   │   ├── jenkins.tf
│   │   └── var.tf
│   ├── jmetter
│   │   ├── jmeter.tf
│   │   └── var.tf
│   ├── mattermost
│   │   ├── mattermost.tf
│   │   └── var.tf
│   ├── rocketchat
│   │   ├── rocketchat.tf
│   │   └── var.tf
│   └── zabbix
│       ├── var.tf
│       └── zabbix.tf
├── provider.tf

Here’s an example of the module for Jenkins in my main.tf file:

module "mattermost" {
  source = "./modules/mattermost"
}

Using modules allowed me to efficiently manage similar instances with slight configuration variations while maintaining a clean and organized project structure.

Step 2: Configuration Files

My configuration files were kept straightforward, making it easy to create infrastructures without repetition. For instance, the mattermost.tf file defined two resources: an “aws_instance” and an “aws_security_group”.

resource "aws_instance" "mattermost" {
  count = 1
  availability_zone = var.availability_zone
  key_name = var.keypair
  instance_type = "t2.medium"
  ami = var.ami
  root_block_device {
        delete_on_termination = "true"
        volume_size = 8
        volume_type = "gp2"
    }
  vpc_security_group_ids = [aws_security_group.mm-sg.id]
  tags = {
    "Name" = "Mattermost Server"
    "Purpose" = "Mattermost"
    "Project" = "num3"
    }
}
resource "aws_security_group" "mm-sg" {
    name = "mattermost-sg"
    vpc_id = var.vpcID
    description = "allow inbound access to the mattermost instance"
    ingress {
        protocol    = "tcp"
        from_port   = 22
        to_port     = 22
        cidr_blocks = [ "0.0.0.0/0" ]
    }
    ingress {
        protocol    = "tcp"
        from_port   = 80
        to_port     = 80
        cidr_blocks = [ "0.0.0.0/0" ]
    }
    ingress {
        protocol    = "tcp"
        from_port   = 443
        to_port     = 443
        cidr_blocks = [ "0.0.0.0/0" ]
    }
    ingress {
        protocol    = "tcp"
        from_port   = 8065
        to_port     = 8065
        cidr_blocks = [ "0.0.0.0/0" ]
    }
    ingress {
        protocol    = "tcp"
        from_port   = 5432
        to_port     = 5432
        cidr_blocks = [ "0.0.0.0/0" ]
    }
    ingress {
        protocol    = "tcp"
        from_port   = 10051
        to_port     = 10051
        cidr_blocks = [ "0.0.0.0/0" ]
    }
     egress {
        protocol    = "-1"
        from_port   = 0
        to_port     = 0
        cidr_blocks = [ "0.0.0.0/0" ]
  }
}

The other configuration files followed a similar structure, with variations in the “aws_security_groups” and minor changes in the “aws_instance” resource like instance type, AMI image, and name tag.

Step 3: Initialize Terraform

I exported my aws profile first:

export AWS_PROFILE=myawsprofile 

I initialized my Terraform configuration by running the command:

terraform init

Step 4: Create a Deployment Plan

Next, I generated a Terraform plan:

terraform plan -out=deploy.tfpl

I reviewed the resources to ensure all configurations were correct:

terraform show deploy.tfplan

Step 5: Apply the Deployment Plan

I applied the Terraform plan to create the instances:

terraform apply "deploy.tfplan"

Step 6: Review Instances

I verified that the instances were successfully created:

terraform show

The screen shot from my AWS account.

Conclusion

I successfully deployed 5 instances on AWS using Terraform. This diary demonstrates a simple setup with Terraform. Next, I used Ansible to manage and install applications on these 5 instances.