Using AWS Certificate Manager and ELB with WordPress

Over the last couple of weeks, I’ve been using this website as a way to learn more about Amazon Web Services. I’ve always found topics easier to learn when I have something practical to apply them to.

During some time away from work, I started looking into making this site HTTPS. Security is something which interests me in and out of work, so it seemed like a good idea.

The plan was to add HTTPS to my WordPress EC2 instance, but I didn’t know much more than that.

I knew that Amazon had Certificate Manager, so I started there.

Here is the first piece of AWS awesomeness, but with a cost: they will give you a free certificate, but currently you can only use it with their Elastic Load Balancing. On first consideration, I thought this was going to be a hassle and increase the work required, but now on reflection, I think this is a good approach.

I can add ELB in front of my EC2 instance and use that to terminate my SSL connections. Now my application doesn’t really have to change; it can be oblivious to the security layer I want to add.

Two different ELB styles

To reduce complexity I went with the Classic Load Balancer instead of the Application Load Balancer. I didn’t feel I needed any of the application level features.

One thing to watch out is that the default health check uses “/index.html”. The install of WordPress I’m using produced an error for that URL and the ELB took my instance out of its pool, this effectively took my site down. Changing the health check to “/” was easy and brought me back online.

Out-of-the-box ELB comes with some really useful monitoring baked into its console UI. This was great for identifying and resolving the problem, a common theme on this platform.

ELB Metrics

I choose to maintain both HTTP and HTTPS for my website, mapping both the HTTP on my instance. Again my instance doesn’t know anything about the ELB.

mapping http and https

Java builds on Travis CI .org

I’d seen the name Travis a number of times in relation to Continous Integration, but never having any non-work repositories I’d never paid any attention to anything other than Jenkins.

But since starting on more private projects I did come to miss not having a  ‘it works on my machine’ check. I didn’t really have an appetite to setup Jenkins locally, although it might not be much hassle with Docker and compose, it just wasn’t something I wanted to spend time on.

This is where Travis-ci.org comes into the picture. Firstly it is completely hosted; secondly, it’s completely free. (Enterprise packages available on travis-ci.com)

The org site is specifically set up to ease integration with your own Github repositories. Once you’ve signed in with the SSO/SAML magic you’re given a list of your private repos and simple tick boxes for which you want to enable.

From there is a tiny domain-specific language file you need to insert into the root of your repo. I’ve included the simplest Java one I could get away with as an example below.

file: .travis.yml

language: java
jdk:
- oraclejdk8
sudo: false
script: mvn clean verify

The build will then trigger whenever you push to the repo. Each build produces a summary plus the raw build process output.

Adding Graphite support to Spring Boot Actuator

I made a very simple Graphite implementation of the MetricWriter interface, you can see the code in my GitHub repo spring-boot-actuator-graphite.

If you want to use it in a production environment please be aware that it does open and close a new Socket connection for each metric measurement.

Assuming you have a Spring Boot Actuator project, below is an example @Configuration class to enable writing your metrics to Graphite.

 
@Configuration
public class MonitoringConfiguration {

    @Value("${spring.metrics.export.graphite.prefix}")
    private String prefix;

    @Value("${spring.metrics.export.graphite.host}")
    private String host;

    @Value("${spring.metrics.export.graphite.port}")
    private int port;

    @Bean
    public MetricsEndpointMetricReader metricsEndpointMetricReader(MetricsEndpoint metricsEndpoint) {
        return new MetricsEndpointMetricReader(metricsEndpoint);
    }

    @Bean
    @ExportMetricWriter
    MetricWriter metricWriter() {
        return new GraphiteMetricWriter(this.prefix, this.host, this.port);
    }
}