On March 26th of this year, I sat the new AWS Certified SysOps Administrator – Associate SOA-C02 Beta exam, the last day of the Beta period. After what felt like a very long, but not unexpected, wait for the results, I received an email from Credly yesterday informing me I have a new badge for AWS SysOps Administrator. Just to make sure, I logged into my Certmetrics and confirmed the pass! Happy days!
Whilst the merits of the Cloud Practitioner is questionable, I felt it served as a good warm up for two reasons:
A refresher for someone like me who hadn’t sat a professional exam for some time.
A first experience of an online proctored exam, given that test centers were closed due to COVID-19.
Happy I passed and felt confident to move onto tackling the Solutions Architect cert. First, however I successfully sat Microsoft Azure Fundamentals , for which I had a free exam voucher, the content of this exam shared some of the basic principles of cloud computing with Cloud Practitioner and along with previous experience with Azure, this stood me in good stead.
I had started studying for the Architect exam back in January 2020 with Adrians Cantrill’s course on Linux Academy, but work got in the way and by the time I got to focus on the Architect certification again AWS had released the new SAA-C02 version of the exam with new topics added. I opted to study Adrian’s new, comprehensive course at learn.cantrill.io to continue my studies. Thankfully I got my pass and the studies have proved useful as the portion of my job working with AWS grows as more of our Teleco customers adopt cloud services.
SysOps Study
Anyway, back to the subject of this post, the SysOps Associate beta exam…I decided to give the beta a go after seeing posts regarding the new exam on various AWS channels, Reddit, Twitter and Adrian’s Tech Study Slack. Being a beta exam the exam fee was at a reduced rate and the only downslide I saw was having to wait around 90 days for the result as opposed to the instant result on a non-beta exam!
To study this time I opted for Stephane Maarak’s excellent Udemy course. I didn’t quite have the time for Adrians Cantrill’s SysOps course, so I would rely on Stephane’s course, the overlap from Adrian’s Solution Architect course and my growing experience with AWS.
The exam
The exam is split into two parts, the first involving the familar multiple choice and multi-answer questions section and the second part contained a hands-on lab portion. With a total time of 3 hours and 45 minutes to complete all sections, plenty of time is provided and being beta it allows for any issues experienced. On finishing the first portion of 55 questions, I felt ok, but not super confident as some subjects for me at the time were not so familiar.
Sticking to the NDA and without giving anything away, some of the subjects I was not sure about were:
Amazon Elasticsearch Architecture
CloudFormation cross-stack references vs nested-stack
Plus I got two questions on Route 53 around APEX vs NONAPEX DNS Record types, for which I know I opted for the wrong option!
So going into the 3 labs, I felt I’d need to score well to secure a passing mark (720 out of 1000). I had plenty of time remaining for the labs, much longer than the 20 minutes recommended for each, so I took my time and didn’t rush through them, thoroughly checking my work after completing the tasks.
My experience of the labs were good, I believe other people sitting the exam had issues, but I had no such concerns. The labs were setup through a virtual Windows machine with browser access to the AWS console (there is no internet access so you are not able to look at AWS documentation to help implement tasks). On the right hand side of the screen, you are given a scenario, asked to create A B C, or implement X Y Z, using names provided and make sure it works as specified. You follow the requirements, implement the task using the console and complete each lab before moving onto the next (you cannot return to a previously completed lab).
Again sticking to the NDA my three tasks were around:
The setup of a scalable application – configuring a VPC, LT, ASG, ALB, Security, Networking etc
Using AWS config to ensure something is set (compliance)
Configure some S3 data buckets with lifecycle policies
On completing each lab, I felt confident that I’d fully implemented the tasks correctly.
Wrapping Up
I enjoyed the exam, I liked the hands-on section and I expect that element will be added to future AWS exams going forward. I didn’t like the long wait for the results, however, but I knew that beforehand!
The old SOA-C01 SysOps exam is retired from 26th of July. If you are looking to take the new SOA-C02 exam you can find more information on the Coming Soon to AWS Certification page with the exam guide here.
I will look to complete the AWS Certified Developer next to round off all three associate certifications, first however, I want to clear my Certified Kubernetes Administrator (CKA)
As per Red Hat documentation Docker is not supported in RHEL 8.
The Podman, Skopeo, and Buildah tools were developed to replace Docker command features. Each tool in this scenario is more lightweight and focused on a subset of features.
For my latest work project, however, where we will be deploying Kubernetes clusters with Rancher we need RHEL8 and Docker.
Add and enable the docker-ce repo with dnf config-manager. Verify with repolist:
$ sudo dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo
[ec2-user@ip-192-169-2-20 ~]$ sudo dnf repolist -v | grep docker-ce-stable -A10
repo: using cache for: docker-ce-stable
docker-ce-stable: using metadata from Wed 02 Jun 2021 07:27:37 PM UTC.
....
Repo-id : docker-ce-stable
Repo-name : Docker CE Stable - x86_64
Repo-revision : 1622662057
Repo-updated : Wed 02 Jun 2021 07:27:37 PM UTC
Repo-pkgs : 38
Repo-available-pkgs: 38
Repo-size : 937 M
Repo-baseurl : https://download.docker.com/linux/centos/8/x86_64/stable
Repo-expire : 172,800 second(s) (last: Tue 15 Jun 2021 03:49:08 PM UTC)
Repo-filename : /etc/yum.repos.d/docker-ce.repo
Display available versions and install with dnf and the –nobest flag:
[ec2-user@ip-192-169-2-20 ~]$ sudo dnf list docker-ce --showduplicates | sort -r
Updating Subscription Management repositories.
Unable to read consumer identity
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
Last metadata expiration check: 0:40:11 ago on Tue 15 Jun 2021 03:49:08 PM UTC.
docker-ce.x86_64 3:20.10.7-3.el8 docker-ce-stable
docker-ce.x86_64 3:20.10.6-3.el8 docker-ce-stable
docker-ce.x86_64 3:20.10.5-3.el8 docker-ce-stable
docker-ce.x86_64 3:20.10.4-3.el8 docker-ce-stable
docker-ce.x86_64 3:20.10.3-3.el8 docker-ce-stable
docker-ce.x86_64 3:20.10.2-3.el8 docker-ce-stable
docker-ce.x86_64 3:20.10.1-3.el8 docker-ce-stable
docker-ce.x86_64 3:20.10.0-3.el8 docker-ce-stable
docker-ce.x86_64 3:19.03.15-3.el8 docker-ce-stable
docker-ce.x86_64 3:19.03.14-3.el8 docker-ce-stable
docker-ce.x86_64 3:19.03.13-3.el8 docker-ce-stable
Available Packages
[ec2-user@ip-192-169-2-20 ~]$ sudo dnf install --nobest docker-ce
Updating Subscription Management repositories.
Unable to read consumer identity
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
Last metadata expiration check: 0:40:17 ago on Tue 15 Jun 2021 03:49:08 PM UTC.
Dependencies resolved.
===============================================================================================================================================
Package Architecture Version Repository Size
===============================================================================================================================================
Installing:
docker-ce x86_64 3:20.10.7-3.el8 docker-ce-stable 27 M
Installing dependencies:
container-selinux noarch 2:2.162.0-1.module+el8.4.0+11311+9da8acfb rhui-rhel-8-appstream-rhui-rpms 52 k
containerd.io x86_64 1.4.6-3.1.el8 docker-ce-stable 34 M
docker-ce-cli x86_64 1:20.10.7-3.el8 docker-ce-stable 33 M
docker-ce-rootless-extras x86_64 20.10.7-3.el8 docker-ce-stable 9.2 M
docker-scan-plugin x86_64 0.8.0-3.el8 docker-ce-stable 4.2 M
fuse-common x86_64 3.2.1-12.el8 rhui-rhel-8-baseos-rhui-rpms 21 k
fuse-overlayfs x86_64 1.4.0-3.module+el8.4.0+11311+9da8acfb rhui-rhel-8-appstream-rhui-rpms 72 k
fuse3 x86_64 3.2.1-12.el8 rhui-rhel-8-baseos-rhui-rpms 50 k
fuse3-libs x86_64 3.2.1-12.el8 rhui-rhel-8-baseos-rhui-rpms 94 k
iptables x86_64 1.8.4-10.el8 rhui-rhel-8-baseos-rhui-rpms 581 k
libcgroup x86_64 0.41-19.el8 rhui-rhel-8-baseos-rhui-rpms 70 k
libnetfilter_conntrack x86_64 1.0.6-5.el8 rhui-rhel-8-baseos-rhui-rpms 65 k
libnfnetlink x86_64 1.0.1-13.el8 rhui-rhel-8-baseos-rhui-rpms 33 k
libnftnl x86_64 1.1.5-4.el8 rhui-rhel-8-baseos-rhui-rpms 83 k
libslirp x86_64 4.3.1-1.module+el8.4.0+11311+9da8acfb rhui-rhel-8-appstream-rhui-rpms 69 k
policycoreutils-python-utils noarch 2.9-9.el8 rhui-rhel-8-baseos-rhui-rpms 251 k
slirp4netns x86_64 1.1.8-1.module+el8.4.0+11311+9da8acfb rhui-rhel-8-appstream-rhui-rpms 51 k
Enabling module streams:
container-tools rhel8
Transaction Summary
===============================================================================================================================================
Install 18 Packages
Total download size: 108 M
Installed size: 441 M
Is this ok [y/N]: y
Downloading Packages:
firewalld is already disabled so we don’t need to disable it to address concerns about DNS resolution working inside Docker containers.
Add my user to the docker group and start/enable the docker daemon.
[ec2-user@ip-192-169-2-20 ~]$ cat /etc/redhat-release && docker --version
Red Hat Enterprise Linux release 8.4 (Ootpa)
Docker version 20.10.7, build f0df350
Test docker with hello-world.
Automated Install with Ansible
As I have a number of servers to repeat the installation on, I’ll use an ansible playbook.
[ec2-user@ip-192-169-2-108 ansible-rhel8]$ ansible-playbook -i ./inv docker-rancher.yaml -b
PLAY [rancher] ********************************************************************************************************************************
TASK [Gathering Facts] ************************************************************************************************************************
ok: [DevRHEL8-Rancher-03]
ok: [DevRHEL8-Rancher-02]
ok: [DevRHEL8-Rancher-01]
TASK [docker-rancher : Upgrade all packages] **************************************************************************************************
changed: [DevRHEL8-Rancher-02]
changed: [DevRHEL8-Rancher-03]
changed: [DevRHEL8-Rancher-01]
TASK [docker-rancher : Install packages] ******************************************************************************************************
changed: [DevRHEL8-Rancher-03]
changed: [DevRHEL8-Rancher-02]
changed: [DevRHEL8-Rancher-01]
TASK [docker-rancher : Enable docker-ce repo] *************************************************************************************************
[WARNING]: Consider using the dnf module rather than running 'dnf'. If you need to use command because dnf is insufficient you can add 'warn:
false' to this command task or set 'command_warnings=False' in ansible.cfg to get rid of this message.
changed: [DevRHEL8-Rancher-03]
changed: [DevRHEL8-Rancher-02]
changed: [DevRHEL8-Rancher-01]
TASK [docker-rancher : Install docker] ********************************************************************************************************
changed: [DevRHEL8-Rancher-03]
changed: [DevRHEL8-Rancher-01]
changed: [DevRHEL8-Rancher-02]
TASK [docker-rancher : enable docker service] *************************************************************************************************
changed: [DevRHEL8-Rancher-03]
changed: [DevRHEL8-Rancher-02]
changed: [DevRHEL8-Rancher-01]
TASK [docker-rancher : Update sshd_config AllowAgentForwarding] *******************************************************************************
changed: [DevRHEL8-Rancher-03]
changed: [DevRHEL8-Rancher-01]
changed: [DevRHEL8-Rancher-02]
TASK [docker-rancher : Update sshd_config AllowTcpForwarding] *********************************************************************************
changed: [DevRHEL8-Rancher-01]
changed: [DevRHEL8-Rancher-03]
changed: [DevRHEL8-Rancher-02]
TASK [docker-rancher : Update sshd_config GatewayPorts] ***************************************************************************************
changed: [DevRHEL8-Rancher-02]
changed: [DevRHEL8-Rancher-03]
changed: [DevRHEL8-Rancher-01]
TASK [docker-rancher : check bridge networking is allowed] ************************************************************************************
changed: [DevRHEL8-Rancher-03]
changed: [DevRHEL8-Rancher-02]
changed: [DevRHEL8-Rancher-01]
TASK [docker-rancher : check bridge networking is allowed bridge-nf-call-iptables] ************************************************************
changed: [DevRHEL8-Rancher-03]
changed: [DevRHEL8-Rancher-02]
changed: [DevRHEL8-Rancher-01]
TASK [docker-rancher : Add Kubernetes repo] ***************************************************************************************************
changed: [DevRHEL8-Rancher-03]
changed: [DevRHEL8-Rancher-02]
changed: [DevRHEL8-Rancher-01]
TASK [docker-rancher : Install packages] ******************************************************************************************************
changed: [DevRHEL8-Rancher-03]
changed: [DevRHEL8-Rancher-02]
changed: [DevRHEL8-Rancher-01]
TASK [docker-rancher : Update /etc/hosts] *****************************************************************************************************
changed: [DevRHEL8-Rancher-03]
changed: [DevRHEL8-Rancher-01]
changed: [DevRHEL8-Rancher-02]
PLAY RECAP ************************************************************************************************************************************
DevRHEL8-Rancher-01 : ok=14 changed=5 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
DevRHEL8-Rancher-02 : ok=14 changed=5 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
DevRHEL8-Rancher-03 : ok=14 changed=5 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Test as before with ‘docker run hello-world’ and verify docker version:
[ec2-user@ip-192-169-2-7 ~]$ cat /etc/redhat-release && docker --version
Red Hat Enterprise Linux release 8.4 (Ootpa)
Docker version 20.10.7, build f0df350
[ec2-user@ip-192-169-2-250 ~]$ curl https://releases.rancher.com/install-docker/20.10.sh | sh
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 17683 100 17683 0 0 46904 0 --:--:-- --:--:-- --:--:-- 46904
# Executing docker install script, commit: 7cae5f8b0decc17d6571f9f52eb840fbc13b2737
+ sudo -E sh -c 'yum install -y -q yum-utils'
+ sudo -E sh -c 'yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo'
Updating Subscription Management repositories.
Unable to read consumer identity
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
Adding repo from: https://download.docker.com/linux/centos/docker-ce.repo
+ '[' stable '!=' stable ']'
+ '[' rhel = rhel ']'
+ adjust_repo_releasever 8.2
+ DOWNLOAD_URL=https://download.docker.com
+ case $1 in
+ releasever=8
+ for channel in "stable" "test" "nightly"
+ sudo -E sh -c 'yum-config-manager --setopt=docker-ce-stable.baseurl=https://download.docker.com/linux/centos/8/\$basearch/stable --save'
Updating Subscription Management repositories.
Unable to read consumer identity
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
+ sudo -E sh -c 'yum-config-manager --setopt=docker-ce-stable-debuginfo.baseurl=https://download.docker.com/linux/centos/8/debug-\$basearch/stable --save'
Updating Subscription Management repositories.
Unable to read consumer identity
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
+ sudo -E sh -c 'yum-config-manager --setopt=docker-ce-stable-source.baseurl=https://download.docker.com/linux/centos/8/source/stable --save'
Updating Subscription Management repositories.
Unable to read consumer identity
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
+ for channel in "stable" "test" "nightly"
+ sudo -E sh -c 'yum-config-manager --setopt=docker-ce-test.baseurl=https://download.docker.com/linux/centos/8/\$basearch/test --save'
Updating Subscription Management repositories.
Unable to read consumer identity
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
+ sudo -E sh -c 'yum-config-manager --setopt=docker-ce-test-debuginfo.baseurl=https://download.docker.com/linux/centos/8/debug-\$basearch/test --save'
Updating Subscription Management repositories.
Unable to read consumer identity
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
+ sudo -E sh -c 'yum-config-manager --setopt=docker-ce-test-source.baseurl=https://download.docker.com/linux/centos/8/source/test --save'
Updating Subscription Management repositories.
Unable to read consumer identity
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
+ for channel in "stable" "test" "nightly"
+ sudo -E sh -c 'yum-config-manager --setopt=docker-ce-nightly.baseurl=https://download.docker.com/linux/centos/8/\$basearch/nightly --save'
Updating Subscription Management repositories.
Unable to read consumer identity
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
+ sudo -E sh -c 'yum-config-manager --setopt=docker-ce-nightly-debuginfo.baseurl=https://download.docker.com/linux/centos/8/debug-\$basearch/nightly --save'
Updating Subscription Management repositories.
Unable to read consumer identity
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
+ sudo -E sh -c 'yum-config-manager --setopt=docker-ce-nightly-source.baseurl=https://download.docker.com/linux/centos/8/source/nightly --save'
Updating Subscription Management repositories.
Unable to read consumer identity
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
+ [[ 8.2 =~ 7\. ]]
+ '[' 8.2 == 7 ']'
+ sudo -E sh -c 'yum makecache'
Updating Subscription Management repositories.
Unable to read consumer identity
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
Docker CE Stable - x86_64 137 kB/s | 14 kB 00:00
Red Hat Update Infrastructure 3 Client Configuration Server 8 35 kB/s | 2.1 kB 00:00
Red Hat Enterprise Linux 8 for x86_64 - AppStream from RHUI (RPMs) 22 kB/s | 2.8 kB 00:00
Red Hat Enterprise Linux 8 for x86_64 - BaseOS from RHUI (RPMs) 24 kB/s | 2.4 kB 00:00
Metadata cache created.
INFO: Searching repository for VERSION '20.10.7'
INFO: yum list --showduplicates 'docker-ce' | grep '20.10.7.*el' | tail -1 | awk '{print $2}'
+ '[' -n 20.10.7-3.el8 ']'
+ sudo -E sh -c 'yum install -y -q docker-ce-cli-20.10.7-3.el8'
warning: /var/cache/dnf/docker-ce-stable-fa9dc42ab4cec2f4/packages/docker-ce-cli-20.10.7-3.el8.x86_64.rpm: Header V4 RSA/SHA512 Signature, key ID 621e9f35: NOKEY
Importing GPG key 0x621E9F35:
Userid : "Docker Release (CE rpm) <docker@docker.com>"
Fingerprint: 060A 61C5 1B55 8A7F 742B 77AA C52F EB6B 621E 9F35
From : https://download.docker.com/linux/centos/gpg
Installed:
docker-ce-cli-1:20.10.7-3.el8.x86_64 docker-scan-plugin-0.8.0-3.el8.x86_64
+ sudo -E sh -c 'yum install -y -q docker-ce-20.10.7-3.el8'
Installed:
container-selinux-2:2.162.0-1.module+el8.4.0+11311+9da8acfb.noarch containerd.io-1.4.6-3.1.el8.x86_64
docker-ce-3:20.10.7-3.el8.x86_64 docker-ce-rootless-extras-20.10.7-3.el8.x86_64
fuse-common-3.2.1-12.el8.x86_64 fuse-overlayfs-1.4.0-3.module+el8.4.0+11311+9da8acfb.x86_64
fuse3-3.2.1-12.el8.x86_64 fuse3-libs-3.2.1-12.el8.x86_64
iptables-1.8.4-10.el8.x86_64 libcgroup-0.41-19.el8.x86_64
libnetfilter_conntrack-1.0.6-5.el8.x86_64 libnfnetlink-1.0.1-13.el8.x86_64
libnftnl-1.1.5-4.el8.x86_64 libslirp-4.3.1-1.module+el8.4.0+11311+9da8acfb.x86_64
policycoreutils-python-utils-2.9-9.el8.noarch slirp4netns-1.1.8-1.module+el8.4.0+11311+9da8acfb.x86_64
+ '[' -n 1 ']'
+ sudo -E sh -c 'yum install -y -q docker-ce-rootless-extras-20.10.7-3.el8'
+ command_exists iptables
+ command -v iptables
+ start_docker
+ '[' '!' -z ']'
+ '[' -d /run/systemd/system ']'
+ sudo -E sh -c 'systemctl start docker'
+ sudo -E sh -c 'docker version'
Client: Docker Engine - Community
Version: 20.10.7
API version: 1.41
Go version: go1.13.15
Git commit: f0df350
Built: Wed Jun 2 11:56:24 2021
OS/Arch: linux/amd64
Context: default
Experimental: true
Server: Docker Engine - Community
Engine:
Version: 20.10.7
API version: 1.41 (minimum version 1.12)
Go version: go1.13.15
Git commit: b0f5bc3
Built: Wed Jun 2 11:54:48 2021
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.4.6
GitCommit: d71fcd7d8303cbf684402823e425e9dd2e99285d
runc:
Version: 1.0.0-rc95
GitCommit: b9ee9c6314599f1b4a7f497e1f1f856fe433d3b7
docker-init:
Version: 0.19.0
GitCommit: de40ad0
================================================================================
To run Docker as a non-privileged user, consider setting up the
Docker daemon in rootless mode for your user:
dockerd-rootless-setuptool.sh install
Visit https://docs.docker.com/go/rootless/ to learn about rootless mode.
To run the Docker daemon as a fully privileged service, but granting non-root
users access, refer to https://docs.docker.com/go/daemon-access/
WARNING: Access to the remote API on a privileged Docker daemon is equivalent
to root access on the host. Refer to the 'Docker daemon attack surface'
documentation for details: https://docs.docker.com/go/attack-surface/
================================================================================
[ec2-user@ip-192-169-2-250 ~]$
https://releases.rancher.com/install-docker/20.10.sh
Verify as before:
[ec2-user@ip-192-169-2-250 ~]$ cat /etc/redhat-release && docker --version
Red Hat Enterprise Linux release 8.4 (Ootpa)
Docker version 20.10.7, build f0df350
I’ll use this script in later versions of the ansible playbook.
Wrapping Up
I didn’t expect the process of installing docker on RHEL8 to be so easy, I expected to hit dependency issues, but it seems with the later versions of Docker 20.10 many of the install issues are fixed https://medium.com/nttlabs/docker-20-10-59cc4bd59d37 .
It is still not an ideal situation, Red Hat are unlikely to help with any container related issues on opening a support case where we are running docker and not podman on RHEL8, but docker appears to be stable.
Deploy a personal website and blog in AWS using a previously registered domain name: ianstacey.net using the free tier, setting up a WordPress site on a single EC2 instance with Amazon RDS for MySQL to run the MySQL database.
My first step was to create a new VPC in eu-central-1 Frankfurt with a 10.84.0.0/16 CIDR and four subnets, 2 public and 2 private across 2 Availability Zones.
2. Creating a MySQL Database with RDS:
After deleting my first DB as it was associated with all four of my subnets, I created a Subnet Group containing my two private subnets before creating my new DB instance.
Next I created the RDS database, with MySQL as the engine, choosing the latest available version of MySQL and selecting the free tier.
Stepping through the options I set:
My DB instance identifier.
The master username and password for my database.
Instance class and storage details, as I’m using the free tier options are limited.
The configure connectivity and network configuration, choosing my new VPC and Subnet Group
Created a new Security Group, for now without any Inbound rules set, this will come later
Set the initial database name
3. Creating an EC2 Instance:
Next to create an Amazon EC2 instance to run the WordPress site, selecting Launch instance to open the instance creation wizard and selecting
The AMI of Amazon Linux 2
An instance type of t2.micro, free tier-eligible
Selecting my VPC and a public subnet
Minimal storage
Added a Name Tag
Configured a new Security, limiting ssh access from only my home and office IP and allowing HTTP from outside for initial testing
Created and downloaded a new key pair
4. Configuring Your RDS Database
At this point I’ve created my RDS database and my EC2 instance, the next action is to configure the RDS database.
Allow access from the EC2 instance to the RDS database by updating the Security Group created earlier, 3306 as the port and referencing the source Security Group of the instance.
ssh to the EC2 instance with the .pem file downloaded earlier and install a MySQL client to interact with the database
sudo yum install -y mysql
Find the hostname for the RDS database in the AWS console. In the details of the RDS database, the hostname will be shown as the Endpoint in the Connectivity & security section.
Use the dig command from the EC2 instance to check DNS
In the terminal, enter the following command to set an environment variable for the MySQL host. Be sure to replace “<your-endpoint>” with the hostname of the RDS instance.
export MYSQL_HOST=<your-endpoint>
Next, run the following command in the terminal to connect to the MySQL database. Replace “<user>” and “<password>” with the master username and password configured when creating the RDS database.
mysql --user=<user> --password=<password> wordpress
If connected successfully, the terminal should indicate connection to the MySQL database as shown in the following image.
Finally, create a database user for the WordPress application and give it permission to access the “wordpress” database. Run the following commands, substituting “wordpress-pass” for a strong password :
CREATE USER 'wordpress' IDENTIFIED BY 'wordpress-pass';
GRANT ALL PRIVILEGES ON wordpress.* TO wordpress;
FLUSH PRIVILEGES;
Exit
An alternative method to the above is to Configure Authentication Variables.
DBName='wordpress'
DBUser='wordpress'
DBPassword='REPLACEME'
DBRootPassword='REPLACEME'
STEP: Create WordPress DB
echo "CREATE DATABASE $DBName;" >> /tmp/db.setup
echo "CREATE USER '$DBUser'@'localhost' IDENTIFIED BY '$DBPassword';" >> /tmp/db.setup
echo "GRANT ALL ON $DBName.* TO '$DBUser'@'localhost';" >> /tmp/db.setup
echo "FLUSH PRIVILEGES;" >> /tmp/db.setup
mysql -u root --password=$DBRootPassword < /tmp/db.setup
sudo rm /tmp/db.setup
5. Install Apache on EC2
To run WordPress, you need to run a web server on your EC2 instance. Apache and Nginx are popular web servers used with WordPress, choosing the best one is a matter of some debate.
I’ve installed Apache on the EC2 instance with the following command:
sudo yum install -y httpd
To start the Apache web server, run the following commands in the terminal:
sudo service httpd enable
sudo service httpd start
Confirm Apache is working by browsing to the Public IP of the EC2 instance
6. Download and Configure WordPress on EC2
In this step, we will download the WordPress software and set up the configuration.
First, download and uncompress the software by running the following commands in the terminal:
wget https://wordpress.org/latest.tar.gz
tar -xzf latest.tar.gz
If you run “ls” to view the contents of your directory, you will see a tar file and a directory called wordpress with the uncompressed contents.
$ ls
latest.tar.gz wordpress
Change into the wordpress directory and create a copy of the default config file using the following commands:
cd wordpress
cp wp-config-sample.php wp-config.php
Then, open the wp-config.php file using vi:
vi wp-config.php
You need to edit two areas of configuration.
First, edit the database configuration by changing the following lines:
// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define( 'DB_NAME', 'database_name_here' );
/** MySQL database username */
define( 'DB_USER', 'username_here' );
/** MySQL database password */
define( 'DB_PASSWORD', 'password_here' );
/** MySQL hostname */
define( 'DB_HOST', 'localhost' );
The values should be:
DB_NAME: “wordpress”
DB_USER: The name of the user you created in the database in the previous module
DB_PASSWORD: The password for the user you created in the previous module.
DB_HOST: The hostname of the database that you found in the previous module.
The second configuration section you need to configure is the Authentication Unique Keys and Salts. It looks as follows in the configuration file:
/**#@+
* Authentication Unique Keys and Salts.
*
* Change these to different unique phrases!
* You can generate these using the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service}
* You can change these at any point in time to invalidate all existing cookies. This will force all users to have to log in again.
*
* @since 2.6.0
*/
define( 'AUTH_KEY', 'put your unique phrase here' );
define( 'SECURE_AUTH_KEY', 'put your unique phrase here' );
define( 'LOGGED_IN_KEY', 'put your unique phrase here' );
define( 'NONCE_KEY', 'put your unique phrase here' );
define( 'AUTH_SALT', 'put your unique phrase here' );
define( 'SECURE_AUTH_SALT', 'put your unique phrase here' );
define( 'LOGGED_IN_SALT', 'put your unique phrase here' );
define( 'NONCE_SALT', 'put your unique phrase here' );
Go to this link to generate values for this configuration section. Replace the entire content in that section with the content from the link. Save and exit from vi.
With the configuration updated, we are almost ready to deploy the WordPress site. In the next step, we will make your WordPress site live.
7. Deploying WordPress
In this step, we will download the WordPress software and set up the configuration, making the Apache web server handle requests for WordPress.
First, install the application dependencies we need for WordPress. In the terminal, run the following command.
Created a new Elastic Load Balancer with HTTP and HTTPS support
Configured my Security Settings, requesting a new certificate from AWS Certificate Manager (ACM), using DNS validation.
Configure the Security Group
Configured the Routing
Created my Target Groups for the ELB, registered the target EC2 instance and configured the Health Checks
Updated Route 53 to point www.ianstacey.net and blog.ianstacey.net to the new ELB.
ACM Cert Request
Issues:
After configuring the above I hit a couple of issues. Firstly the website was only displaying simple text. Once I fixed that I found links were trying to leave ianstacey.net and follow the Public IP of the instance.
To help isolate and resolve the second issue, I created a very simple static website with a couple of links:
[ec2-user@ip-10-84-1-125 html-static]$ cat index.html
<!DOCTYPE html>
<html>
<title>HTML Tutorial is</title>
<body>
<h1>This is a heading yes</h1>
<p>This is a paragraph oh boy.</p>
<a href="https://www.w3schools.com/">Visit W3Schools.com!</a>
<br>
<a href=link1.html>Visit Link1</a>
<br>
<a href=link2.html>Visit Link2</a>
</body>
</html>
[ec2-user@ip-10-84-1-125 html-static]$ cat link1.html
<!DOCTYPE html>
<html>
<title>HTML Tutorial LINK1 </title>
<body>
<h1>This is a heading LINK1 </h1>
<p>This is a paragraph LINK1</p>
</body>
</html>
[ec2-user@ip-10-84-1-125 html-static]$ cat link2.html
<!DOCTYPE html>
<html>
<title>HTML Tutorial LINK2 </title>
<body>
<h1>This is a heading LINK2 </h1>
<p>This is a paragraph LINK2</p>
</body>
</html>
[ec2-user@ip-10-84-1-125 html-static]$
Then resolved the WordPress settings, switching my apache root back to WordPress.
9. Next Steps
Explore WordPress and its available themes and populate this site.
Secure the site, I have the WP Cerber plugin enabled to help against brute-force attacks on the wp-admin page, limiting login attempts to 5 before blocking an IP address. Attempts to hide the wp-admin with https://wordpress.org/plugins/wps-hide-login/ did not work for me, so I plan to revisit this.
Deploy a second EC2 instance in a different AZ and update my ELB Target Groups.
Tear everything down and redeploy with CloudFormation.
Monitor costs with Cost Explorer to ensure I keep within the free tier with Billing Alerts configured.