Deploying a POCO REST API Server to AWS EC2
4 minute read.
In Multiplayer Net Adventures I deployed a POCO based WebSocket server to Digital Ocean 1.
Now I need to deploy a POCO-based 2 RESTful Web Service and I chose to learn about Amazon AWS in the process. Hence, I will be deploying to EC2 and using letsencrypt for SSL encryption.
The "right" way?
When half way through the process I found that the “true”/“right”/“scalable” way to deploy an API to AWS would be through the API Gateway in which you define your endpoints to then forward requests to EC2, Lambda or other services.
You could then use Certificate Manager even, which for my use cases is overkill, though. (It starts at 400$/month).
While my approach here is less scalable, it is simpler and more straight forward.
Setting Up EC2
If you head over to the EC2 page, you can easily spin up a small EC2 instance for free. Just sign in to the Dashboard and click “Launch Instance”, it will take you through the necessary setup.
In the process you will also generate a keypair to access your instance and a security group to control incoming traffic to your instance for SSH and HTTPS.
Connecting
With your keypair, you can now SSH into your instance. I found the AWS documentation to be very thorough and helpful. You can find information on how to connect to your instance on this page. It will guide you through any combination of host and instance OS and also tell you how to convert the key for PuTTY on Windows for example.
Find the username you need to connect with in the above document aswell.
Getting Certificates
Let’s Encrypt offers free automatic certificates that can be acquired with scripts available for basically every system through Certbot.
Make sure to add a temporary inbound rule---to allow HTTP for the certificate challenge--- to your security group.
Running a POCO Application
You will obviously need to compile POCO and your application for the system and distribution you chose for your instance. Choosing a more recent system version will save you some hassle about compiling with an older version of GCC, so keep that in mind.
I wanted to avoid cluttering my EC2 instance with compilers, cmake, and development libraries, so I set up Gitlab CI to build on a docker image for my system.
Deploying from Gitlab CI onto an AWS EC2 instance is a matter of creating another keypair, ensuring the security groups are configured to allow SSH traffic from your Gitlab CI runners (or the Gitlab.com shared runners) and then using the following config:
deploy:<system>:aws-ec2:
image: <system>
stage: deploy
only:
- tags
before_script:
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" > key.pem
- chmod 0400 key.pem
- ssh-add key.pem
script:
- scp -i key.pem -oStrictHostKeyChecking=no -r install/* ${SERVER}:/destination/dir/
dependencies:
- build:<system>
when: on_success
Where ${SERVER} is the same destination you used to connect via SSH, including username, e.g. username@1.2.3.4, and the ${SSH_PRIVATE_KEY} variable contains your private key.
Configuring your POCO Application
To allow your POCO application to use the freshly acquired certificat, you need to have a .properties file.
This configuration worked for me (make sure to replace <domain> appropriately):
openSSL.server.privateKeyFile = /etc/letsencrypt/live/<domain>/privkey.pem
openSSL.server.certificateFile = /etc/letsencrypt/live/<domain>/fullchain.pem
openSSL.server.verificationMode = none
openSSL.server.loadDefaultCAFile = true
openSSL.server.cipherList = HIGH:MEDIUM:!aNULL:!EC4:!MD5:!SEED:!IDEA
openSSL.server.privateKeyPassphraseHandler.name = KeyFileHandler
openSSL.server.privateKeyPassphraseHandler.options.password = <password>
openSSL.server.invalidCertificateHandler.name = AcceptCertificateHandler
openSSL.server.extendedVerification = false
openSSL.server.cacheSessions = true
openSSL.server.sessionIdContext = ${application.name}
openSSL.server.sessionCacheSize = 100
openSSL.server.requireTLSv1 = false
openSSL.server.disableProtocols = sslv2
This requires you to have the application load property files and use HTTPS, which in turn requires initializing SSL. If you are interested in a walkthrough, give me a hint through social media or email.
Footnotes
-
Here’s a referal link. Use it to get 10$ to start off with. ↩
-
POCO — C++ libraries for building network- and internet-based applications ↩