Building a solution is one thing, but making sure it scales it's another.
Throttling, latency, auto scaling, memory problems, excessive infrastructure cost, soft and hard limits. Those are all things you must keep in mind if you want to keep your users happy.
One aweasome tool for the job it's k6. It enables you to write load tests using JavaScript.
k6 requires you to pass each environment variable as a -e
argument, which can become messy pretty quickly or setting up a extension that involves rebuilding the executable.
I use the dotenv-cli to load a .env
file.
npm i -g dotenv-cli
dotenv -- k6 run tests/smoke.test.js
You can install the @types/k6
and load them with the help of VS Code without needing to add TypeScript to configure the Options
.
/**
* @type {import("k6/options").Options}
*/
export const options = {}
I recommend creating a tests
folder and create tests for your different use cases and scenarios, starting by the most critical or most probable to stress the system.
Make sure you study the 6 types of tests and best practices.
Using Terraform you can spin up a AWS instance with SSH access in a public subnet.
I commonly use the R6i family instances since they are memory optimized. You can choose the appopriate one for your needs based on the average MB by each VU.
variable "vpc_id" {
type = string
}
variable "public_subnet_id" {
type = string
}
resource "aws_security_group" "allow_ssh" {
name = "k6"
description = "Allow SSH"
vpc_id = var.vpc_id
ingress {
description = "SSH"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
ipv6_cidr_blocks = ["::/0"]
}
tags = {
Name = "k6"
}
}
data "aws_ami" "ubuntu" {
most_recent = true
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
owners = ["099720109477"] # Canonical
}
resource "aws_instance" "this" {
ami = data.aws_ami.ubuntu.id
subnet_id = var.public_subnet_id
instance_type = "r6i.16xlarge"
vpc_security_group_ids = [aws_security_group.allow_ssh.id]
key_name = "k6"
tags = {
Name = "k6"
}
}
I also use a null_resource
to automatically run a SSH script with the OS fine tunning and setting up Docker.
resource "null_resource" "bootstrap" {
depends_on = [aws_instance.this]
connection {
type = "ssh"
user = "ubuntu"
private_key = file("./k6.pem")
host = aws_instance.this.public_ip
timeout = "1m"
}
provisioner "file" {
content = file("./script.sh")
destination = "/tmp/script.sh"
}
provisioner "remote-exec" {
inline = [
"sudo chmod +x /tmp/script.sh",
"bash /tmp/script.sh",
]
}
}