diff --git a/Gemfile b/Gemfile index b338ffd..8e38a0e 100644 --- a/Gemfile +++ b/Gemfile @@ -44,7 +44,9 @@ gem 'exception_notification-rake', '~> 0.3.0' group :development, :test do # Use sqlite3 as the database for Active Record - gem 'sqlite3' + # gem 'sqlite3' + gem 'mysql2' + # Call 'byebug' anywhere in the code to stop execution and get a debugger console gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] # Adds support for Capybara system testing and selenium driver diff --git a/Gemfile.lock b/Gemfile.lock index 0d17a68..ab60a0a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -139,6 +139,9 @@ GEM minitest (5.11.3) multi_json (1.13.1) mustermann (1.0.2) + mysql (2.9.1) + mysql (2.9.1-x86-mingw32) + mysql (2.9.1-x86-mswin32-60) nenv (0.3.0) netrc (0.11.0) nio4r (2.3.0) @@ -154,9 +157,6 @@ GEM nenv (~> 0.1) shellany (~> 0.0) orm_adapter (0.5.0) - pg (1.0.0) - pg (1.0.0-x64-mingw32) - pg (1.0.0-x86-mingw32) pry (0.11.3) coderay (~> 1.1.0) method_source (~> 0.9.0) @@ -370,7 +370,7 @@ DEPENDENCIES jbuilder (~> 2.5) listen (>= 3.0.5, < 3.2) mini_racer - pg + mysql puma (~> 3.11) rack-timeout rails (~> 5.1.6) diff --git a/Matreon.template b/Matreon.template new file mode 100644 index 0000000..5cb4ded --- /dev/null +++ b/Matreon.template @@ -0,0 +1,327 @@ +production{ + "AWSTemplateFormatVersion" : "2010-09-09", + + "Description" : "Creates a single EC2 instance with a pruned Bitcoin Core node, C-Lightning, Lightning Charge, MySQL, Ruby on Rails and Matreon.", + + "Parameters" : { + + "KeyName": { + "Description" : "Name of an existing EC2 KeyPair to enable SSH access to the instances", + "Type": "AWS::EC2::KeyPair::KeyName", + "ConstraintDescription" : "must be the name of an existing EC2 KeyPair." + }, + + "DBPassword": { + "NoEcho": "true", + "Description" : "Password MySQL database access", + "Type": "String", + "MinLength": "1", + "MaxLength": "41", + "AllowedPattern" : "[a-zA-Z0-9]*", + "ConstraintDescription" : "must contain only alphanumeric characters." + }, + + "DBRootPassword": { + "NoEcho": "true", + "Description" : "Root password for MySQL", + "Type": "String", + "MinLength": "1", + "MaxLength": "41", + "AllowedPattern" : "[a-zA-Z0-9]*", + "ConstraintDescription" : "must contain only alphanumeric characters." + }, + + "InstanceType" : { + "Description" : "WebServer EC2 instance type", + "Type" : "String", + "Default" : "t2.small", + "AllowedValues" : [ "t2.micro", "t2.small", "t2.medium"], + "ConstraintDescription" : "must be a valid EC2 instance type." + }, + + "SSHLocation" : { + "Description" : "The IP address range that can be used to SSH to the EC2 instances", + "Type": "String", + "MinLength": "9", + "MaxLength": "18", + "Default": "0.0.0.0/0", + "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})", + "ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x." + } + }, + + "Mappings" : { + "AWSInstanceType2Arch" : { + "t2.micro" : { "Arch" : "HVM64" }, + "t2.small" : { "Arch" : "HVM64" }, + "t2.medium" : { "Arch" : "HVM64" } + }, + + "AWSInstanceType2NATArch" : { + "t2.micro" : { "Arch" : "NATHVM64" }, + "t2.small" : { "Arch" : "NATHVM64" }, + "t2.medium" : { "Arch" : "NATHVM64" } + + }, + + "AWSRegionArch2AMI" : { + "eu-central-1" : {"HVM64" : "ami-5652ce39"} + } + + }, + + "Resources" : { + + "WebServer": { + "Type": "AWS::EC2::Instance", + "Metadata" : { + "AWS::CloudFormation::Init" : { + "configSets" : { + "full_install" : [ "install_cfn", "install_ruby_2_5_1", "install_mysql", "configure_mysql", "install_application" ] + }, + + "install_cfn" : { + "files" : { + "/etc/cfn/cfn-hup.conf" : { + "content" : { "Fn::Join" : ["", [ + "[main]\n", + "stack=", { "Ref" : "AWS::StackId" }, "\n", + "region=", { "Ref" : "AWS::Region" }, "\n" + ]]}, + "mode" : "000400", + "owner" : "root", + "group" : "root" + }, + + "/etc/cfn/hooks.d/cfn-auto-reloader.conf" : { + "content": { "Fn::Join" : ["", [ + "[cfn-auto-reloader-hook]\n", + "triggers=post.update\n", + "path=Resources.WebServer.Metadata.AWS::CloudFormation::Init\n", + "action=/opt/aws/bin/cfn-init -v ", + " --stack ", { "Ref" : "AWS::StackName" }, + " --resource WebServer ", + " --configsets full_install ", + " --region ", { "Ref" : "AWS::Region" }, "\n", + "runas=root\n" + ]]}, + "mode" : "000400", + "owner" : "root", + "group" : "root" + } + }, + + "services" : { + "sysvinit" : { + "cfn-hup" : { "enabled" : "true", "ensureRunning" : "true", + "files" : ["/etc/cfn/cfn-hup.conf", "/etc/cfn/hooks.d/cfn-auto-reloader.conf"]} + } + } + }, + + "install_ruby_2_5_1": { + "files": { + "/tmp/install_ruby": { + "content": { + "Fn::Join": [ + "\n", + [ + "#!/bin/bash", + "curl -sSL https://get.rvm.io | bash", + "source /etc/profile.d/rvm.sh", + "rvm install 2.5.1", + "rvm --default use 2.5.1", + "gem install rails" + ] + ] + }, + "mode": "000500", + "owner": "root", + "group": "root" + } + }, + "commands": { + "01_install_ruby": { + "command": "/tmp/install_ruby > /var/log/install_ruby.log" + } + } + }, + + "install_mysql" : { + "packages" : { + "yum" : { + "mysql" : [], + "mysql-server" : [], + "mysql-devel" : [], + "mysql-libs" : [] + } + }, + + "files" : { + "/tmp/setup.mysql" : { + "content" : { "Fn::Join" : ["", [ + "CREATE USER 'matreon'@'localhost' IDENTIFIED BY '", { "Ref" : "DBPassword" }, "';\n", + "GRANT ALL ON matreon.* TO 'matreon'@'localhost';\n", + "FLUSH PRIVILEGES;\n" + ]]}, + "mode" : "000400", + "owner" : "root", + "group" : "root" + } + }, + + "services" : { + "sysvinit" : { + "mysqld" : { "enabled" : "true", "ensureRunning" : "true" } + } + } + }, + + "configure_mysql" : { + "commands" : { + "01_set_mysql_root_password" : { + "command" : { "Fn::Join" : ["", ["mysqladmin -u root password '", { "Ref" : "DBRootPassword" }, "'"]]}, + "test" : { "Fn::Join" : ["", ["$(mysql matreon -u root --password='", { "Ref" : "DBRootPassword" }, "' >/dev/null 2>&1 /dev/null 2>&1 /dev/null ; then pkill -TERM ruby ; fi\n", + + "git clone https://github.com/Sjors/matreon.git\n", + "cd matreon\n", + "git checkout 2018/05/aws_cloudformation\n", + "bundle install --without development:test\n", + + "# Configure the database connection\n", + "mv /tmp/database.yml config\n", + "rake db:create db:migrate # RAILS_ENV=production\n" + ]]}, + "mode" : "000500", + "owner" : "root", + "group" : "root" + }, + "/home/ec2-user/start-application" : { + "content" : { "Fn::Join" : ["", [ + "#!/bin/bash -e\n", + "source /etc/profile.d/rvm.sh\n", + "rvm use 2.5.1\n", + "export HOME=/home/ec2-user\n", + "export PATH=$PATH:/usr/local/bin\n", + "cd /home/ec2-user/matreon\n", + + "# Startup the application\n", + "rails server --binding 0.0.0.0 -p 80 -d # RAILS_ENV=production\n" + ]]}, + "mode" : "000500", + "owner" : "root", + "group" : "root" + } + }, + "commands" : { + "01_install_application" : { + "command" : "/tmp/install_application > /var/log/install_application.log" + }, + "02_configure_reboot" : { + "command" : "echo /home/ec2-user/start-application >> /etc/rc.local" + }, + "03_start_application" : { + "command" : "/home/ec2-user/start-application" + }, + "04_cleanup" : { + "command" : "rm /tmp/install_application" + } + } + } + } + }, + "Properties": { + "ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" }, + { "Fn::FindInMap" : [ "AWSInstanceType2Arch", { "Ref" : "InstanceType" }, "Arch" ] } ] }, + "InstanceType" : { "Ref" : "InstanceType" }, + "SecurityGroups" : [ {"Ref" : "WebServerSecurityGroup"} ], + "KeyName" : { "Ref" : "KeyName" }, + "UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [ + "#!/bin/bash -xe\n", + "yum update -y aws-cfn-bootstrap\n", + + "/opt/aws/bin/cfn-init -v ", + " --stack ", { "Ref" : "AWS::StackId" }, + " --resource WebServer ", + " --configsets full_install ", + " --region ", { "Ref" : "AWS::Region" }, "\n", + + "/opt/aws/bin/cfn-signal -e $? ", + " --stack ", { "Ref" : "AWS::StackId" }, + " --resource WebServer ", + " --region ", { "Ref" : "AWS::Region" }, "\n" + ]]}} + }, + "CreationPolicy" : { + "ResourceSignal" : { + "Timeout" : "PT30M" + } + } + }, + + "WebServerSecurityGroup" : { + "Type" : "AWS::EC2::SecurityGroup", + "Properties" : { + "GroupDescription" : "Enable HTTP and SSH access", + "SecurityGroupIngress" : [ + {"IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "CidrIp" : "0.0.0.0/0"}, + {"IpProtocol" : "tcp", "FromPort" : "22", "ToPort" : "22", "CidrIp" : { "Ref" : "SSHLocation"}} + ] + } + } + }, + + "Outputs" : { + "WebsiteURL" : { + "Value" : { "Fn::Join" : ["", ["http://", { "Fn::GetAtt" : [ "WebServer", "PublicDnsName" ]}, "/notes" ]] }, + "Description" : "URL for newly created Rails application" + } + } +}