Cloudpower für WordPress

Die Vorteile von Cloud Services gegenüber „traditionellem“ Hosting werden oft in der schnellen Bereitstellung, fließenden Skalierbarkeit oder Pay-per-use gesehen. Aus Sicht der Software-Entwicklung sind die leistungsfähigen APIs fast noch interessanter. Die völlige Automatisierung von Entwicklungsprozessen wie Continuous Integration, Build oder Deployment kann jetzt darüber hinaus auch auf die Infrastruktur ausgeweitet werden. Mit Tools wie Terraform werden Infrastructure as Code und echte Reproduzierbarkeit zum Kinderspiel. DevOps für alle!

OK, das mit dem Kinderspiel war gelogen – Terraform in der Version 0.6.15 ist noch ziemlich hakelig. Aber der dahinter liegende Grundgedanke passt, die Community ist sehr engagiert und andere Tools haben auch mal klein angefangen.

Dockerizing WordPress war ein erster Schritt in Richtung Cloud. Mit standardisierten Containern ist es leicht, bei einem beliebigen Cloud-Anbieter Infrastruktur-Services zu nutzen. Für das folgende Beispiel verwende ich Amazon Web Services (AWS), Ziel ist die Installation der WordPress-Container in der AWS-Cloud.

 

Terraform Prozess

 

Erzeugen der Cloud Instanz

Die Infrastruktur wird vollautomatisch über Terraform erzeugt. Die zugehörigen Sourcen bestehen aus vier Teilen. Zur besseren Übersicht habe ich zu den einzelnen Abschnitten nur die entsprechenden Fragmente dargestellt. Das vollständige Skript „aws_wordpress.tf“ und alle weiteren Dateien können aus Bitbucket herunter geladen werden.

$ terraform plan
$ terraform apply

 

Teil I – Security Credentials

Für die Verbindung mit dem AWS-Account benötigt Terrafom Security Credentials. Diese dienen zur Authentifizierung und Autorisierung der AWS-API-Aufrufe. Vorsicht, diese Werte sind sensibel und sollten nicht in einem Skript oder gar Repository abgelegt werden. Terraform bietet verschiedene Wege, die Credentials zu injizieren. Im folgenden Beispiel befinden sich die tatsächlichen Werte in den Umgebungsvariablen (TF_VAR_access_key, TV_VAR_secret_key) und werden zur Laufzeit ausgelesen. AWS Security Credentials können über die AWS Management Console erzeugt werden.

##### PART I #####
variable "access_key" {}
variable "secret_key" {}

provider "aws" {
    access_key = "${var.access_key}"
    secret_key = "${var.secret_key}"
    region = "eu-central-1"
}

 

Teil II – Security Group

An dieser Stelle wird die „virtuelle Firewall“ modifiziert. Damit wird der ein- und ausgehende Verkehr der Machine definiert. Eingehend werden die Ports 22 (SSH) und 80 (HTTP) geöffnet, ausgehender Verkehr wird vollständig zugelassen.

##### PART II #####
resource "aws_security_group" "demo_wordpress-sg" {
    name = "demo_wordpress-sg"
    description = "ssh + http inbound"
    ingress {
        from_port = 22
        to_port = 22
        protocol = "TCP"
        cidr_blocks = ["0.0.0.0/0"]
    }
    ingress {
        from_port = 80
        to_port = 80
        protocol = "TCP"
        cidr_blocks = ["0.0.0.0/0"]
    }
    egress {
        from_port = 0
        to_port = 0
        protocol = "-1"
        cidr_blocks = ["0.0.0.0/0"]
    }
    tags {
        Name = "demo_wordpress-sg"
    }
}

 

Teil III – Die AWS Instanz

Es wird eine EC2 Instanz vom Typ „t2.micro“ erzeugt und mit einem Ubuntu-Image bespielt. Die neue Instanz wird mit der Security-Group aus Teil II verknüpft.

Über den „key_name“ wird der SSH-Key für den späteren SSH-Zugriff auf die Instanz definiert. Der angegebene Wert muss mit einem bei AWS hinterlegten „key pair name“ übereinstimmen. „Key pairs“ können über die AWS Management Console verwaltet werden.

##### PART III #####
### Create AWS EC2 instance ###
resource "aws_instance" "demo_wordpress" {
    ami = "ami-87564feb"
    availability_zone = "eu-central-1a"
    instance_type = "t2.micro"
    key_name = "AWS-wordpress-key"
    security_groups = ["${aws_security_group.demo_wordpress-sg.name}"]
    tags {
        Name = "demo_wordpress"
    }
[...]

 

Teil IV – Trigger Bootstrapping

Das Bootstrapping umfasst die initiale Einrichtung der Maschine. Diese Aufgabe sollte nicht von Terraform selbst, sondern von nachgelagerten Tools übernommen werden. Da sich das Bootstrapping hier auf die beiden Aufgaben „Docker installieren“ und „Container starten“ reduziert, reicht der Aufruf eines simplen Shellskripts. Leider benötigt das Shellskript noch weitere Files. Um die Übersicht zu behalten, werden alle Files rund um das Thema Bootstrapping gemeinsam im Verzeichnis „/bootstrap“ abgelegt.

Bootstrap-Arbeitsschritte für Terraform:

(1) Verzeichnis „/bootstrap“ anlegen
(2) Bootstrap-Dateien in das Verzeichnis „/bootstrap“ kopieren
(3) Skript „bootstrap.sh“ starten

[...]
##### PART IV #####
    provisioner "remote-exec" {
        connection {
            host = "${aws_instance.demo_wordpress.public_ip}"
            private_key = "C:/.../.ssh/AWS-wordpress-key.pem"
            user = "ubuntu"
        }
        inline = [
            "sudo mkdir /bootstrap",
            "sudo chown ubuntu /bootstrap",
            "sudo chgrp ubuntu /bootstrap"
        ]
    }
    provisioner "file" {
        connection {
            host = "${aws_instance.demo_wordpress.public_ip}"
            private_key = "C:/.../.ssh/AWS-wordpress-key.pem"
            user = "ubuntu"
        }
        source = "bootstrap"
        destination = "/"
    }
    provisioner "remote-exec" {
        connection {
            host = "${aws_instance.demo_wordpress.public_ip}"
            private_key = "C:/.../.ssh/AWS-wordpress-key.pem"
            user = "ubuntu"
        }
        script = "bootstrap.sh"
    }
}