npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

cloudpirate

v2.0.6

Published

Deployment tool for aws ec2 instances

Downloads

41

Readme

CloudPirate

CloudPirate is a set of deployment tasks based on top of flightplan allowing deployments to a dynamic set of aws ec2 instances.

Whats new?

  • 2.0.x

    • Using own bin script wrapping flightplan. See below on how to upgrade from 1.x.x.
    • The S3 bucket name can now be configured with the option bucket which will override the value within the aws configuration file.
    • A special role of single can now be used to identify the first instance without the need for defining a tag. A tag may still be defined and will take priority if exists.
    • Commands can now optionally use a space to separate task from target rather than a colon.
    • Options with local paths now expand tilde.
    • Improved handling of symlinking shared items, copy deployment contents if no current shared item exists and remove before symlink.
  • 1.5.x

    • Ability to specify aws configuration file location with the option awsConfig. This enables the ability to configure credentials in a different file location and/or use different credentials per application/environment.

Updating configuration from version 1.x to 2.x

  • Application deployment configuration now lives within the file cloudpirate.json within the current working directory. To migrate, move the configuration defined within flightplan.js (the second parameter to the CloudPirate constructor) and place it within its own json file.
  • Aws configuration, by default, has now moved to the file cloudpirate-aws.json within the current working directory. This file location can still be overriden with the option awsConfig.
  • If you were additionally configuring the flightplan instance within flightplan.js this can still be achieved within the new cloudpirate.js file, which exposes the flightplan instance, see below.

Looking for version 1.x readme?

This can be found here.

Installation

# Install the cloudpirate cli tool
$ npm install -g cloudpirate

Usage

The task and target may be separated either with a space or colon.

# View help
$ cloudpirate -h

# List the target servers for the myapp application on the prod environment
$ cloudpirate servers myapp.prod

# List the versions deployed for the myapp application across environments
$ cloudpirate version myapp

# Build myapp and place the asset in S3.
# using the branch configuration, or prompted if false
$ cloudpirate build myapp

# Build myapp and place the asset in S3 for the prod environment.
# Required, if configuration is overridden at the environment level.
$ cloudpirate build myapp.prod

# Deploy a previously built myapp version to the prod environment
# using the branch configuration, or prompted if false
$ cloudpirate deploy myapp.prod

# Run the task1 task on the scripts role of the prod environment
# for the myapp application
$ cloudpirate task1 myapp.prod.scripts

# Run the task3 task on the special single role of the prod environment
# for the myapp application.
# The single role uses the first instance and does not need a role tag.
$ cloudpirate task3 myapp.prod.single

Example cloudpirate.json

The cloudpirate.json file defines the application deployment configuration, and should exist within the current working directory. Alternatively, the location of this file can be specified with the -f cli option.

{
    "config": {
        "keep": 5,
        "sshKey": "/home/me/.ssh/key.pem"
    },
    "apps": {
        "myapp": {
            "default": {
                "awsConfig": false,
                "bucket": false,
                "envs": [ "stage", "prod" ],
                "git": "[email protected]:bedican/cloudpirate.git",
                "branch": false,
                "defaultBranch": false,
                "sshKey": "/home/me/.ssh/myapp-key.pem",
                "username": "ubuntu",
                "path": "/home/ubuntu/apps/cloudpirate",
                "shared": [ "cache", "log" ],
                "build": "echo 'GO BANANA !'",
                "buildRemote": "echo 'IM A UNITARD'",
                "postSymlink": "echo 'I BENT MY WOOKIE'",
                "roles": {
                    "single": {
                        "task3": "echo 'WHY DO PEOPLE RUN FROM ME?'"
                    },
                    "scripts": {
                        "task1": "echo 'ME FAIL ENGLISH? THAT UMPOSSIBLE'",
                        "task2": "echo 'MY CATS BREATH SMELLS LIKE CAT FOOD'"
                    }
                }
            },
            "preprod": {
                "sshKey": "/home/me/.ssh/myapp-preprod-key.pem"
            }
        }
    }
}

Options

Depending on the application and environment selected, configuration is determined by merging the default and the environment configuration under the selected application, along with the common config configuration.

Environments can be defined by either creating overriding configuration options at the same level as default under the application, or if there is no specific configuration needed, added to a envs configuration option. In the example cloudpirate.json above, the myapp application has three environments: stage, prod and preprod, where the preprod environment has an overridden sshKey option.

