Today, we’re going to give you the “Hello, world” of web stacks and explain how you could run WordPress with mu. This is the fifth post in Stelligent’s blog series on mu, where we’ll lay out a path for using mu to run WordPress and try to hit a target that’s often hard to find in that part of our world: managing a WordPress stack with infrastructure as code, utilizing a continuous delivery pipeline. In that vein, we’re going to keep the feature list as short and simple as possible. To make this easier to follow, we’re going to keep the feature list short and simple. Look for future posts in the Stelligent blog where we’ll talk about adding more functionality.
Why would I want to run WordPress with mu?
mu will take care of a lot of nice things for you. It creates a CodePipeline stack that will manage your deployment workflow, and you’ll have test and production environments out of the box. You can inspect changes in your test instance before you let them continue through the pipeline. It will manage your databases in RDS, so your backend data layer gets its own high availability and scaling that’s independent of your other resources; your test and production data are also kept separate. Each environment will run in Amazon’s EC2 Container Service, behind a load balancer, so the pipeline can roll out new containers without bringing the old ones down. When it’s all done, you can even export CloudFormation templates for your infrastructure and manage them on your own — you’re never locked into using mu!
We’re going to deploy a Docker container from the official WordPress image. How do we get there? mu will manage a CodePipeline stack that orchestrates everything: it creates a custom image with your web data and the official image, then uses ECS to deploy a test instance for you to inspect, and then — if you approve it — rolls it out to production. Because we’re using mu, all of this will be done through code, and we’ll use GitHub to make that code available to CodePipeline.
Stelligent created mu to simplify using microservices on AWS. It gives you a simple, flexible front-end to some really sophisticated services that can seem bewildering until you’ve gained a lot of experience with them. All those advanced products from AWS are themselves hiding the complexity of running very robust services across data centers around the world. There is vast machinery hidden behind this relatively simple command-line interface. You benefit from all of this with a really simple process for deploying your WordPress site, and you get to do it with tools native to most developers: a code editor and a command line.
Let’s get down to the nitty gritty. To get started, fork our repository into your own GitHub account then clone it to your workstation. Click the “Fork” button in the top right corner of the page at stelligent/mu-wordpress:
Next, clone the new repo from your account to your local workstation:
git clone _your_fork_of_mu-wordpress_ cd mu-wordpress
In this directory, you’ll find a few files. Edit mu’s main config file, mu.yml, to customize it for your usage. As initially configured, your launched instances will use an ssh key pair named mu-wordpress. Create that or reference an EC2 key you already have:
## See https://github.com/stelligent/mu/wiki/Environments environments: - name: test ### Attributes for the ECS container instances cluster: #### Name of EC2 keypair to associate with ECS container instances. #### Launches bastion host if defined. #### (default: none) keyName: mu-wordpress #### The instance type to use for the ECS container instances #### (default: t2.micro) instanceType: t2.micro - name: prod cluster: keyName: mu-wordpress instanceType: t2.small
Farther down, change pipeline.source.repo to point to your own GitHub account instead of “stelligent”:
pipeline: source: provider: GitHub repo: _your_github_username_/mu-wordpress
Commit your changes and push them back up to your GitHub account:
git add mu.yml git commit -m 'first config' && git push
You’re ready to start up your pipeline:
mu pipeline up
mu will ask you for a GitHub token. CodePipeline uses it to watch your repo for changes so that it can automatically deploy them. Create a new token in your own GitHub account and grant it the “admin:repo_hook” and “admin” permissions. Save it somewhere, like a nice password manager, and then provide it at mu’s prompt.
Now you can watch your pipeline get deployed:
mu pipeline logs -f
Give it a little time – it will probably take about 10 minutes for the pipeline to deploy all the resources. When it’s done, you’ll have your first environment, “test”:
mu env list
You should see a table like this, but it won’t say CREATE_COMPLETE under each environment until they’re done.
+-------------+-----------------------+---------------------+-----+ | ENVIRONMENT | STACK | STATUS | ... | +-------------+-----------------------+---------------------+-----+ | test | mu-cluster-test | CREATE_COMPLETE | ... | +-------------+-----------------------+---------------------+-----+
On to WordPress!
Now that you have a test environment, you can initialize WordPress and make sure it’s working. Start by inspecting “test”:
mu env show test
You’ll see a block at the top that includes “Base URL”:
Environment: test Cluster Stack: mu-cluster-test (UPDATE_IN_PROGRESS) VPC Stack: mu-vpc-test (UPDATE_COMPLETE) Bastion Host: 220.127.116.11 Base URL: http://mu-cl-some-long-uuid.us-east-1.elb.amazonaws.com
Append “/wp-admin” to that and load the URL in your browser:
Follow the instructions there to set up a WordPress admin user and initialize the database.
Deploy to “production”
If it looks to you like it’s working, load up your CodePipeline console. You can find the URL for it by asking mu for information on your service:
mu service show | head
The first line of output will give you the URL for your pipeline stack:
Pipeline URL: https://console.aws.amazon.com/codepipeline/home?region=...
Load that page in your web browser. Find the “Production” stage. The first step there is “Approve”, and you’ll see a button labeled “Review”. Fill that in – any text will do – and click the “Approve” button:
CodePipeline will deploy a new copy of the container it build into your “prod” environment. When it’s done, you can do the same thing you did with test to initialize WordPress and inspect your new web site. When you’re ready, try these commands to watch it go and get the site URL:
mu pipeline logs -f mu env show prod |head
Behind the scenes
If you’ve made it this far, I’ll bet you’re wondering what mu is actually doing for you. Let’s take a look. mu brings together a handful of Amazon products. It will:
- customize the official WordPress Docker image,
- storing a copy in Amazon’s ECR Docker registry,
- running it in Amazon’s EC2 Container Service,
- fronted by an Application Load Balancer,
- backed by an RDS Aurora database,
- deployed with CodeBuild and CodePipeline,
- all done through AWS CloudFormation using a pair of simple YAML files.
Those are the pieces. How do they all fit together?
- GitHub stores your infrastructural code.
- mu acts as your front-end to AWS by generating and applying CloudFormation templates, orchestrated by CodePipeline.
- CodeBuild combines your content with the official WordPress Docker container, storing the new image in Amazon ECR, then deploying it through ECS.
- An ECS cluster is run for each environment we define: in this case, “test” and “prod”.
- An AWS ALB sits in front of each cluster.
- Your WordPress database will be provided by an Amazon RDS cluster, one for each environment. Each runs Aurora, Amazon’s highly optimized clone of MySQL.
Let’s talk about how your information flows through those pieces. AWS CodePipeline orchestrates all the other services in AWS. It’s used to give you a continuous delivery pipeline:
- It watches your GitHub repo for changes and automatically applies them shortly after you push.
- AWS CodeBuild uses buildspec.yml to run any custom steps you add there.
- AWS CodeBuild generates your own Docker image by combining the results of the last step with the official WordPress image and storing it in Amazon ECR.
- Your container is deployed to your “test” environment.
- You manually inspect your container and approve or reject it.
- If you approve it, your container is deployed to your “prod” environment.
Wrapping it up
If you want to customize your WordPress site, add content to the html directory of your repo. Anything there will be installed with WordPress as the container is built, so you have a simple way to add content to your site’s wp-content directory by adding new plugins or themes to your own codebase. Take a look at your mu.yml file, too – it includes comments that explain the settings used and suggest some things you might want to change, like the instance size deployed to each environment.
We’ve shown a fast and simple way to get WordPress running at AWS. There’s a lot of tech running behind the scenes, but mu makes it easy to get started and navigate that complexity. There’s a lot more we could do: optimizing WordPress and making your stack robust are extensive topics that deserve their own articles, and much has been written about them elsewhere. Look for future posts on the Stelligent blog as we improve our mu-wordpress code, too.
Are you passionate about working with the latest AWS technologies? Are you interested in helping build tools to help automate deployments? Do you want to engage in spirited debate about how to pronounce Greek letters? Stelligent is hiring!