AWS Developer Tools Blog
Introducing the ‘aws-rails-provisioner’ gem developer preview
AWS is happy to announce that the aws-rails-provisioner gem for Ruby is now in developer preview and available for you to try!
aws-rails-provisioner gem is a tool that helps you define and deploy your containerized Ruby on Rails applications on AWS. It currently only supports AWS Fargate.
aws-rails-provisioner is a command line tool using the configuration file
aws-rails-provisioner.yml to generate AWS Cloud Development Kit (CDK) stacks on your behalf. It automates provisioning AWS resources to run your containerized Ruby on Rails applications on AWS Fargate with a few commands. It can also generate a CI/CD AWS CodePipeline pipeline for your applications when you enable its CI/CD option.
Why use aws-rails-provisioner?
Moving a local Ruby on Rails application to a well-configured web application running on the cloud is a complicated task. While
aws-rails-provisioner doesn’t change this into a “one-click” task, it helps ease the most monotonous and detail-oriented aspects of the job.
aws-rails-provisioner gem shifts your primary focus to component-oriented definitions inside a concise aws-rails-provisioner.yml file. This file defines the AWS resources your application needs, such as container image environment, a database cluster engine, or Auto Scaling strategies.
The new gem handles default details—like VPC configuration, subnet placement, inbound traffic rules between databases and applications—for you. With CI/CD opt-in,
aws-rails-provisioner can also generate and provision a predefined CI/CD pipeline, including a database migration phase.
For containerized Ruby on Rails applications that you already maintain on AWS,
aws-rails-provisioner helps to keep the AWS infrastructure for your application as code in a maintainable way. This ease allows you to focus more on application development.
Before using the preview gem, you must have the following resources:
• A Ruby on Rails application with Dockerfile
• A Docker daemon set up locally
• The AWS CDK installed (requires `Node.js` >= 8.11.x)
npm i -g aws-cdk
Getting started with aws-rails-provisioner is fast and easy.
Step 1: Install aws-rails-provisioner
You can download the
aws-rails-provisioner preview gem from RubyGems.
To install the gem, run the following command:
gem install 'aws-rails-provisioner' -v 0.0.0.rc1
Step 2: Define your aws-rails-provisioner.yml file
aws-rails-provisioner.yml configuration file allows you to define how and what components you want
aws-rails-provisioner to provision to run your application image on Fargate.
aws-rails-provisioner.yml file looks like the following format:
version: '0' vpc: max_azs: 2 services: rails_foo: source_path: ../sandbox/rails_foo fargate: desired_count: 3 public: true envs: PORT: 80 RAILS_LOG_TO_STDOUT: true db_cluster: engine: aurora-postgresql db_name: myrails_db instance: 2 scaling: max_capacity: 2 on_cpu: target_util_percent: 80 scale_in_cool_down: 300 rails_bar: ...
aws-rails-provisioner.yml file overview
The aws-rails-provisioner.yml file contains two parts:
services. VPC defines networking settings, such as Amazon VPC hosting your applications and databases. It can be as simple as:
vpc: max_az: 3 cidr: '10.0.0.0/21' enable_dns: true
aws-rails-provisioner defines a default VPC with three Availability Zones containing public, private, and isolated subnets with a CIDR range of 10.0.0.0/21 and DNS enabled. If these default settings don’t meet your needs, you can configure settings yourself, such as in the following example, which defines the subnets with details:
vpc: subnets: application: # a subnet name cidr_mark: 24 type: private ...
You can review the full range of VPC configuration options to meet your exact needs.
services portion of aws-rails-provisioner.yml allows you to define your Rails applications, Database cluster, and Auto Scaling policies.
For every application, you can add their entry with identifiers like:
services: my_awesome_rails_app: source_path: ../path/to/awesome_app # relative path from `aws-rails-provisioner.yml` ... my_another_awesome_rails_app: source_path: ./path/to/another_awesome_app # relative path from `aws-rails-provisioner.yml` ...
When you run
aws-rails-provisioner commands later, it takes the configuration values of a service—under
scaling: to provision a Fargate service fronted by an Application Load Balancer (DBClusters resource and Auto Scaling policies are optional for a service).
db_cluster portion of
aws-rails-provisioner.yml defines database settings for your Rails application. It currently supports Aurora PostgreSQL, Aurora MySQL, and Aurora. You can specify the engine version by appending
engine_version to the command. You can also choose to provide a user name for your databases; if not,
aws-rails-provisioner automatically generates username and password and stores it in AWS Secrets Manager.
To enable storage encryption for the Amazon RDS database cluster, provide
kms_key_arn with the AWS KMS key ARN you use for storage encryption:
my_awesome_rails_app: source_path: ../path/to/awesome_app db_cluster: engine: aurora-postgresql db_name: awesome_db username: myadmin
You can review the full list of db_cluster: configuration options to meet your specific needs.
fargate: portion of
aws-rails-provisioner.yml defines which Fargate services and Tasks that running your application image, for example:
my_awesome_rails_app: source_path: ../path/to/awesome_app fargate: public: true memory: 512 cpu: 256 container_port: 80 envs: RAILS_ENV: ... RAILSLOGTO_STDOUT: ... ...
For HTTPs applications, you can provide
certificate with a certificate ARN from AWS Certificate Manager. This automatically associates with the Application Load Balancer and sets
container_port to 443. You can also provide a domain name and domain zone for your application under
domain_zone. If you don’t provide these elements, the system provides a default DNS address from the Application Load Balancer.
When providing environment variables for your application image, you don’t have to define
DATABASE_URL by yourself;
aws-rails-provisioner computes the value based on your
db_cluster configuration. Make sure to update the
config/database.yml file for your Rails application to recognize the
DATABASE_URL environment variable.
You can review the full list of fargate: configuration options to meet your specific needs.
You can also configure the Auto Scaling setting for your service. In this prototype stage, you can configure scaling policies
my_awesome_rails_app: source_path: ../path/to/awesome_app scaling: max_capacity: 10 on_memory: target_util_percent: 80 scale_out_cool_down: 200 on_request: requests_per_target: 100000 disable_scale_in: true ...
You can review the full list of scaling: configuration options to meet your specific needs.
Step 3: Build and deploy
aws-rails-provisioner.yml defined, you can run a build command. Doing so bootstraps AWS CDK stacks in code, defining all the necessary AWS resources and connections for you.
Run the following:
This command initializes and builds a CDK project with stacks—installing all required CDK packages—leaving a deploy-ready project. By default, it generates an
InitStack that defines the VPC and Amazon ECS cluster, hosting Fargate services. It also generates a
FargateStack that defines a database cluster and a load-balanced, scaling Fargate service for each service entry.
When you enable
aws-rails-provisioner also provides a pipeline stack containing source, build, database migration, and deploy stages for each service defined for you. You can enable CI/CD with the following command:
aws-rails-provisioner build --with-cicd
After the build completes, run the following deploy command to deploy all defined AWS resources:
Instead of deploying everything all at the same time, you can deploy stack by stack or application by application:
# only deploys the stack that creates the VPC and ECS cluster aws-rails-provisioner deploy --init # deploys the fargate service and database cluster when defined aws-rails-provisioner deploy --fargate # deploy the CI/CD stack aws-rails-provisioner deploy --cicd # deploy only `my_awesome_rails_app` application aws-rails-provisioner deploy --fargate --service my_awesome_rails_app
You can check on the status of your stacks by logging in to the AWS console and navigating to AWS CloudFormation. Deployment can take several minutes.
Completing deployment leaves your applications running on AWS Fargate, fronted with the Application Load Balancer.
Step 4: View AWS resources
To see your database cluster, log in to the Amazon RDS console.
To see an ECS cluster created, with Fargate Services and tasks running, you can also check the Amazon ECS console.
To view the application via DNS address or domain address, check the Application Load Balancing dashboard.
Any applications with databases need rails migration to work. The generated CI/CD stack contains a migration phase. The following CI/CD section contains additional details.
To view all the aws-rails-provisioner command line options, run:
Step 5: Trigger the CI/CD pipeline
To trigger the pipeline that
aws-rails-provisioner provisioned for you, you must commit your application source code and Dockerfile with AWS CodeBuild build specs into an AWS CodeCommit repository. The
aws-rails-provisioner gem automatically creates this repository for you.
To experiment with application image build and database migration on your own, try these example build spec files from the aws-rails-provisioner GitHub repo.
aws-rails-provisioner for RubyGems is currently under developer preview, it provides you with a powerful, time-saving tool. I would love for you to try it out and return with feedback for how AWS can improve this asset before its final launch. As always, you can leave your thoughts and feedback on GitHub.