Creating a Joomla website with a PostgreSQL database using Terraform
To create an infrastructure for your Joomla website with a PostgreSQL database using Terraform:
- Prepare your cloud.
- Create an infrastructure.
- Install Joomla and additional components.
- Configure the Apache2 web server.
- Configure Joomla.
- Upload the website files.
- Create an infrastructure.
- Test the website.
If you no longer need the resources you created, delete them.
Prepare your cloud
Sign up for Yandex Cloud and create a billing account:
- Go to the management console
and log in to Yandex Cloud or create an account if you do not have one yet. - On the Yandex Cloud Billing
page, make sure you have a billing account linked and it has theACTIVE
orTRIAL_ACTIVE
status. If you do not have a billing account, create one.
If you have an active billing account, you can go to the cloud page
Learn more about clouds and folders.
Make sure the selected folder contains a network with subnets in the ru-central1-a
, ru-central1-b
, and ru-central1-d
availability zones. To do this, select Virtual Private Cloud on the folder page. If the list contains a network, click its name to see the list of subnets. If the subnets or network you need are not listed, create them.
Required paid resources
The cost of hosting a Joomla-powered website includes:
- Fee for a continuously running VM (see Yandex Compute Cloud pricing).
- Fee for using a dynamic or static external IP address (see Yandex Virtual Private Cloud pricing).
- Fee for a PostgreSQL DB cluster (see Yandex Managed Service for PostgreSQL pricing).
- Fee for outgoing traffic from Yandex Cloud to the internet (see Compute Cloud pricing).
- Fee for public DNS queries and DNS zones if using Yandex Cloud DNS (see pricing Cloud DNS).
Create an infrastructure
With Terraform
Terraform is distributed under the Business Source License
For more information about the provider resources, see the documentation on the Terraform
To create an infrastructure using Terraform:
-
Install Terraform and specify the source for installing the Yandex Cloud provider (see Configure a provider, step 1).
-
Prepare a file with the infrastructure description:
Ready-made archiveManually- Create a directory for the file with the infrastructure description.
- Download the archive
(2 KB). - Unpack the archive to the directory. As a result, it should contain the
joomla-postgresql-terraform.tf
configuration file and thejoomla-postgresql-terraform.auto.tfvars
file with user data.
-
Create a directory for the file with the infrastructure description.
-
In the directory, create a configuration file named
joomla-postgresql-terraform.tf
:joomla-postgresql-terraform.tf
# Declaring variables for custom parameters variable "folder_id" { type = string } variable "vm_user" { type = string } variable "ssh_key_path" { type = string } variable "db_user" { type = string } variable "db_password" { type = string sensitive = true } variable "dns_zone" { type = string } variable "dns_recordset_name" { type = string } # Adding other variables locals { network_name = "example-network" subnet_name1 = "subnet-1" subnet_name2 = "subnet-2" subnet_name3 = "subnet-3" sg_vm_name = "sg-vm" sg_pgsql_name = "sg-pgsql" vm_name = "joomla-pg-tutorial-web" cluster_name = "joomla-pg-tutorial-db-cluster" db_name = "joomla-pg-tutorial-db" dns_zone_name = "example-zone-1" } # Configuring a provider terraform { required_providers { yandex = { source = "yandex-cloud/yandex" version = ">= 0.47.0" } } } provider "yandex" { folder_id = var.folder_id } # Creating a cloud network resource "yandex_vpc_network" "joomla-pg-network" { name = local.network_name } # Creating a subnet in the ru-central1-a availability zone resource "yandex_vpc_subnet" "joomla-pg-network-subnet-a" { name = local.subnet_name1 zone = "ru-central1-a" v4_cidr_blocks = ["10.128.0.0/24"] network_id = yandex_vpc_network.joomla-pg-network.id } # Creating a subnet in the ru-central1-b availability zone resource "yandex_vpc_subnet" "joomla-pg-network-subnet-b" { name = local.subnet_name2 zone = "ru-central1-b" v4_cidr_blocks = ["10.129.0.0/24"] network_id = yandex_vpc_network.joomla-pg-network.id } # Creating a subnet in the ru-central1-d availability zone resource "yandex_vpc_subnet" "joomla-pg-network-subnet-d" { name = local.subnet_name3 zone = "ru-central1-d" v4_cidr_blocks = ["10.130.0.0/24"] network_id = yandex_vpc_network.joomla-pg-network.id } # Creating a security group for a PostgreSQL database cluster resource "yandex_vpc_security_group" "pgsql-sg" { name = local.sg_pgsql_name network_id = yandex_vpc_network.joomla-pg-network.id ingress { description = "PostgreSQL" port = 6432 protocol = "TCP" v4_cidr_blocks = ["0.0.0.0/0"] } } # Creating a security group for a VM resource "yandex_vpc_security_group" "vm-sg" { name = local.sg_vm_name network_id = yandex_vpc_network.joomla-pg-network.id egress { protocol = "ANY" description = "ANY" v4_cidr_blocks = ["0.0.0.0/0"] from_port = 0 to_port = 65535 } ingress { description = "HTTP" protocol = "TCP" v4_cidr_blocks = ["0.0.0.0/0"] port = 80 } ingress { description = "HTTPS" protocol = "TCP" v4_cidr_blocks = ["0.0.0.0/0"] port = 443 } ingress { description = "SSH" protocol = "ANY" v4_cidr_blocks = ["0.0.0.0/0"] port = 22 } } # Adding a prebuilt VM image resource "yandex_compute_image" "joomla-pg-vm-image" { source_family = "centos-stream-8" } resource "yandex_compute_disk" "boot-disk" { name = "bootvmdisk" type = "network-hdd" zone = "ru-central1-a" size = "10" image_id = yandex_compute_image.joomla-pg-vm-image.id } # Creating a VM instance resource "yandex_compute_instance" "joomla-pg-vm" { name = local.vm_name platform_id = "standard-v3" zone = "ru-central1-a" resources { cores = 2 memory = 1 core_fraction = 20 } boot_disk { disk_id = yandex_compute_disk.boot-disk.id } network_interface { subnet_id = yandex_vpc_subnet.joomla-pg-network-subnet-a.id nat = true security_group_ids = [ yandex_vpc_security_group.vm-sg.id ] } metadata = { user-data = "#cloud-config\nusers:\n - name: ${var.vm_user}\n groups: sudo\n shell: /bin/bash\n sudo: 'ALL=(ALL) NOPASSWD:ALL'\n ssh_authorized_keys:\n - ${file("${var.ssh_key_path}")}" } } # Creating a PostgreSQL database cluster resource "yandex_mdb_postgresql_cluster" "joomla-pg-cluster" { name = local.cluster_name environment = "PRODUCTION" network_id = yandex_vpc_network.joomla-pg-network.id security_group_ids = [ yandex_vpc_security_group.pgsql-sg.id ] config { version = "14" resources { resource_preset_id = "b2.medium" disk_type_id = "network-ssd" disk_size = 10 } } host { zone = "ru-central1-a" subnet_id = yandex_vpc_subnet.joomla-pg-network-subnet-a.id } host { zone = "ru-central1-b" subnet_id = yandex_vpc_subnet.joomla-pg-network-subnet-b.id } host { zone = "ru-central1-d" subnet_id = yandex_vpc_subnet.joomla-pg-network-subnet-d.id } } # Creating a database resource "yandex_mdb_postgresql_database" "joomla-pg-tutorial-db" { cluster_id = yandex_mdb_postgresql_cluster.joomla-pg-cluster.id name = local.db_name owner = var.db_user } # Creating a database user resource "yandex_mdb_postgresql_user" "joomla-user" { cluster_id = yandex_mdb_postgresql_cluster.joomla-pg-cluster.id name = var.db_user password = var.db_password } # Creating a DNS zone resource "yandex_dns_zone" "joomla-pg" { name = local.dns_zone_name zone = var.dns_zone public = true } # Creating a type A resource record resource "yandex_dns_recordset" "joomla-pg-a" { zone_id = yandex_dns_zone.joomla-pg.id name = var.dns_recordset_name type = "A" ttl = 600 data = [ yandex_compute_instance.joomla-pg-vm.network_interface.0.nat_ip_address ] } # Creating a CNAME resource record resource "yandex_dns_recordset" "joomla-pg-cname" { zone_id = yandex_dns_zone.joomla-pg.id name = "www" type = "CNAME" ttl = 600 data = [ var.dns_zone ] }
-
In the directory, create the
joomla-postgresql-terraform.auto.tfvars
file with user data:joomla-postgresql-terraform.auto.tfvars
folder_id = "<folder ID>" vm_user = "<VM_username>" ssh_key_path = "<path_to_public_SSH_key>" db_user = "<database_username>" db_password = "<database_password>" dns_zone = "<DNS_zone>" dns_recordset_name = "<DNS_record_name>"
For more information about the parameters of resources used in Terraform, see the provider documentation:
- Network: yandex_vpc_network
- Subnets: yandex_vpc_subnet
- Security groups: yandex_vpc_security_group
- VM image: yandex_compute_image
- Disk: yandex_compute_disk
- VM instance: yandex_compute_instance
- PostgreSQL cluster: yandex_mdb_postgresql_cluster
- PostgreSQL database: yandex_mdb_postgresql_database
- Database user: yandex_mdb_postgresql_user
- DNS zone: yandex_dns_zone
- DNS resource record: yandex_dns_recordset
-
In the
joomla-postgresql-terraform.auto.tfvars
file, set the user-defined parameters:folder_id
: Folder ID.vm_user
: VM username.ssh_key_path
: Path to the file with a public SSH key to authenticate the user on the VM. For more information, see Creating an SSH key pair.db_user
: Database username, e.g.,joomla
.
db_password
: Password for the database. The password must be 8 to 128 characters long.dns_zone
: DNS zone. Specify your registered domain, e.g.,example.com.
.dns_recordset_name
: Name of the record set, e.g.,example-recordset
.
To get access to public zone domain names, you need to delegate the domain. Specify the addresses of thens1.yandexcloud.net
andns2.yandexcloud.net
servers in your personal dashboard at your registrar.
-
Create resources:
-
In the terminal, change to the folder where you edited the configuration file.
-
Make sure the configuration file is correct using the command:
terraform validate
If the configuration is correct, the following message is returned:
Success! The configuration is valid.
-
Run the command:
terraform plan
The terminal will display a list of resources with parameters. No changes are made at this step. If the configuration contains errors, Terraform will point them out.
-
Apply the configuration changes:
terraform apply
-
Confirm the changes: type
yes
in the terminal and press Enter.
-
After creating the infrastructure, install Joomla.
Install Joomla and additional components
After the joomla-pg-tutorial-web
VM's status changes to RUNNING
, do the following:
-
Under Network on the VM page in the management console
, find the VM's public IP address. -
Connect to the VM via SSH. To do this, use
ssh
in Linux or macOS, or PuTTY in Windows.The recommended authentication method when connecting over SSH is using a key pair. Make sure to configure the generated key pair so that the private key matches the public key sent to the VM.
-
Download and unpack the Joomla archive:
CentOS Streamsudo mkdir -p /var/www/html/ curl https://downloads.joomla.org/cms/joomla3/3-8-7/Joomla_3-8-7-Stable-Full_Package.tar.gz?format=gz --output Joomla_3-8-7-Stable-Full_Package.tar.gz --location sudo mv Joomla_3-8-7-Stable-Full_Package.tar.gz /var/www/html/ (cd /var/www/html/ && sudo tar -zxvf Joomla_3-8-7-Stable-Full_Package.tar.gz) sudo rm /var/www/html/Joomla_3-8-7-Stable-Full_Package.tar.gz sudo mv /var/www/html/htaccess.txt /var/www/html/.htaccess
-
Install additional components:
CentOS Streamsudo dnf install epel-release sudo dnf install https://rpms.remirepo.net/enterprise/remi-release-8.rpm sudo yum -y install --enablerepo remi-modular httpd php php-pgsql php php-common php-mbstring php-zip php-xml nano wget php-json sudo dnf module enable postgresql:13 sudo dnf install postgresql-server
-
Get and configure the SSL certificate:
CentOS Streamsudo mkdir ~apache/.postgresql sudo wget "https://crls.yandex.net/allCLCAs.pem" -O ~apache/.postgresql/root.crt sudo chmod 0600 ~apache/.postgresql/root.crt sudo chown -R apache:apache ~apache/.postgresql
Configure the Apache2 web server
-
Perform the basic configuration of Apache2:
CentOS Streamsudo chown -R apache /var/www/html/
-
Specify the virtual host settings in the Apache2 configuration file. You can edit files in the
nano
editor:CentOS Streamsudo nano /etc/httpd/conf.d/joomla.conf
Edit the file as follows:
<VirtualHost *:80 [::]:80> ServerAdmin webmaster@localhost DocumentRoot /var/www/html/ <Directory /var/www/html/> DirectoryIndex index.php index.html DirectorySlash off RewriteEngine on RewriteBase / AllowOverride all </Directory> </VirtualHost>
-
Restart the web server:
CentOS Streamsudo service httpd restart
-
Change the settings:
CentOS Streamsudo restorecon -R /var/www/html sudo setsebool -P httpd_can_network_connect 1
Configure Joomla
Configure Joomla by following this guide
-
Get the addresses of the DB cluster hosts in the management console:
- Open the folder where the DB cluster was created and select Managed Service for PostgreSQL.
- Select the
joomla-pg-tutorial-db-cluster
cluster. - Go to the Hosts tab.
- In the Host FQDN field, copy the host addresses.
-
At the Database step, fill in the following fields in the Joomla web installer:
-
Database type:
PostgreSQL
. -
DB server name:
<address_of_host_1>,<address_of_host_2>,<address_of_host_3> port=6432 sslmode=verify-full target_session_attrs=read-write
-
Username:
joomla
. -
Password: Enter the DB user's password.
-
DB name:
joomla-pg-tutorial-db
.
-
-
For security reasons, Joomla may ask you to create or delete a special test file. On the VM, go to the
/var/www/html/installation
folder and create or delete the specified file there. -
Create an empty file named
configuration.php
to safe configuration and configure write permissions for the folder:sudo touch /var/www/html/configuration.php sudo chmod 655 /var/www/html/configuration.php sudo chown -R apache:apache /var/www/html/ sudo restorecon -R /var/www/html
-
After the installation is completed, delete the
installation
directory. This is a Joomla security requirement:sudo rm -rf /var/www/html/installation
Upload the website files
-
Under Network on the VM page in the management console
, find the VM public IP address. -
Connect to the VM via SSH.
-
Grant your user write access to the
/var/www/html
directory:sudo chown -R "$USER":apache /var/www/html
-
Upload the website files to the VM via SCP
.Linux/macOSWindowsUse the
scp
command-line utility:scp -r <path_to_file_directory> <VM_username>@<VM_IP_address>:/var/www/html
Use WinSCP
to copy the local file directory to/var/www/html
on the VM.
Test the website
To check that the site is up, enter its IP address or domain name in your browser:
http://<public_IP_of_VM>
http://www.example.com
How to delete the resources you created
To shut down the website and stop paying for the resources you created:
-
Open the
joomla-postgresql-terraform.tf
configuration file and delete from it the description of the infrastructure you created. -
Apply the changes:
-
In the terminal, change to the folder where you edited the configuration file.
-
Make sure the configuration file is correct using the command:
terraform validate
If the configuration is correct, the following message is returned:
Success! The configuration is valid.
-
Run the command:
terraform plan
The terminal will display a list of resources with parameters. No changes are made at this step. If the configuration contains errors, Terraform will point them out.
-
Apply the configuration changes:
terraform apply
-
Confirm the changes: type
yes
in the terminal and press Enter.
-