| Option | Description | | ------------- | --------------------------------------------------------------------------------------------------------------------------- | | git | The git repository of the application. The assumption is made that access is already configured to clone the repository. | | sshKey | The ssh key to use when connecting to ec2 instances. | | username | The username to use when connecting to ec2 instances. | | path | The remote path the project will reside under. | | keep | How many releases to keep remotely. Set to false not to cleanup old releases. | | shared | A list of files or directories that should remain constant across releases. e.g. a cache or log directory. | | branch | The branch to build or deploy. If false, you will be prompted. | | defaultBranch | If the branch option is false, you will be prompted either using this value as a default, or master if false. | | build | The build command to run locally relative to the project root used when running the build task. | | buildRemote | The build command to run remotely relative to the project root used when running the deploy task. This is executed before creating the current symlink. | | postSymlink | The command to run remotely relative to the project root used when running the deploy task. This is executed after creating the current symlink. | | envs | A list of environments if not defined with their own overriding configuration. | | roles | Used to define roles and tasks (commands) that can be run against them within the application. This allows targeted subset of ec2 instances using the cloudpirate.role tag. | | servers | To define a static list of servers if desired, see below. | | awsConfig | The filename of the aws configuration file, see below. Defaults to cloudpirate-aws.json within the current working directory. | | bucket | The S3 bucket name, if false or omitted, the value within cloudpirate-aws.json will be used. |

Example cloudpirate.js

The optional cloudpirate.js file provides an mechanism to access the cloudpirate and flightplan instances, and should exist within the current working directory. Alternatively, the location of this file can be specified with the -e cli option.

module.exports = function(cloudpirate, config) {
    var flightplan = cloudpirate.getPlan();
    // ...
};

Roles

Roles specify the purpose of an instance, and enable a subset of instances within an application for an environment to be defined using the optional cloudpirate.role tag.

Roles are defined using the roles configuration option, with a mapping of role and the tasks that can be invoked.

If using auto scaling groups, in order to tag ec2 instances differently, multiple auto scaling groups are required, each with a different cloudpirate.role tag value.

The single role

The single role is a special role that does not require a tag on any instances. Instead, a single instance will be selected to run the task against.

For example, in the case where a database migration script is required to be run.

It is still possible to define a single tag on one or more instances, which will take priority if defined.

Remote application layout

Based from the path configuration, each application will be laid out with the following.

| Path | Type | Description | | ---------- | --------- | ------------------------------------------------------------------------------------------------------ | | ./releases | Directory | Contains the deployed code, each release within its own subdirectory. | | ./shared | Directory | Each subdirectory is defined within the shared configuration and is symlinked out from each release. | | ./current | Symlink | The currently deployed release within the ./releases directory. | | ./previous | Symlink | The previously deployed release within the ./releases directory. |

Aws

Tagging

In order to use CloudPirate, ec2 instances need to be tagged with the following tags. These can be added within the aws console for each instance manually, within an auto scaling group, or defined within a cloud formation template. Tags can consist of multiple values as a comma separated list.

| Tag Name | Description | Required | | ---------------- | --------------------------------------------- | -------- | | cloudpirate.env | The environnent the instance resides in. | Yes | | cloudpirate.app | The application being deployed. | Yes | | cloudpirate.role | The role of the instance for the application. | No |

Configuration

Aws configuration, by default, resides within the file cloudpirate-aws.json in the current working directory. The location of this file can be overridden globally, per-application or per-environment by making use of the awsConfig option.

The IAM user should have privileges to upload and download to the specified bucket and be able to list ec2 instances.

{
    "aws": {
        "accessKeyId":"<access key>",
        "secretAccessKey":"<secret access key>",
        "region":"<region>"
    },
    "s3": {
        "bucket": "<bucket>"
    }
}

The aws credentials may be omitted from this file, in favour of the environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY. This will, however, remove the ability to set credentials on a per-application basis with the option awsConfig.

Usage with Launch Configuration

New ec2 instances can download the current deployed release as they are created, by making use of the UserData parameter within the Launch Configuration.

The following example demonstrates how a release is taken from S3, making use of the awscli tool.

#!/bin/bash -ex

BUCKET=mybucket
APPSDIR=/home/ubuntu/apps

function deploy {

    mkdir -p $APPSDIR/$2/init-deploy

    aws s3 cp s3://$BUCKET/$1/current-version-prod $APPSDIR/$2/init-deploy/current-version-prod
    VERSION=$(cat $APPSDIR/$2/init-deploy/current-version-prod)

    aws s3 cp s3://$BUCKET/$1/$VERSION $APPSDIR/$2/init-deploy/$VERSION
    tar -xz --strip-components=1 -C $APPSDIR/$2/init-deploy -f $APPSDIR/$2/init-deploy/$VERSION

    rm $APPSDIR/$2/init-deploy/current-version-prod $APPSDIR/$2/init-deploy/$VERSION

    # App project hook, to keep init scripts within the project
    if [ -f $APPSDIR/$2/init-deploy/bin/ec2-init ]; then
        $APPSDIR/$2/init-deploy/bin/ec2-init
    fi

    ln -s $APPSDIR/$2/init-deploy $APPSDIR/$2/current
}

deploy myapp myapp.co.uk

But I don't want to use dynamic instances and just need a static list of servers!

While this tool was written with aws in mind, with a dynamic pool of instances, it is possible to use with a static list of servers.

This can be done by defining a servers configuration option.

{
    "apps": {
        "myapp": {
            "default": {
                "servers": {
                    "default": [ "hostname1", "hostname2" ],
                    "role1": [ "hostname1" ]
                }
            }
        }
    }
}

License: MIT

Author: Ash Brown