{
  "AWSTemplateFormatVersion" : "2010-09-09",

  "Description" : "AWS CloudFormation Sample Template Redmine_Single_instance: Redmine is a  flexible project management web application which includes a gantt chart, calendar, wiki, forums, multiple roles, and email notification. This template installs a Redmine stack using a single EC2 instance with a local MySQL database for storage. It demonstrates using the AWS CloudFormation bootstrap scripts to install the packages and files necessary to deploy the Redmine, Rails, MySQL and all dependent packages at instance launch time. **WARNING** This template creates an Amazon EC2 instance. You will be billed for the AWS resources used if you create a stack from this template.",

  "Parameters" : {

    "KeyName": {
      "Description" : "Name of an existing EC2 KeyPair to enable SSH access to the instances",
      "Type": "String",
      "MinLength": "1",
      "MaxLength": "255",
      "AllowedPattern" : "[\\x20-\\x7E]*",
      "ConstraintDescription" : "can contain only ASCII characters."
    },

    "DBName": {
      "Default": "redmine",
      "Description" : "MySQL database name",
      "Type": "String",
      "MinLength": "1",
      "MaxLength": "64",
      "AllowedPattern" : "[a-zA-Z][a-zA-Z0-9]*",
      "ConstraintDescription" : "must begin with a letter and contain only alphanumeric characters."
    },

    "DBUsername": {
      "NoEcho": "true",
      "Description" : "Username for MySQL database access",
      "Type": "String",
      "MinLength": "1",
      "MaxLength": "16",
      "AllowedPattern" : "[a-zA-Z][a-zA-Z0-9]*",
      "ConstraintDescription" : "must begin with a letter and contain only alphanumeric characters."
    },

    "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" : "m1.small",
      "AllowedValues" : [ "t1.micro","m1.small","m1.medium","m1.large","m1.xlarge","m2.xlarge","m2.2xlarge","m2.4xlarge","m3.xlarge","m3.2xlarge","c1.medium","c1.xlarge","cc1.4xlarge","cc2.8xlarge","cg1.4xlarge"],
      "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" : {
      "t1.micro"    : { "Arch" : "64" },
      "m1.small"    : { "Arch" : "64" },
      "m1.medium"   : { "Arch" : "64" },
      "m1.large"    : { "Arch" : "64" },
      "m1.xlarge"   : { "Arch" : "64" },
      "m2.xlarge"   : { "Arch" : "64" },
      "m2.2xlarge"  : { "Arch" : "64" },
      "m2.4xlarge"  : { "Arch" : "64" },
      "m3.xlarge"   : { "Arch" : "64" },
      "m3.2xlarge"  : { "Arch" : "64" },
      "c1.medium"   : { "Arch" : "64" },
      "c1.xlarge"   : { "Arch" : "64" },
      "cc1.4xlarge" : { "Arch" : "64HVM" },
      "cc2.8xlarge" : { "Arch" : "64HVM" },
      "cg1.4xlarge" : { "Arch" : "64HVM" }
    },

    "AWSRegionArch2AMI" : {
      "us-east-1"      : { "32" : "ami-31814f58", "64" : "ami-1b814f72", "64HVM" : "ami-0da96764" },
      "us-west-2"      : { "32" : "ami-38fe7308", "64" : "ami-30fe7300", "64HVM" : "NOT_YET_SUPPORTED" },
      "us-west-1"      : { "32" : "ami-11d68a54", "64" : "ami-1bd68a5e", "64HVM" : "NOT_YET_SUPPORTED" },
      "eu-west-1"      : { "32" : "ami-973b06e3", "64" : "ami-953b06e1", "64HVM" : "NOT_YET_SUPPORTED" },
      "ap-southeast-1" : { "32" : "ami-b4b0cae6", "64" : "ami-beb0caec", "64HVM" : "NOT_YET_SUPPORTED" },
      "ap-southeast-2" : { "32" : "ami-b3990e89", "64" : "ami-bd990e87", "64HVM" : "NOT_YET_SUPPORTED" },
      "ap-northeast-1" : { "32" : "ami-0644f007", "64" : "ami-0a44f00b", "64HVM" : "NOT_YET_SUPPORTED" },
      "sa-east-1"      : { "32" : "ami-3e3be423", "64" : "ami-3c3be421", "64HVM" : "NOT_YET_SUPPORTED" }
    }
  },

  "Resources" : {

    "WebServer": {
      "Type": "AWS::EC2::Instance",
      "Metadata" : {
        "AWS::CloudFormation::Init" : {

          "configSets" : {
            "fullinstall" : [ "install_packages", "setup_database" ]
          },

          "install_packages" : {
            "packages" : {
              "yum" : {
                "git"               : [],
                "gcc-c++"           : [],
                "make"              : [],
                "ruby-devel"        : [],
                "ruby18-rdoc"       : [],
                "rubygems"          : [],
                "mysql"             : [],
                "mysql-server"      : [],
                "mysql-devel"       : [],
                "libjpeg-turbo-devel" : [],
                "libpng-devel"      : [],
                "libtiff-devel"     : [],
                "freetype-devel"    : [],
                "ghostscript-devel" : [],
                "ImageMagick-devel" : []
              },

              "rubygems" : {
                "bundle"            : []
              }
            },

            "sources" : {
              "/home/ec2-user/redmine"     : "http://rubyforge.org/frs/download.php/77242/redmine-2.4.0.tar.gz"
            },

            "files" : {

              "/home/ec2-user/run_redmine" : {
                "content" : { "Fn::Join" : ["", [
                  "#!/bin/bash -v\n",
                  "#Install and run Redmine\n",
                  "cd /home/ec2-user/redmine/redmine-2.4.0\n",
                  "bundle install --without development test postgresql sqlite\n",
                  "rake generate_secret_token\n",
                  "RAILS_ENV=production rake db:migrate\n",
                  "RAILS_ENV=production rake redmine:load_default_data << EOF\n",
                  "en\n",
                  "EOF\n",
                  "ruby script/rails server webrick -e production --port=80 &\n"
                  ]]},
                "mode"  : "000755",
                "owner" : "root",
                "group" : "root"
              },

              "/home/ec2-user/redmine/redmine-2.4.0/config/database.yml" : {
                "content" : { "Fn::Join" : ["", [
                  "production:\n",
                  "  adapter: mysql\n",
                  "  database: ", { "Ref" : "DBName" }, "\n",
                  "  host: localhost\n",
                  "  username: ", { "Ref" : "DBUsername" }, "\n",
                  "  password: ", { "Ref" : "DBPassword" }, "\n",
                  "  timeout: 5000\n"
                  ]]},
                "mode"  : "000644",
                "owner" : "root",
                "group" : "root"
              }
            },

            "services" : {
              "sysvinit" : {
                "mysqld" : {
                  "enabled"       : "true",
                  "ensureRunning" : "true"
                }
              }
            }
          },
          "setup_database" : {

            "files" : {
              "/tmp/setup.mysql" : {
                "content" : { "Fn::Join" : ["", [
                  "CREATE DATABASE ", { "Ref" : "DBName" }, " character set utf8;\n",
                  "GRANT ALL ON ", { "Ref" : "DBName" }, ".* TO '", { "Ref" : "DBUsername" }, "'@'localhost' IDENTIFIED BY '", { "Ref" : "DBPassword"} , "';\n"
                  ]]},
                "mode"  : "000600",
                "owner" : "root",
                "group" : "root"
              },

              "/tmp/setup_database" : {
                "content" : { "Fn::Join" : ["", [
                  "#!/bin/bash -v\n",
                  "# Setup MySQL root password and create a user\n",
                  "mysqladmin -u root password '", { "Ref" : "DBRootPassword" }, "'\n",
                  "mysql -u root --password='", { "Ref" : "DBRootPassword" }, "' < /tmp/setup.mysql\n"
                  ]]},
                "mode"  : "000700",
                "owner" : "root",
                "group" : "root"
              }
            },

            "commands" : {
              "01_setup_database" : {
                "command" : "/tmp/setup_database"
              }
            }
          }
        }
      },
      "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 -v\n",
          "yum update -y aws-cfn-bootstrap\n",

          "# Helper function\n",
          "function error_exit\n",
          "{\n",
          "  /opt/aws/bin/cfn-signal -e 1 -r \"$1\" '", { "Ref" : "WaitHandle" }, "'\n",
          "  exit 1\n",
          "}\n",

          "# Install packages\n",
          "/opt/aws/bin/cfn-init -s ", { "Ref" : "AWS::StackId" }, " -r WebServer ",
          "    --region ", { "Ref" : "AWS::Region" },
          "    --configset fullinstall || error_exit 'Failed to run cfn-init'\n",

          "# Startup Redmine\n",
          "/home/ec2-user/run_redmine\n",

          "# All is well so signal success\n",
          "/opt/aws/bin/cfn-signal -e 0 -r \"Redmine setup complete\" '", { "Ref" : "WaitHandle" }, "'\n"
        ]]}}
      }
    },

    "WaitHandle" : {
      "Type" : "AWS::CloudFormation::WaitConditionHandle"
    },

    "WaitCondition" : {
      "Type" : "AWS::CloudFormation::WaitCondition",
      "DependsOn" : "WebServer",
      "Properties" : {
        "Handle" : {"Ref" : "WaitHandle"},
        "Timeout" : "900"
      }
    },

    "WebServerSecurityGroup" : {
      "Type" : "AWS::EC2::SecurityGroup",
      "Properties" : {
        "GroupDescription" : "Enable HTTP access via port 80, the indexer port plus 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" ]}]]},
      "Description" : "URL for Redmine"
    }
  }
}

