Terraform configuration for provisioning a single server that runs both WordPress and MySQL. The cloud-init script will install and configure both services so that WordPress uses the local MySQL service.
terraform {
required_providers {
faxter = {
source = "local/faxter/faxter"
version = "0.1.0"
}
}
required_version = ">= 1.0.0"
}
provider "faxter" {
token = var.faxter_token
}
# Variables
variable "faxter_token" {
description = "API token for Faxter provider"
type = string
}
variable "ssh_key_name" {
description = "SSH key name"
type = string
}
variable "ssh_public_key" {
description = "Path to SSH public key"
type = string
}
variable "private_key_path" {
description = "Path to SSH private key"
type = string
}
variable "project" {
description = "Project name"
type = string
}
# Resources
# SSH Key
resource "faxter_ssh_key" "default" {
name = var.ssh_key_name
public_key = file(var.ssh_public_key)
}
# Private Network
resource "faxter_network" "private" {
project = var.project
name = "private-network"
subnets {
name = "private-subnet"
cidr = "192.168.100.0/24"
}
}
# router
resource "faxter_router" "router" {
project = var.project
name = "router"
subnets = [faxter_network.private.subnets[0].name]
}
# Security Group
resource "faxter_security_group" "web_db_sg" {
project = var.project
name = "web-db-sg"
rules {
protocol = "tcp"
port_range_min = 22
port_range_max = 22
direction = "ingress"
remote_ip_prefix = "0.0.0.0/0"
}
rules {
protocol = "tcp"
port_range_min = 80
port_range_max = 80
direction = "ingress"
remote_ip_prefix = "0.0.0.0/0"
}
# ingress allow mysql from localhost
rules {
protocol = "tcp"
port_range_min = 3306
port_range_max = 3306
direction = "ingress"
remote_ip_prefix = "127.0.0.1/32"
}
}
# Server with WordPress and MySQL
resource "faxter_server" "wordpress_mysql" {
project = var.project
name = "wordpress-mysql"
flavor = "titanium"
image = "Ubuntu2204"
key_name = faxter_ssh_key.default.name
networks = [faxter_network.private.name]
security_groups = [faxter_security_group.web_db_sg.name]
cloud_init = base64encode(data.local_file.wordpress_mysql_cloud_init.content)
}
# Cloud-Init Script for WordPress and MySQL
data "local_file" "wordpress_mysql_cloud_init" {
filename = "${path.module}/wordpress_mysql_cloud_init.yaml"
}
# Output
output "server_ip" {
value = faxter_server.wordpress_mysql.ip_addresses[0]
}
terraform.tfvars
faxter_token = "YOUR_API_TOKEN"
ssh_key_name = "wordpress_key"
ssh_public_key = "~/.ssh/id_rsa.pub"
private_key_path = "~/.ssh/id_rsa"
project = "your_project_name"
Cloud-Init File (wordpress_mysql_cloud_init.yaml)
Save this file in the same directory as your Terraform configuration.
#cloud-config
package_update: true
package_upgrade: true
packages:
- apache2
- php
- php-mysql
- mysql-server
- wget
- unzip
runcmd:
# Configure MySQL
- systemctl enable mysql
- systemctl start mysql
- mysql -e "CREATE DATABASE wordpress;"
- mysql -e "CREATE USER 'wordpressuser'@'localhost' IDENTIFIED BY 'password';"
- mysql -e "GRANT ALL PRIVILEGES ON wordpress.* TO 'wordpressuser'@'localhost';"
- mysql -e "FLUSH PRIVILEGES;"
# Configure Apache and PHP
- wget https://wordpress.org/latest.zip -O /tmp/wordpress.zip
- unzip /tmp/wordpress.zip -d /var/www/html/
- mv /var/www/html/wordpress /var/www/html/wordpress-site
- chown -R www-data:www-data /var/www/html/wordpress-site
- chmod -R 755 /var/www/html/wordpress-site
# Configure WordPress
- cp /var/www/html/wordpress-site/wp-config-sample.php /var/www/html/wordpress-site/wp-config.php
- sed -i "s/database_name_here/wordpress/" /var/www/html/wordpress-site/wp-config.php
- sed -i "s/username_here/wordpressuser/" /var/www/html/wordpress-site/wp-config.php
- sed -i "s/password_here/password/" /var/www/html/wordpress-site/wp-config.php
# Restart Apache
- systemctl enable apache2
- systemctl restart apache2
Explanation
-
Cloud-Init Script:
- Updates and upgrades the server packages.
- Installs apache2, php, php-mysql, and mysql-server.
- Configures MySQL by creating a database and user for WordPress.
- Downloads and configures WordPress, including setting file permissions.
-
Security Groups:
-
Allows HTTP traffic on port 80 and MySQL traffic restricted to the local host.
-
Server:
-
A single server running both Apache and MySQL with WordPress installed.
Steps to Deploy:
- Save the Terraform files and the wordpress_mysql_cloud_init.yaml file.
- Replace placeholders in terraform.tfvars or set the variables using the CLI.
- Run the following commands:
terraform init
terraform plan
terraform apply
- Access WordPress via the server's IP address on port 80.