Aurora Serverless – notes


Serverless is the trendy word of 2018 and everything is serverless or wannabe serverless. Aurora is no exception, and it is also reaching towards serverless. Aurora serverless introduced actually last Re:Invent and the preview phase lasted for half a year. Since summer it has been generally available.

Under the hood

Launching Aurora as ‘Serverless’ is no more difficult than launching Aurora to be a ‘traditional’ SQL database. Only a few clicks and Aurora serverless is ready to rock. The most interesting feature is the automatic scaling.  One can set minimum and maximum limits in terms of ACU. Minimum is 2 ACU and scaling steps includes always even amount of ACUs (2,4,6, on). In addition it is possible to go full serverless in terms of scaling to allow 0 ACU if there is no traffic to the database. For budget perspective that sounds great, as the costs can be pressed down during the idle times.  For the budget calculations it is good to remember that even though the price is per ACU, there are always min 2 (or 0 if sleeping). The price for 2 ACUs is slightly greater than smallest ‘traditional’ Aurora, so if the use scenario requires cheap and always on database, maybe Aurora Serverless is not the answer.

And that leads us to the wake-up time of the sleeping database. It seems to be 25s or a bit less for the first request to get the response. Of course after that the database is fast and there is no delays between queries and responses. If that is something that cannot be live with, one can define a long idle time (24h max) before database goes to sleep and maybe some crons to keep the database awake… But Aurora Serverless documentation indicates that it might be excellent fit for development databases as there are typically no red flags for the waking-up delays.

However, it is possible to use CloudWatch Metrics for Aurora Serverless and query whether the database is sleeping or not. Then this information can be used in the application in some novel way, for example hiding the waking up phase from the user…

CLI command example:

$> aws cloudwatch get-metric-statistics --metric-name ServerlessDatabaseCapacity --start-time 2018-09-19T12:19:00Z --end-time 2018-09-19T12:20:00Z --period 60 --namespace AWS/RDS --statistics Maximum --dimensions Name=DBClusterIdentifier,Value=<name> --region <region>

Another difference between Aurora Serverless and traditional Aurora is the amount of cluster endpoints; aurora serverless has only one. There is no dedicated endpoints for writer and reader(s). That indicates automatic scaling to affect also writer instead of only to the amount of readers. However, the performance of such scaling is not yet a widely available. Furthermore, the comparison to Aurora Multi-Master would be highly interesting. Nevertheless, Aurora Serverless is highly interesting product and will be widely used as it will takes away the database scaling from the user. Administrative tasks will be somewhat relieved.


Application Load Balancer & new actions


Application Load Balancer received upgrade last summer as redirect and fixed responses were introduced as new actions.  Therefore, action possibilities contains at the moment Forward, Authenticate (HTTPS listener only), Redirect, and Fixed responses. These two latest actions enable some simplifications to the environment.


I find the Redirect very useful and a real word example is HTTP to HTTPS redirect. HTTP requests don’t need to reach the webserver anymore for HTTP -> HTTPS redirect as the magic happens at the load balancer. Apache/NGINX can be configured to listen only one traffic port as all traffic will be routed through that port. For setting HTTP-> HTTPS redirect up at the ALB, it is only required to select HTTP Listener and a new rule; first the Condition (either Path or Host) and then Redirect Action and type 443 in to the console. The result is that all HTTP requests are redirected to HTTPS.

Figure 1. Redirect as a new action.

Fixed responses

The trend is to move some of the activities away from webserver to the load balancer and utilizing a fixed response is one. For example, certain HTTP error codes can be handled on the load balancer level. Clearly some benefits, but I see that the Redirect will be somewhat more widely used.

Even though these new features will make life somewhat easier, there is one feature that still remains on my wish list. Support for the Application controlled session cookies.



AWS revenue jumps 49% in Q1/2018


The performance of the AWS remains strong. Already last year was excellent but the current year seems to accelerate the pace.  One year might be too short window to use but the picture is not so different with wider window. In two years the revenue has more than doubled from Q1/2016 and $2.566B to  $5.442B. From cash flow perspective, the impact of the AWS is crucial for Amazon. The quarter was good for Amazon (net income $1.9B in Q1) in particular due to the AWS as it generated net income of $1.4B alone.

It is worth to keep in mind that also other big public cloud vendors have increased their revenues a lot. Cloud market is bigger than ever and there are no indications that it will decrease any day soon. All of that underlines the trend that everyone is relying more and more on cloud based infrastructure. It is easy to point out the winners but where are the losers and how they can survive.  The only way to decrease the impact the is modifications to business models. Selling just capacity is not enough anymore and business models should leverage to new dimension, maybe content.

