Introduction

In this tutorial, we will explore how we can deploy Kill Bill in AWS by leveraging the existing Docker Kill Bill container.

The deployment deploy one EC2 instance where Kill Bill, Kaui and the MySQL containers will run.

Note that those steps are mostly for the purpose of a demo; they omit production-like features such as DB backup, monitoring, or even deploying multiple EC2 instances for HA or horizontal scalability purpose. However, all those are more a matter of configuring AWS towards that end and spawning more instances, so in final, the steps can be used as a basis to deploy Kill Bill in the cloud to handle your production traffic.

Requirements

AWS API user

You need to create an AWS account and have an access to the AWS console.

Once logged-in, create a new IAM user:

  1. Click "Add User". On the next screen, pick a username and make sure to check "Programmatic access".

  2. Attach the following policy. Replace %AWS_ACCOUNT_ID% with your account ID (that you can get from the My Account page) and update the region eu-west-1 as needed:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "TheseActionsDontSupportResourceLevelPermissions",
            "Effect": "Allow",
            "Action": [
                "ec2:CreateKeyPair",
                "ec2:DeleteKeyPair",
                "ec2:ImportKeyPair",
                "ec2:Describe*",
                "ec2:CreateTags",
                "ec2:CreateSecurityGroup",
                "ec2:AuthorizeSecurityGroupIngress"
            ],
            "Resource": "*"
        },
        {
            "Sid": "ThisActionsSupportResourceLevelPermissions",
            "Effect": "Allow",
            "Action": ["ec2:RunInstances"],
            "Resource": [
                "arn:aws:ec2:eu-west-1::image/ami-*",
                "arn:aws:ec2:eu-west-1:%AWS_ACCOUNT_ID%:instance/*",
                "arn:aws:ec2:eu-west-1:%AWS_ACCOUNT_ID%:key-pair/*",
                "arn:aws:ec2:eu-west-1:%AWS_ACCOUNT_ID%:network-interface/*",
                "arn:aws:ec2:eu-west-1:%AWS_ACCOUNT_ID%:placement-group/*",
                "arn:aws:ec2:eu-west-1:%AWS_ACCOUNT_ID%:security-group/*",
                "arn:aws:ec2:eu-west-1:%AWS_ACCOUNT_ID%:subnet/*",
                "arn:aws:ec2:eu-west-1:%AWS_ACCOUNT_ID%:volume/*"
                ]
        },
        {
            "Sid": "TheseActionsSupportResourceLevelPermissions",
            "Effect": "Allow",
            "Action": [
                "ec2:TerminateInstances",
                "ec2:StopInstances",
                "ec2:StartInstances",
                "ec2:RebootInstances"
            ],
            "Resource": [
                "arn:aws:ec2:eu-west-1:%AWS_ACCOUNT_ID%:instance/*"
            ]
        }
    ]
}
  1. Note the access key and secret

Populate the following environment variables:

  • AWS_ACCESS_KEY_ID: IAM user access key

  • AWS_SECRET_ACCESS_KEY: IAM user secret key

  • AWS_DEFAULT_REGION: AWS region (matching the policy above)

AWS VPC

  1. Go to Services → VPC → Your VPCs and locate the VPC ID you would like to use from the VPC column. Populate the AWS_VPC_ID environment variable with it.

  2. Go to Services → VPC → Subnets. Examine the Availability Zone column to verify that zone a exists and matches your VPC ID (if it doesn’t, you must create a new subnet in that zone).

Docker

This guids assumes you have installed Docker, Docker Machine and Docker Compose.

EC2 setup

Create the saas machine as such:

docker-machine --debug \
               create  \
               --driver amazonec2 \
               --amazonec2-access-key $AWS_ACCESS_KEY_ID \
               --amazonec2-secret-key $AWS_SECRET_ACCESS_KEY \
               --amazonec2-vpc-id $AWS_VPC_ID \
               --amazonec2-region $AWS_DEFAULT_REGION \
               --amazonec2-zone a \
               --amazonec2-instance-type c4.xlarge \
               --amazonec2-root-size 250 \
               saas

Note: we recommand using c4.xlarge instances or larger (at least 7.5GB RAM).

If the command is successful, run:

  1. eval "$(docker-machine env saas)"

  2. docker ps

You should have no error and the output should be empty:

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

Kill Bill Setup

Next, create a docker-compose.yml file similar to the one below:

version: '3.2'
volumes:
  db:
services:
  killbill:
    image: killbill/killbill:0.20.0
    ports:
      - "8080:8080"
    environment:
      - KILLBILL_DAO_URL=jdbc:mysql://db:3306/killbill
      - KILLBILL_DAO_USER=root
      - KILLBILL_DAO_PASSWORD=killbill
  kaui:
    image: killbill/kaui:latest
    ports:
      - "9090:8080"
    environment:
      - KAUI_CONFIG_DAO_URL=jdbc:mysql://db:3306/kaui
      - KAUI_CONFIG_DAO_USER=root
      - KAUI_CONFIG_DAO_PASSWORD=killbill
      - KAUI_KILLBILL_URL=http://killbill:8080
  db:
    image: killbill/mariadb:0.20
    volumes:
      - type: volume
        source: db
        target: /var/lib/mysql
    expose:
      - "3306"
    environment:
      - MYSQL_ROOT_PASSWORD=killbill

and run:

docker-compose up

3 containers will start:

  • one for MariaDB (shared database, used by both Kill Bill and Kaui)

  • one for Kill Bill

  • one for Kaui

Get the public IP of you EC2 instance:

docker-machine ip saas

and verify you can access Kaui at http://W.X.Y.Z:9090.

Stripe setup

Go to the Kaui tenant page:

  1. Click the "Plugin Config" tab

  2. Enter "stripe" as the plugin name

  3. Specify your Stripe secret key

End to end testing

Use our demo to test a full end to end flow:

  • Use Stripe.js to tokenize the card

  • Store the token in Kill Bill for subsequent (or recurring) payments

  • Create subscriptions, generate invoices and trigger automatic payments

  • Retrieve a Kill Bill payment in your Stripe dashboard