Deploying a Discord Bot to AWS EC2 Using Terraform
Published: 2024-07-08 16:32:13

## Prerequisites

1. **Install Terraform**: Ensure that Terraform is installed on your local machine. You can download it from the [Terraform website](https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli).
2. **AWS CLI**: Install and configure the AWS CLI with your credentials. Follow the [AWS CLI installation guide](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html).
3. Discord Bot code, this tutorial is only concerned with the deployment of your code to AWS, not the actual bot code itself.

## AWS Setup with Terraform

1. **Set Up AWS Credentials**: Configure your AWS CLI with the aws configure command and provide your AWS Access Key, Secret Key, region, and output format.
2. **Create a Key Pair**: Generate an SSH key pair to access your EC2 instance. Use the following command:

```
ssh-keygen -t rsa -b 2048 -f ~/.ssh/aws -N ""
```
 
This will create a public key file (_~/.ssh/aws.pub_) and a private key file (_~/.ssh/aws_).

3. **Create a Terraform Directory**: Create a directory for your Terraform files and navigate into it:

```
mkdir terraform-deploy
cd terraform-deploy
```
4. **Discord Bot Code**: Place your Discord bot code in the following directory structure:

```
<terraform-dir>/Code/discordbot.py
<terraform-dir>/Code/.env
<terraform-dir>/Code/requirements.txt
```
Note: It is crucial to have your Discord bot code ready in the specified structure before proceeding. If your files are named differently or located in different directories, you must update the _user_data.sh.tpl _file accordingly to match your setup.

## Terraform Configuration Files

1. **main.tf**: This file contains the main configuration for deploying an EC2 instance.

```
provider "aws" {
  region = var.aws_region
}
resource "aws_instance" "web" {
  ami           = var.ami_id
  instance_type = var.instance_type
  key_name = aws_key_pair.generated_key.key_name
  security_groups = [aws_security_group.sg_ssh.name]
  user_data = templatefile("user_data.sh.tpl", {
    python_script = file("${path.module}/Code/discordbot.py"),
    env_file      = file("${path.module}/Code/.env"),
    requirements  = file("${path.module}/Code/requirements.txt")
  })

  tags = {
    Name = var.instance_name
  }
}
resource "aws_security_group" "sg_ssh" {
  name        = "allow_ssh"
  description = "Allow SSH inbound traffic"

  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = [var.trusted_ip]
  }
egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}
resource "aws_key_pair" "generated_key" {
  key_name   = "generated-key"
  public_key = file(var.public_key_path)
}
```

2. **variables.tf**: This file defines the variables used in the Terraform configuration.

```
variable "aws_region" {
  description = "The AWS region to deploy to"
  default     = "us-east-1"
}

variable "ami_id" {
  description = "The AMI ID for the EC2 instance"
  default     = "ami-0bb84b8ffd87024d8"  # Amazon Linux 2 AMI ID
}

variable "instance_type" {
  description = "The instance type for the EC2 instance"
  default     = "t2.micro" # You can update this based on your requirements
}

variable "trusted_ip" {
  description = "The IP address allowed to SSH into the instance"
  default     = "<Insert-Your-IPV4-Address>/32" # Use “0.0.0.0/0” to allow SSH from all
}

variable "public_key_path" {
  description = "Path to the SSH public key"
  default     = "~/.ssh/aws.pub"
}

variable "instance_name" {
  description = "The name of the EC2 instance"
  default     = "Discord-Scripts-Instance"  # Replace with your desired instance name
}

```

3. **outputs.tf**: This file outputs the public IP address of the EC2 instance.

```
output "instance_ip" {
  description = "Public IP of the EC2 instance"
  value       = aws_instance.web.public_ip
}
```

4. **user_data.sh.tpl**: This script will be executed on the EC2 instance to set up the environment and run the Discord bot.

```
#!/bin/bash
# Update the package index
sudo yum update -y

# Install Python3 and pip
sudo yum install -y python3

# Ensure pip in installed
python3 -m ensurepip --upgrade

# Create a directory for the Python script and environment file
mkdir -p /home/ec2-user/app

# Copy the Python script
cat <<EOF > /home/ec2-user/app/discordbot.py
${python_script}
EOF

# Copy the .env file
cat <<EOF > /home/ec2-user/app/.env
${env_file}
EOF

# Copy the requirements.txt file
cat <<EOF > /home/ec2-user/app/requirements.txt
${requirements}
EOF
## Copy the Any additional files similarly
# Install required Python packages
sudo pip3 install -r /home/ec2-user/app/requirements.txt

# Run the Python script
python3 /home/ec2-user/app/discordbot.py

```

## Deploying with Terraform
1. **Initialize Terraform**: Run the following command to initialize Terraform. This will download the necessary providers and set up the environment.
```
terraform init
```

2. **Plan the Deployment**: Create an execution plan to ensure everything is configured correctly.
```
terraform plan
```

3. **Apply the Deployment**: Apply the configuration to deploy the resources to AWS.
```
terraform apply
```

4. **Retrieve the Instance IP**: Once the deployment is complete, you can retrieve the public IP of the EC2 instance.
```
terraform output instance_ip
```

5. **Access the EC2 Instance**: Use the public IP to SSH into the instance.
```
ssh -i ~/.ssh/aws ec2-user@<instance_ip>
```

## Conclusion
By following these steps, you can deploy your Discord bot to an AWS EC2 instance using Terraform. This setup ensures that your bot runs automatically on the instance, leveraging the infrastructure as code approach to manage your deployment.
Feel free to customize the provided Terraform configuration files according to your specific requirements. Happy deploying!

## ABOUT AISQUARE
[AISquare](https://aisquare.com/) is an innovative platform designed to gamify the learning process for developers. Leveraging an advanced AI system, AISquare generates and provides access to millions, potentially billions, of questions across multiple domains. By incorporating elements of competition and skill recognition, AISquare not only makes learning engaging but also helps developers demonstrate their expertise in a measurable way. The platform is backed by the Dynamic Coalition on Gaming for Purpose ([DC-G4P](https://intgovforum.org/en/content/dynamic-coalition-on-gaming-for-purpose-dc-g4p)), affiliated with the UN's Internet Governance Forum, which actively works on gamifying learning and exploring the potential uses of gaming across various sectors. Together, AISquare and DC-G4P are dedicated to creating games with a purpose, driving continuous growth and development in the tech industry.
You can reach us at [LinkedIn](https://www.linkedin.com/groups/14431174/), [X](https://x.com/AISquareAI), [Instagram](https://www.instagram.com/aisquarecommunity/), [Discord](https://discord.com/invite/8tJ3aCDYur).

_Author - Jatin Saini_