Amazon itself has studied new business innovations in retail industry a lot and one of the interesting one is Amazon Go.  That is a shop where are not clerks, customers just pick what they like and after they leave the shop they are automatically billed. For customer perspective that sounds fast, simple and convenient way to do shopping. Maybe that is the future…


Using S3 as a source action for CodePipeline


Rather new feature is to set S3 bucket to trigger CodePipeline (AWS blog).  There have been around scheduled pulls option for CodePipeline and S3 connection but since March 2018 also ‘push’ option is possible. There are good references available to set CodePipeline and that is therefore skipped in this blogpost. Lets run through a scenario where a new version arrives by Lambda. Let say the s3 bucket to be used is s3sourcebucket and the code is in the

At first, versioning has to be turned on for S3 bucket. CodePipeline job can be identified by the version identifier. So after versioning turned on the S3 bucket is all set.

Then the focus is on CodePipeline. Lets use the CodePipeline console to configure the s3://s3sourcebucket/ as the code source as (according to the documentation) CloudTrail and CloudWatch Events are automatically created and linked to the CodePipeline. Whenever new version is uploaded to the bucket, CloudTrail logs the API call, CloudWatch Event rule catch the CloudTrail logged trail and invokes the correspondent CodePipeline.

Below is an example of the automatically generated CloudWatch event rule. As default,  event pattern is built to match the entire event.

  "source": [ "aws.s3" ],
  "detail-type": [ "AWS API Call via CloudTrail" ],
  "detail": {
    "eventSource": [ "" ],
    "eventName": [ "PutObject" ],
    "resources": {
       "ARN": [ "arn:aws:s3:::s3sourcebucket/" ]

As the snippet points out, CloudWatch event rule is looking for “PutObject” as an EventName. That is the correct event name for ‘put’, as if IAM user is uploading a fresh file to the bucket. However, if the file transfers to the bucket by a copy operation, as if Lambda copies the file from somewhere to the bucket, then the EventName is not match. And the CodePipeline won-t be invoked. The correct event name is “CopyObject” for that occasion.  As a general hint for debugging, double-check the CloudTrail log for the correct event name and confirm that the same phrase is used in the CloudWatch Event rule.


Cloudfront for S3 website

S3 website is rather cheap serverless solution for delivering static websites such as single page applications. S3 architechture is regional and the website will face various latencies based on geographical location of the client. Latencies might vary from a few milliseconds to few hundreds. For some applications that might not be crucial but some other should utilize Content Delivery Network (CDN) to decrease latencies. CDN service in AWS is Cloudfront. Furthermore, S3 endpoint accepts only HTTP traffic from internet but with Cloudfront also HTTPS traffic is possible to be configured (between client and Cloudfront, but between Cloudfront and S3 bucket there is still HTTP).

Cloudfront is one of the global services in AWS that can be used to take the first hit and deliver the request further to dedicated region(s). Most likely due to the global approach the Cloudfront configuration has us-east-1 perspective. For example the custom SSL certificate should be requested for that region (through ACM) before those can be connected to the distribution. So even though the bucket is on any other region, the SSL certificate have to be requested to us-east-1.

Notes for distribution creation

It would be appealing to select the S3 Bucket as Origin Domain Name but that would not be correct (*). S3 Website is a custom origin and the Origin Domain Name should be the address of the S3 website (i.e. the word ‘s3-website’ should be there). Surprisingly, none of the s3-related options on the list is the correct one – they all point to S3 bucket not to the website… So copy-paste the s3-website address to the Origin Domain Name -field.

Due to the custom origin, Origin Access Identity cannot be used to control the access to the S3 bucket. And therefore -by default- any request can go directly to S3 website bypassing CloudFront. One way to confirm that S3 website is not accessible directly but only through Cloudfront is to define a Custom Header and set a long&random value for it. And update the bucket policy to deny all other requests. Below is an example bucket policy utilizing User-Agent as a custom header. Finally the CNAME should match to the S3 bucket name and then Route53 can be updated accordingly.

    "Version": "2012-10-17",
    "Id": "Policy15226007",
    "Statement": [
            "Sid": "CFaccess",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": [
            "Condition": {
                "StringNotEquals": {
                    "aws:UserAgent": "fgrt45gfrt32hGGdsdeWEFgdd"


(*) Cloudfront configuration is somewhat different when S3 bucket is not configured as a website. In this scenario, S3 bucket is just a place for SPA files. However, keeping S3 bucket as bucket (and selecting S3 as origin) requires that Cloudfront configuration includes:

a) default file (for example index.html) and

b) routing for Error(s), such as 403. The custom error pages are required as the requested file might not be there as it is SPA and errors should be handled by the SPA.  


Brief notes from AWS Community Day Nordics

On last Wednesday the tradition began at Clarion Helsinki. Over 300 AWS enthusiastics witnessed the arrival of the AWS Community Days to Nordics. The structure of the one day event was following to the typical seminar day, with keynotes and multitrack sessions. Slides are expected to be available afterwards. Tracks were titled with ‘Main’, ‘Serverless’, and ‘Data + ML’ and for the two latter ones the content were pretty self-explanatory. I participated in Serverless track but unfortunately, I was not able stay for the whole day due to the other commitments. The serverless approach was also present in the first keynote where Martin Buberl from Trustpilot discussed the journey they have had towards serverless architecture. The number of EC2s has been decreased as tasks have been processed by Lambdas instead. And as a EC2 is typically replaced by more than single Lambda, it is expected that the number of Lambdas is growing faster than the number of EC2 is shrinking.

The first session at Serverless track was hosted by Paul Lyons from Nordcloud and it focussed on Serverless framework. The demo was about serverless backend but the content was not the most interesting element. The framework was somewhat familiar for me in advance but the discussions strengthened my understanding that for the serious serverless approach the Serverless framework is a great tool. Serverless Framework can be used with various plugins and the related community is active. For example there is plugin for a rather new service called AppSync (my personal favorite service currently). Paul mentioned during his show that S3 event trigger for Lambda is not working well at the moment with Serverless and one have to activate that in the console. Using console is something that is not preferred when using Serverless…

Fellows from Zalando, Uri Savelchev & Ruben Diaz, discussed about Kubernetes. They have built custom deployment tool as they had found all available tools cumbersome to some extent, at least out-of-the-box. Zalando has independent teams and these teams operate in various sites in Europe. As a result they have numerous AWS accounts. Zalando seems to utilize AWS a lot.

It was a great day and I got lots of new ideas. Hopefully the next Community day is not too far away.


CodePipeline & CodeBuild & S3 website

Single Page Applications (SPA) are convenient as they provide a smooth user experience. For SPAs React is a good choice. But this blog is not about React, this is about AWS services that can be used in automatic deployment of SPA.  AWS services to be discussed are CodePipeline, CodeBuild,  CodeCommit, and S3.


S3 is appealing service not only from a storage perspective but also due to the possibility to configure it to work as a static website; combining low price and high scalability.  S3 website is also a ‘Serverless’ approach. The lack of IP address can be handled with Route53 (using S3 website as an alias). But lets move on and say the name of the static-website bucket is


The CodePipeline can be used as the main framework to address the continuing development. The pipeline can include several phases and each of the phases can be one of the handful of types. A basic pipeline contains just the source of the code (CodeCommit) and a buildphase (CodeBuild). There is no need to set any deployment phase. CodePipeline stores all output artifacts of the phases in S3 bucket and if those artifacts are used for example by Lambda in another phase of the pipeline, IAM policy with suitable permissions to the codepipeline-bucket should be attached to the Lambda’s service role.


Integration between CodeCommit and (for example) Git makes it convenient starting point of the pipeline. Once user credentials for IAM user are set up, the user is able to connect the CodeCommit. The CLI-usage of the CodeCommit is not different than Git as the user experience is exactly the same. Setting up CodeCommit as the source for CodePipeline is presented in figure 1.

Figure 1. Setting up CodePipeline


CodeBuild project can be setup through CodeBuild console and then it is possible to select existing CodeBuild project in the CodePipeline console. However, creating the CodeBuild project through CodePipeline console tackles some issues relating permissions and odd errors. CodeBuild will be invoked by CodePipeline not CodeCommit. Once the CodeBuild project has been created through CodePipeline console, the source is correct (CodeBuild project has the Current source: AWS CodePipeline) . Setting up the CodeBuild through CodePipeline is presented in figure 2.

Figure 2. Creation of CodeBuild project through CodePipeline console

The heart of the CodeBuild project is the buildspec.yml file. The build process is divided into several phases that can be used to run custom commands and scripts (check the example of buildspec.yml file below). The formal syntax of the yml-file is crucial, and it seems to be typical that syntax-errors are not necessary very conveniently identified from the logs. So make sure all those spaces are correct! As shown below (post-build phase), the build files are copied to bucket. The sufficient IAM policy with permission to access the bucket should be attached to the CodeBuild service role.

version: 0.2




      - npm install



      - npm run build



      - aws s3 sync --delete build/ s3:// --acl public-read

Also notice that the version number (0.2) is not a random number. It is a static number defined by AWS.


Sharing AMI between 2 accounts

Configurate and tune an EC2 could be fun. At least once. At some point is good to have the image of the finalized EC2 at hand to make similar instances  quicker. Amazon calls images as Amazon Machine Images (AMIs). These hand-made and polished AMIs can be used conveniently for example in Launch configurations. The amount of further configuration is decreased during the autoscaling with hand-made AMIs. Even though AMIs are regional and private by default, it is possible to share those between two accounts. If the AMI is required on the other region, it have to be copied first to that region.  Nevertheless, the first step is to create the AMI.

Step 1 – Create the image

Even though it is not necessary a must to stop the instance before the image creation, it is highly recommended. At least the reboot should be allowed during the process. Quite often the image is not working due to the creation process that had not included reboot or stopped instance. After the instance is stopped, just go to Actions and select Create Image (figures 1 & 2).


Figure 1. Stop the instance and go to Actions

Figure 2. Create image

Step 2. – Share the image

The image creation status can be found on Images -> AMIs right after the image creation has been started. Image is actually an EBS snapshot and therefore snapshot creation status can be found on Elastic Block Storage -> Snapshots. After a few minutes the image creation status reaches available status.

Sharing the image, select Modify Image Permissions and add permission to the target AWS account id (figure 3).

Figure 3. Add permissions to the AMI

Step 3. Launch the image on the target account

Log in to the target AWS account and select Launch instance. Choose My Amis -> Shared with me and pick just shared created AMI (figure 4).  As a side note, sharing RDS snaphots is a similar & simple task and there are a lot analogues in the RDS-snapshot sharing  process between accounts.

Figure 4. Select & Launch the AMI that is Shared with me


VPN between on-Prem and AWS

Sometimes is necessary to have a secure connection between AWS services and on-premise devices. Or between two AWS accounts, or two VPCs in separated regions (as VPC peering is suitable only for VPCs within the same region -> update: intra-regions possible between certain regions. Yet, Security Groups are not visible between regions ). For these occasions, the solution can be based on AWS VPN connections -service that is found through VPC console. Furthermore, the VPN connections is divided to three parts; Virtual Gateway, Customer Gateway and VPN tunnel between these (i.e. VPN Connections). The VPN solution is based on two Ipsec tunnels; active-passive mode for redundancy.

First step is to create a CGW or -to be more precise- tell AWS what is the IP address of the on-prem VPN gateway. Therefore, the climax to configure CGW is to remember the IP address of the on-prem gateway. In addition, there is the decision between static and dynamic routing. The second step is creating VGW. That is a straightforward task, just give it a proper name and remember to attach it to the VPC.

Configuring VPN tunnel between these is the next step. Select previously created VGW and CGW. Static or dynamic routing? Naturally the decision should be consistent with the previous decision. Static is somewhat quicker to setup as there is no need to advertise routes. The setup of the static and dynamic routing are very similar. For dynamic routing, ASN should between 64512 and 65534 and routes to the AWS private CIDR block should be advertised at the CGW.

After VPN connection is created, select the connection and download configuration file for the on prem setup. There are numerous configuration files available and I am confident that even if the right one is absent, those available ones can be used to help finding the right steps&values. The file contains step by step instructions how to configure the CGW. (Majority of the lines can be copy-pasted and only a few lines require some tuning. Double check the IP values and CIDR blocks as well as keep in mind that on-prem is the <left> side and AWS is the <right> side.)

Finally update VPC route tables. Route all traffic with “destination: <on-prem CIDR block>” to VGW in those route tables that are preferred (most likely private route table(s)). Don’t forget to update security groups to allow traffic from on-prem CIDR block.

AWS side of the task is done.



WordPress site: Lessons learnt

I had a somewhat limited experience about WordPress sites until I decided to host one on EC2. I kinda like to learn new and I was ready to learn all by the hard way. Luckily internet is full of WordPress related examples, tip, hints and nice to know items. Those are scattered around the net. Someone might find that frustrating but I think that is part of the fun. And, as a whole, it has been a great journey with ups and downs. In this blog I share  a few interesting notes from my journey.

Write permissions

As everyone is aware of, just installing WordPress is not enough. WordPress have to grant a permission to work with the files. So

  • give write permission to wp-content and wp-includes folders
  • ownership of the WordPress files should be (for example) apache


Changing default settings for permalinks will make the site  more or less unreachable.  I find that the reason is not WordPress itself but the webserver. Webserver should allow the change in the address. For example in Apache the file to be tuned is the conf-file.

  • make sure that there is AllowOverride All


Default values in /etc/php.ini are not suitable for serious WordPressing. I keep wondering why. I am confident that there is an excellent reason. Maybe I find it someday. Meanwhile I propose some tuning to the php.ini.

  • increase max upload size to 100M
  • increase memory_limit for example 256M

Beyond these notes I strongly advice to look for the best configuration for each WordPress site that you might be hosting. Clearly these notes don’t include the full list of recommended changes but hopefully this is a good start. 🙂