En este nuevo laboratorio, vamos a explorar cómo automatizar el despliegue de un tema de WordPress en un servidor alojado en DigitalOcean utilizando Github Actions. Hemos simplificado la creación de un entorno de prueba para que puedas probarlo tú mismo. 🚀
Creación del Entorno con Terraform 🌍
Para comenzar, vamos a crear una carpeta que contendrá el código de Terraform. Aquí es donde definiremos los recursos que necesitamos para configurar nuestro servidor en DigitalOcean.
Archivo provider.tf 🔌
En este archivo, especificaremos el proveedor que vamos a utilizar, en este caso, DigitalOcean. Asegúrate de que tengas tu token de acceso a DigitalOcean disponible.
terraform {
required_providers {
digitalocean = {
source = "digitalocean/digitalocean"
version = "~> 2.30"
}
}
}
provider "digitalocean" {
token = var.do_token
}
resource "digitalocean_ssh_key" "mi_clave_rsa" {
name = "mi_clave_rsa"
public_key = file(var.do_public_key)
}
Archivo main.tf 🏢
En este archivo, definiremos la creación de nuestro servidor en DigitalOcean. Aquí es donde configuramos detalles como la imagen, el nombre, la región y el tamaño del servidor.
resource "digitalocean_droplet" "mi_droplet" {
image = var.droplet_image
name = var.droplet_name
region = var.droplet_region
size = var.droplet_size
monitoring = true
tags = ["wordpress", "blog", "lab"]
droplet_agent = true
ssh_keys = [
digitalocean_ssh_key.mi_clave_rsa.fingerprint
]
}
Archivo terraform.tfvars 🧾
Este archivo contendrá las variables que utilizaremos en nuestro archivo main.tf
. Asegúrate de configurar estas variables según tus preferencias y necesidades.
do_public_key = "tf-digitalocean.pub"
droplet_image = "wordpress-20-04"
droplet_name = "labs-deploy-wordpress"
droplet_region = "fra1"
droplet_size = "s-2vcpu-4gb"
Estas variables son esenciales para personalizar la configuración de tu servidor en DigitalOcean. A medida que continúes con la automatización del despliegue, estas variables se utilizarán en el archivo main.tf
para configurar y crear tu servidor en DigitalOcean. A continuación, una breve descripción de cada variable:
do_public_key
: Debes especificar el nombre de tu clave pública que utilizarás para acceder al servidor.droplet_image
: Selecciona la imagen de Droplet de DigitalOcean que deseas utilizar, en este caso, "wordpress-20-04".droplet_name
: Define el nombre de tu Droplet, que identificará tu servidor en DigitalOcean.droplet_region
: Selecciona la región de DigitalOcean donde se creará el Droplet. En este caso, "fra1" se refiere a la región de Frankfurt.droplet_size
: Especifica el tamaño del Droplet, en este caso, "s-2vcpu-4gb".
Archivo variables.tf 🧾
En este archivo, definiremos las variables que usaremos en nuestro proyecto. Estas variables son esenciales para la configuración de Terraform.
variable "do_token" {}
variable "do_public_key" {}
variable "droplet_name" {}
variable "droplet_image" {}
variable "droplet_region" {}
variable "droplet_size" {}
Archivo output.tf 📤
output "droplet_name" {
value = digitalocean_droplet.mi_droplet.name
}
output "droplet_ip" {
value = digitalocean_droplet.mi_droplet.ipv4_address
}
output "droplet_price" {
value = digitalocean_droplet.mi_droplet.price_monthly
}
Este archivo definirá las salidas de datos que serán útiles para nuestro servidor, como el nombre, la dirección IP y el precio mensual.
Asegúrate de configurar estos valores según tus necesidades y preferencias antes de ejecutar Terraform.
No olvides configurar el valor de var.do_token
en los secretos de tu repositorio en GitHub. También, para acceder a tu servidor, genera una clave SSH utilizando el comando:
ssh-keygen -t rsa -C "tu_email@example.com" -f ./tf-digitalocean
Finalmente, sube tu clave pública y privada a los secretos de tu repositorio.
Ahora comenzaremos a crear nuestras pipelines. Para ello, crearemos una carpeta llamada .github y dentro de ella crearemos una carpeta llamada workflows. Dentro de esta carpeta, se crearán los siguientes archivos YAML:
Archivo ci.yml 🔄
Este archivo define una pipeline de CI/CD que utiliza varios desencadenadores (on
) y entradas (inputs
) para controlar la ejecución de trabajos específicos. Los trabajos se ejecutan en función de las entradas proporcionadas y las necesidades específicas de tu flujo de trabajo.
name: CI + CD
on:
workflow_dispatch:
inputs:
terraform:
description: Create infrastructure
type: boolean
required: false
default: false
install_wp_cli:
description: Install WP CLI
type: boolean
required: false
default: false
theme_test:
description: Test theme
type: boolean
required: false
default: false
pull_request_development:
description: Create pull request to development
type: boolean
required: false
default: false
pull_request_production:
description: Create pull request to production
type: boolean
required: false
default: false
version_type:
type: choice
description: Define the version type
default: ""
options:
- patch
- minor
- major
ip_address:
description: IP de acesso ao servidor
type: string
required: false
default: ""
deploy:
description: Deploy to production
type: boolean
required: false
default: false
bump:
description: Bump version
type: boolean
required: false
default: false
jobs:
terraform:
name: Create infrastructure
if: ${{ inputs.terraform }}
uses: ./.github/workflows/terraform.yml
secrets:
TF_DIGITALOCEAN_PUB: ${{ secrets.TF_DIGITALOCEAN_PUB }}
DIGITALOCEAN_TOKEN: ${{ secrets.DIGITALOCEAN_TOKEN }}
install_wp_cli:
name: Install WP CLI
if: ${{ inputs.install_wp_cli }}
uses: ./.github/workflows/install_wp_cli.yml
with:
ip_address: ${{ inputs.ip_address }}
secrets:
USERNAME: ${{ secrets.USERNAME }}
TF_DIGITALOCEAN_PUB: ${{ secrets.TF_DIGITALOCEAN_PUB }}
PORT: ${{ secrets.PORT }}
theme_test:
name: Test application
if: ${{ inputs.theme_test }} || ${{ inputs.pull_request_development }} || ${{ inputs.pull_request_production }} || ${{ inputs.bump }}
uses: ./.github/workflows/theme_review_action.yml
pull_request_development:
name: Open pull request to development
if: ${{ inputs.pull_request_development }}
needs: [theme_test]
uses: ./.github/workflows/pull_request.yml
type_version:
name: Type version
if: ${{ inputs.pull_request_production }}
needs : [theme_test]
uses: ./.github/workflows/type_version.yml
with:
version_type: ${{ inputs.version_type }}
pull_request_production:
name: Open pull request to production
if: ${{ inputs.pull_request_production }}
needs: [type_version]
uses: ./.github/workflows/pull_request.yml
deploy_production:
name: Deploy to production
if: ${{ inputs.deploy }}
uses: ./.github/workflows/deploy_theme.yml
with:
ip_address: ${{ inputs.ip_address }}
secrets:
USERNAME: ${{ secrets.USERNAME }}
TF_DIGITALOCEAN_PUB: ${{ secrets.TF_DIGITALOCEAN_PUB }}
PORT: ${{ secrets.PORT }}
deploy_bump_versio:
name: Deploy to production and bump version
if: ${{ inputs.bump }}
needs: [theme_test]
uses: ./.github/workflows/deploy_theme.yml
with:
ip_address: ${{ inputs.ip_address }}
secrets:
USERNAME: ${{ secrets.USERNAME }}
TF_DIGITALOCEAN_PUB: ${{ secrets.TF_DIGITALOCEAN_PUB }}
PORT: ${{ secrets.PORT }}
Como podrás observar en este flujo, nos apoyamos en los inputs para poder ejecutar los trabajos que necesitemos. Aunque este flujo no sea el más óptimo, nos permite realizar pruebas de forma sencilla y nos brinda la flexibilidad de personalizarlo a nuestro gusto y mejorarlo.
Job: terraform.yml 🏗️
name: DigitalOcean
on:
workflow_call:
secrets:
TF_DIGITALOCEAN_PUB:
required: true
DIGITALOCEAN_TOKEN:
required: true
env:
TF_DIGITALOCEAN_PUB: ${{ secrets.TF_DIGITALOCEAN_PUB }}
DIGITALOCEAN_TOKEN: ${{ secrets.DIGITALOCEAN_TOKEN }}
jobs:
terraform:
runs-on: ubuntu-latest
steps:
- name: Checkout código fuente
uses: actions/checkout@v4
- name: Mover llave pública
run: |
echo "$TF_DIGITALOCEAN_PUB" > ./terraform/tf-digitalocean.pub
echo $DIGITALOCEAN_TOKEN
- name: Configurar Terraform
run: |
terraform -chdir=./terraform init -var do_token=$DIGITALOCEAN_TOKEN
terraform -chdir=./terraform validate
- name: Aplicar infraestructura
run: |
terraform -chdir=./terraform apply -auto-approve -var do_token=$DIGITALOCEAN_TOKEN
- name: Esperar 15 minutos
run: sleep 900
- name: Destruir infraestructura
run: |
terraform -chdir=./terraform destroy -auto-approve -var do_token=$DIGITALOCEAN_TOKEN
En este código, hemos creado un servidor en DigitalOcean y disponemos de 15 minutos para realizar las pruebas que necesites.
Job: type_version.yml 🆕
name: Type version
on:
workflow_call:
inputs:
version_type:
description: 'Tipo de versión'
required: true
default: ''
type: string
jobs:
type-version:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.ref }}
token: ${{ secrets.GITHUB_TOKEN }}
fetch-depth: 0
- name: Obtener versión
id: version
run: |
echo " **********************"
git config user.name "$GITHUB_ACTOR"
git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
versionold=$(npm run env | grep npm_package_version | awk -F= '{print $2}')
npm version ${{ inputs.version_type }} -m "v%s"
version=$(node -p "require('./package.json').version")
echo "::set-output name=versionold::${versionold}"
echo "::set-output name=version::${version}"
echo " **********************"
- name: Cambiar versión en style.css
run: |
echo " **********************"
git config user.name "$GITHUB_ACTOR"
git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
sed -i "s/${{ steps.version.outputs.versionold }}/${{ steps.version.outputs.version }}/g" style.css
git add style.css
git commit -m "Actualizar versión a ${{ steps.version.outputs.version }}"
git push --force
echo " **********************"
Job: deploy_theme.yml 🚚
name: Install theme on production
on:
workflow_call:
secrets:
USERNAME:
required: true
TF_DIGITALOCEAN_PUB:
required: true
PORT:
required: true
inputs:
ip_address:
description: 'IP address of the server'
required: true
default: ''
type: string
pull_request:
branches:
- 'production'
types:
- closed
jobs:
deploy:
runs-on: ubuntu-latest
environment: Production
timeout-minutes: 15
steps:
- name: executing remote ssh commands using private key
uses: appleboy/ssh-action@v1.0.0
with:
host: ${{ inputs.ip_address }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.TF_DIGITALOCEAN_PUB }}
port: ${{ secrets.PORT }}
script: |
echo "Activating maintenance mode"
wp --path=/var/www/html --allow-root maintenance-mode activate
echo "Deploying theme to server"
git clone https://github.com/danieljsaldana/deploy-theme-wordpress.git
echo "Changing permissions"
chown -R www-data:www-data deploy-theme-wordpress
echo "Backing up current theme"
mv /var/www/html/wp-content/themes/deploy-theme-wordpress /var/www/html/wp-content/themes/deploy-theme-wordpress.bak
echo "Deploying theme"
rsync -av deploy-theme-wordpress /var/www/html/wp-content/themes
echo "Removing backup"
rm -fr /var/www/html/wp-content/themes/deploy-theme-wordpress.bak
echo "Removing deploy folder"
rm -rf deploy-theme-wordpress
echo "Deploying theme to server completed"
echo "Deactivating maintenance mode"
wp --path=/var/www/html --allow-root maintenance-mode deactivate
En este codigo, lo que hacemos es desplegar el theme en el servidor de produccion. Para ello nos conectamos por ssh y ejecutamos los comandos necesarios para desplegar el theme.
Recordar que nuestra pipeline funcione debemos de agregar todos los secretos que hemos definido en los workflows.
Conclusiones
En este laboratorio, hemos explorado cómo automatizar el proceso de despliegue de un tema de WordPress en un servidor alojado en DigitalOcean utilizando GitHub Actions. Esta automatización te permite ahorrar tiempo y reducir errores al eliminar la necesidad de realizar despliegues manuales. 🕒
Comenzamos creando un entorno de servidor en DigitalOcean utilizando Terraform. Configuramos los recursos esenciales, como la imagen del servidor, su ubicación y su tamaño. Personalizamos estos detalles mediante un archivo terraform.tfvars que contiene variables clave. ⚙️
Luego, configuramos flujos de trabajo en GitHub Actions que nos permiten controlar todo el proceso. Desde la creación del servidor con Terraform hasta el despliegue del tema en producción, cada paso se ha automatizado. 🤖
Además, hemos explorado cómo cambiar la versión del tema y realizar pruebas con GitHub Actions. Estos flujos de trabajo se han diseñado para adaptarse a diferentes situaciones, como la creación de solicitudes de extracción a ramas de desarrollo y producción. 📈
Finalmente, hemos observado cómo el tema se despliega en el servidor de producción mediante una conexión SSH. Hemos seguido prácticas recomendadas, como activar el modo de mantenimiento y realizar copias de seguridad del tema actual para asegurarnos de que el proceso sea seguro y confiable. 🔑
Este enfoque de automatización con GitHub Actions simplifica tus tareas de administración y te permite centrarte en el desarrollo de tu sitio de WordPress. Recuerda configurar los secretos adecuados y personalizar los flujos de trabajo según tus necesidades específicas. 💪