Design philosophy 💡

Why another Netflix Janitor Monkey? 🙈

Janitor Monkey was a strong inspiration for Cecil, but it didn’t fully meet the requirements of the particular use case being targeted at Couchbase couchbase.

About the name: Cecil is a Custodian for your CLoud, which can be shorted to CCL, which can be pronounced as "Cecil".

Developer sandbox focus

Cecil is geared to monitor AWS accounts that are primarily used for development and testing purposes, where EC2 instances are typically ephemeral. Some typical use cases:

  1. Pre-release stress testing, where several test engineers might be running their own stress tests on their own set of EC2 instances.

  2. Reproducing a production bug that requires several EC2 instances to simulate the production environment

  3. Running a (very costly) cluster of GPU-enabled EC2 instances for training a model using a deep learning framework, that may take a few days to train

In all of these cases, it’s very easy for a developer to start on this task and then get pulled off on another higher priority task, and then forget all about the AWS resources for weeks or months. Making developers go through IT red tape or assigning IT resources to manually track down unused resources both have their issues of getting in the way and making it way too easy for things to fall through the cracks.

EC2 Instance focus

Cecil is 100% focused on EC2 instances for now. Maybe in the future it will be extended to cover more types of AWS resources.

If you need to track other resource types, check out Capital One Cloud Custodian, which can track many types of AWS resources beyond EC2 instances. The two tools will happily co-exist.

Minimal IAM Role Permissions

One of the design constraints however, is to keep the amount of permissions needed by the Cecil process as minimal as possible. This minimizes the risk for target AWS accounts being monitored by Cecil.

Because of these limited permissions, Cecil has custom behavior when it comes to terminating EC2 instances that are part of a Cloudformation Template or an AutoScalingGroup. See the Cloudformation fleets and AutoScalingGroups section for more info.

Every new EC2 instance is assigned to an owner

Whenever Cecil detects new instances on the Cloudwatch Event stream, it always assigns a lease to someone, and it if cannot determine who it should assign the lease to, it falls back to the administrator email address.

Initially if Cecil isn’t fully configured with the mapping between AWS key pairs and email address, then everything will still work, but the administrator will be getting more emails than they’d probably like — which will hopefully incentivize them to add the AWS key pair mappings so the whole system can be more self-serve.

How it works âš™

One-time setup

  1. Run the Cecil process somewhere (just a single binary, uses embedded sqlite db by default).

  2. Configure Cecil to monitor Cloudwatch Event streams of one or more AWS accounts by deploying a Cloudformation template.

Each EC2 instance launch

  1. Every time a new EC2 instance is launched in that AWS account, it will be detected on the CloudWatch Event stream and a lease will be created and assigned to the person who launched it, or the admin user if the owner can’t be identified.

    1. Users can add a CecilOwner tag that contains their email address when they launch instances, which means they will be assigned the lease.

    2. The admin can also do a one-time configuration via the REST API to add mappings between AWS Key Pairs and Email addresses

  2. When the lease is about to expire, the owner is notified by email twice and given a chance to extend the lease by clicking a link.

  3. If the lease isn’t extended and eventually expires, then the instance associated with the lease will get terminated.

Interaction Diagram

This shows the interaction between all the moving parts during an instance launch:

Interaction Diagram

Cecil for Administrators 🤕

Install/monitor single AWS account

If you run Cecil in a single AWS account, you will end up with something like this:

Cecil Architecture Single AWS Account
Note
Cecil is shown in the diagram (far right box) as running in an EC2 instance, which is a perfectly valid place to run it. However, it does not need to be run in an EC2 instance, and can be run on Docker Cloud or in a Virtual Machine in your private DataCenter.

Cecil can also be run in one one account while monitoring one or more other AWS accounts, which is described in the Monitor additional AWS accounts section.

This section will walk you through the first approach, where Cecil will monitor the resources in the same AWS account it’s running under.

For the purposes of referring to this account later in the doc, let’s assume the AWS account ID is 78861235

Deploy root cloudformation template

Cecil needs to create a few resources in AWS:

  1. An SQS queue where it can receive new CloudWatch Events

  2. An IAM user "cecilrootuser" that the server process will use, which has limited permissions

These resources are wrapped up in a Cloudformation template. To launch the template in us-east-1, click the button below:

cloudformation launch stack

This will launch in the us-east-1 region. If you need to launch in a different region, you will need to view the HTML and customize the URL accordingly.

Alternative launch method: aws cli

Instead of using the AWS web console via the link above, you can also launch the cloudformation template via the CLI aws tool:

aws cloudformation create-stack --stack-name "CecilRootStack" \
--template-body "http://cecil-assets.s3.amazonaws.com/cloudformation/cecil-root.template" \
--capabilities CAPABILITY_IAM CAPABILITY_NAMED_IAM \
--region us-east-1

Create Access Key for CecilRootUser

Now that the root cloudformation template is installed, you will need to create an AWS access key for the newly created CecilRootUser IAM user. This can be done via the AWS web console, or the aws CLI.

aws iam create-access-key --user-name CecilRootUser

This will return something like:

{
    "AccessKey": {
        "SecretAccessKey": "je7MtGbClwBF/2Zp9Utk/h3yCo8nvbEXAMPLEKEY",
        "Status": "Active",
        "CreateDate": "2013-01-02T22:44:12.897Z",
        "UserName": "CecilRootUser",
        "AccessKeyId": "AKIAIEXAMPLERQ4U4N67LE7A"
    }
}

Write these down as you will need them later.

Start Cecil process

Run Cecil locally

Download the OSX release binary and unzip it.

Set the following environment variables that correspond to the AccessKeyId and SecretAccessKey returned above, and replace YOUR_AWS_ACCOUNT_ID with your actual AWS account id, which is numeric and might look something like 78861235:

$ export AWS_ACCESS_KEY_ID=AKIAIEXAMPLERQ4U4N67LE7A \
AWS_SECRET_ACCESS_KEY=***** \
AWS_REGION=us-east-1 \
AWS_ACCOUNT_ID=YOUR_AWS_ACCOUNT_ID

Launch the process:

$ cecil

There are other optional configuration options you can use to customize the Cecil behavior, see the Configuration Reference section.

Run Cecil on Docker Cloud

You can also run Cecil in Docker Cloud using this predefined stack:

deploy to dockercloud

You will need to customize the environment variables AWS_ACCESS_KEY_ID, etc, as mentioned above.

Note
you will need to setup volume mounts if you want to preserve the database across container restarts. See Deploying to Docker Cloud
Note
See the Configuration Reference for documentation of the environment variables.

Create account and admin user via rest api

Cecil is designed to be multi-tenant. In Cecil terminology, a tenant is called an account, but you might also see references to tenant, which is a synonym for account. Each Cecil account can have multiple AWS accounts under it.

In this step you’ll be setting up a single Cecil account which is configured to monitor a single AWS account, the same AWS account where Cecil is running.

Cecil does not have a Web UI, and so all interaction is over the REST API.

curl -X POST http://localhost:8080/accounts \
-H "Cache-Control: no-cache" \
-H "Content-Type: application/json" \
-d @- << EOF
{
    "email":"you@yourcompany.co",
    "name":"YourName",
    "surname":"AndLastName"
}
EOF
Note
there is also a postman file that can be imported rather than using curl. See the Postman Collection instructions.

Response:

{
  "email": "you@yourcompany.co",
  "account_id": 1,
  "response": "An email has been sent to the specified address with a verification token and instructions.",
  "verified": false
}

you should receive an email with a vefication code (aka verification token). Unless you customized the cecil.yml with custom Mailgun credentials, it might several minutes (15?) to receive the email from their sandbox server. But if you look in the Cecil process logs, you can look for a line with a verification_token and skip waiting for the email.

Verify account admin user and get API token

Replace the sample verification token (0d78a4e0) with your actual verification then run the following curl request:

curl -X POST http://localhost:8080/accounts/1/api_token \
-H "Cache-Control: no-cache" \
-H "Content-Type: application/json" \
-d @- << EOF
{
    "verification_token":"0d78a4e0"
}
EOF

Response:

{
  "account_id": 1,
  "api_token": "Bearer eyJhbGc",
  "email": "you@yourcompany.co",
  "verified": true
}
Note
the api_token will be much longer than this, but has been shortened to make this document more readable

Use the api token to manage your account by including it in the Authorization header on all requests. To make that easier, set a bash variable that will be referenced in subsequent curl requests.

AUTH_TOKEN="Bearer eyJhbGc"

Configure Cecil account with AWS account ID

Make the following REST api call, using the api_token from the previous step:

curl -X POST http://localhost:8080/accounts/1/cloudaccounts \
-H "Authorization: $AUTH_TOKEN" \
-H "Cache-Control: no-cache" \
-H "Content-Type: application/json" \
-d @- << EOF
{
    "aws_id":"78861235"
}
EOF

Response:

{
  "aws_id": "78861235",
  "cloudaccount_id": 1,
  "initial_setup_cloudformation_url": "/accounts/1/cloudaccounts/1/tenant-aws-initial-setup.template",
  "region_setup_cloudformation_url": "/accounts/1/cloudaccounts/1/tenant-aws-region-setup.template"
}

Deploy per-AWS-account cloudformation

For each AWS account you add to a Cecil account, you will need to add the tenant-aws-initial-setup.template Cloudformation template, which sets up a special IAM role and policy for Cecil.

First download it:

curl -X GET \
-H "Authorization: $AUTH_TOKEN" \
-H "Cache-Control: no-cache" \
"http://localhost:8080/accounts/1/cloudaccounts/1/tenant-aws-initial-setup.template" > tenant-aws-initial-setup.template

Then `install it:

$ aws cloudformation create-stack --stack-name "CecilTenantStack" \
  --template-body "file://tenant-aws-initial-setup.template" \
  --region us-east-1 \
  --capabilities CAPABILITY_IAM CAPABILITY_NAMED_IAM

Or alternatively you can upload this in the Cloudformation section of the AWS web UI.

Deploy per-AWS-region cloudformation

For a given AWS account you are monitoring, you’ll need to setup AWS CloudWatch Event rules and AWS SNS (Simple Notification Service) forwarders in each AWS region you want to monitor. That is done via the tenant-aws-region-setup.template Cloudformation template.

curl -X GET \
-H "Authorization: $AUTH_TOKEN" \
-H "Cache-Control: no-cache" \
"http://localhost:8080/accounts/1/cloudaccounts/1/tenant-aws-region-setup.template" > tenant-aws-region-setup.template

Then install it:

$ aws cloudformation create-stack --stack-name "CecilTenantRegionStack" \
  --template-body "file://tenant-aws-region-setup.template" \
  --region us-east-1

To monitor more regions, simply repeat this step with a different --region parameter. There is a helper script for this in scripts/deploy/deploy_region_setup_all_regions.sh.

Launch EC2 instance and verify behavior

Launch a new EC2 instance

$ aws ec2 run-instances --image-id ami-c58c1dd3 --count 1 --instance-type t2.micro --key-name MyKeyPair

Expected behavior

  1. You should receive an email notification from Cecil with links to approve or terminate the instance.

  2. If you wait a few days, you should get an email notification warning you the lease will expire, which will include a link to extend the lease.

  3. If you do not extend the lease, Cecil should terminate the instance and send an email notification.

Monitor additional AWS accounts

If you want to monitor additional AWS accounts, you will need to repeat a few of the above steps using a different AWS account ID and credentials. The rest of this section assumes you want to monitor AWS account ID 19382281 and have created AWS_ACCESS_KEY_ID=AKIAJEF and AWS_SECRET_ACCESS_KEY=6KLcaqGeH that have admin privilages in the 2nd AWS account.

At the end of these steps, you’ll end up with something that looks like this:

Cecil Architecture Multiple AWS Accounts
Note
Cecil will be monitoring EC2 instance events in both its own AWS account (78861235), and the 2nd AWS account (19382281).

Configure Cecil account with 2nd AWS account ID

Make the following REST api call, using the api_token from the previous step:

curl -X POST \
-H "Authorization: $AUTH_TOKEN" \
-H "Cache-Control: no-cache" \
-H "Content-Type: application/json" \
-d '{ \
	"aws_id":"19382281" \
}' \
"http://localhost:8080/accounts/1/cloudaccounts"

Response:

{
  "aws_id": "19382281",
  "cloudaccount_id": 2,
  "initial_setup_cloudformation_url": "/accounts/1/cloudaccounts/2/tenant-aws-initial-setup.template",
  "region_setup_cloudformation_url": "/accounts/1/cloudaccounts/2/tenant-aws-region-setup.template"
}

Deploy 2nd per-AWS-account cloudformation

Downlaod tenant-aws-initial-setup.template:

curl -X GET \
-H "Authorization: $AUTH_TOKEN" \
-H "Cache-Control: no-cache" \
"http://localhost:8080/accounts/1/cloudaccounts/2/tenant-aws-initial-setup.template" > tenant-aws-initial-setup.template

Then install it using an AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY with admin privilages in the 2nd AWS account:

$ AWS_ACCESS_KEY_ID=AKIAJEF AWS_SECRET_ACCESS_KEY=6KLcaqGeH aws cloudformation create-stack --stack-name "CecilTenantStack" \
  --template-body "file://tenant-aws-initial-setup.template" \
  --region us-east-1 \
  --capabilities CAPABILITY_IAM CAPABILITY_NAMED_IAM

Or alternatively you can upload this in the Cloudformation section of the AWS web UI.

Deploy 2nd per-AWS-region cloudformation

Download tenant-aws-region-setup.template:

curl -X GET \
-H "Authorization: $AUTH_TOKEN" \
-H "Cache-Control: no-cache" \
"http://localhost:8080/accounts/1/cloudaccounts/2/tenant-aws-region-setup.template" > tenant-aws-region-setup.template

Then install it using an AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY with admin privilages in the 2nd AWS account:

$ AWS_ACCESS_KEY_ID=AKIAJEF AWS_SECRET_ACCESS_KEY=6KLcaqGeH aws cloudformation create-stack --stack-name "CecilTenantRegionStack" \
  --template-body "file://tenant-aws-region-setup.template" \
  --region us-east-1

To monitor more regions, simply repeat this step with a different --region parameter.

Launch EC2 instance in 2nd account and verify behavior

Launch a new EC2 instance

$ AWS_ACCESS_KEY_ID=AKIAJEF AWS_SECRET_ACCESS_KEY=6KLcaqGeH aws ec2 run-instances --image-id ami-46c1b650 --count 1 --instance-type t2.micro --key-name MyKeyPair

You should see the same behavior as described in Launch EC2 instance and verify behavior

Customize for your team

Add AWS keypair associations

The idea behind AWS keypair associations is to be able to detect who launched an EC2 Instance without having to require custom resource tags. This is useful if you have automation that launches instances and you don’t want to update that automation to add resource tags.

Issue a request against this REST API endpoint:

curl -X POST \
  -H 'authorization: Bearer eyJhbGc' \
  -H 'cache-control: no-cache' \
  -H 'content-type: application/json' \
  -d '{
  "email":"yourcoworker@yourcompany.co",
  "key_name": "yourcoworker"
}' "http://localhost:8080/accounts/1/cloudaccounts/1/owners"

and you should see response:

{"message":"Owner added successfully to whitelist"}

Now if any instances are launched with the yourcoworker AWS keypair, the lease will automatically be assigned to yourcoworker@yourcompany.co, and a lease confirmation email will be sent to that address.

Configuration Reference

Cecil can use configuration from the config.yml file in its current directory, or from environment variables, which will override anything in the config.yml file.

Note
the environment variables must be in all-caps or else they will be ignored.

Here is the reference for all configuration values that can be specified either in the config.yml or as environment variables.

Table 1. Cecil Configuration
YAML config name Environment variable config name Example Default Description

AWS_ACCESS_KEY_ID

AWS_ACCESS_KEY_ID

AKIAIEXAMPLETXGA5C4ZSQ

None

The AWS access key for the CecilRootUser IAM user created via the CecilRootStack Cloudformation Stack

AWS_ACCOUNT_ID

AWS_ACCOUNT_ID

788612350

None

The AWS account ID where the CecilRootStack Cloudformation Stack is running. Needed to construct ARN’s (AWS resource identifiers)

AWS_SECRET_ACCESS_KEY

AWS_SECRET_ACCESS_KEY

ZhcmCxQmazD8u

None

The AWS secret access key for the CecilRootUser IAM user created via the CecilRootStack Cloudformation Stack

AWS_REGION

AWS_REGION

us-east-2

None

The AWS region where the CecilRootStack Cloudformation Stack is running. Needed to construct ARN’s (AWS resource identifiers)

CECIL_RSA_PRIVATE

CECIL_RSA_PRIVATE

~/cecil_rsa_private

None

Cecil uses JWT tokens in a few places to verify the authenticity of links sent to users via email. In order for this to work, it needs an RSA keypair. If not provided, it will generate a keypair on its own and use it, and emit it on the console. However, if you want to restart the cecil process and re-use the generated keypair, check the logs from the first run and capture the emitted private key into a file and then reference the file in an environment variable named CECIL_RSA_PRIVATE:

ForeignIAMRoleName

FOREIGNIAMROLENAME

AcmeCloudJanitorRole

CecilRole

Useful in case you want to customize the resource names created in the AWS cloud. In this case, it affects the name of the IAM Role that Cecil will create and use in the AWS account being monitored.

LeaseDuration

LEASEDURATION

72h

72h

How long a lease lasts by default before it will expire and must be renewed, or else the EC2 instances tracked by the lease will be terminated. See golang/time for time syntax examples

LeaseApprovalTimeoutDuration

LEASEAPPROVALTIMEOUTDURATION

24h

24h

In certain cases (TODO: document this), the administrator will need to approve the lease or else the instance will be terminated early. This is the max allowed time window for that approval process. See golang/time for time syntax examples

LeaseFirstWarningBeforeExpiry

LEASEFIRSTWARNINGBEFOREEXPIRY

24h

24h

How long before a lease expires when Cecil sends the owner the first warning with a link to extende the lease. See golang/time for time syntax examples

LeaseSecondWarningBeforeExpiry

LEASESECONDWARNINGBEFOREEXPIRY

1h

1h

How long before a lease expires when Cecil sends the owner the second and final warning with a link to extende the lease. See golang/time for time syntax examples

LeaseMaxPerOwner

LEASEMAXPEROWNER

10

10

How many leases per unique owner email address (or mapped AWS keypair) are allowed without administrator approval

MailerAPIKey

MAILERAPIKEY

key-82ea6cfe7dc69f6c

None

The Mailgun API key. At the moment, mailgun is the only option for outgoing mail. Please open an issue if you need a different option. You can find the mailer (Mailgun) API keys in the Maigun Web Admin For MAILERAPIKEY use the value in Active API Key and for MAILERPUBLICAPIKEY use Email Validation Key

MailerPublicAPIKey

MAILERPUBLICAPIKEY

pubkey-e9ceff19d2749

None

The Mailgun public api key.

MailerDomain

MAILERDOMAIN

sandboxc66.mailgun.org

None

The Mailgun domain.

ProductName

PRODUCTNAME

AcmeCloudJanitor

Cecil

Basic white label functionality, which controls things like FROM address and email template text (not comprehensive yet)

ServerHostName

SERVERHOSTNAME

cecil.yourserver.co

localhost

The URL to link back to the hostname (domain name or IP address), which is used to generate links in emails

ServerPort

SERVERPORT

:8080

:8080

The port to bind to, which is also used to generate links in emails. Must have a leading colon (:)

ServerScheme

SERVERSCHEME

https

http

Whether to use HTTP or HTTPS. This affects links that appear in email messages.

SNSTopicName

SNSTOPICNAME

AcmeCloudJanitorSNS

CecilTopic

In case you want to customize the resource names created in the AWS cloud. In this case, it affects the name of the SNS (Simple Notification Service) topic that will forward CloudWatch Events to Cecil.

SQSQueueName

SQSQUEUENAME

AcmeCloudJanitorSQS

CecilQueue

Useful in case you want to customize the resource names created in the AWS cloud. In this case, it affects the name of the SQS (Simple Queue Service) that will be created in the CecilRootStack to receive the CloudWatch Events from the AWS account being monitored.

TokenDuration

TOKENDURATION

720h

720h

How long REST API JWT authentication tokens are valid before expiring. See golang/time for time syntax examples

Deployment

Deploying to Docker Cloud

Preserving the database across restarts

Most of the time you will want to preserve the data across redeploys of the Cecil Docker Cloud service. Here are the steps to do that:

ssh into node

Follow the SSH into a Docker Cloud-managed node instructions to add your SSH key.

Copy the database file to a file on the host

After you have ssh’d into the Docker Cloud host, run these steps to copy the database file

$ cd /root
$ CONTAINER_ID=$(docker ps | grep -i cecil | awk '{print $1}')
$ docker cp $CONTAINER_ID:/go/src/github.com/tleyden/cecil/cecil.db .
Note
if you haven’t started the Cecil service on Docker Cloud, then just run this instead:
$ cd /root
$ touch cecil.db

Update the service

In the volumes section, hit the plus button to the right of the second line Add volumes, and use:

  • Container path: /go/src/github.com/tleyden/cecil/cecil.db

  • Host path: /root/cecil.db

You can now redeploy the service and your data will be preserved.

Switching from SQLite → Postgres

Via customizing config.yml

In your config.yml customize the values that correspond to your postgres installation.

Start Cecil with the --db-type flag set to postgres:

$ cecil --db-type postgres

Via environment variables

Or instead of customizing the config.yml, you can override with environment variables, but since Viper expects dots in the names, you have to use env as in the example below.

Start Cecil with the --db-type flag set to postgres:

$ env "POSTGRES.HOST=postgres1" "POSTGRES.USER=testuser2" "POSTGRES.PASSWORD=testuser2pass" "POSTGRES.DBNAME=cecil" cecil --db-type postgres

Cecil REST API

Cecil comes with powerful REST API that allows you to customize its behavior and examine various aspects of its state.

Swagger API Docs

Adhoc API Docs (deprecated)

Note
These are most likely out of date and will be replaced by the Swagger API docs, but there are still a few things in these docs that are missing from the Swagger API docs.

CLI Wrapper

All of the Cecil REST API funcionality is also exposed via a command line interface. Try running cecil-cli -h to see the available commands.

$ cecil-cli -h
CLI client for the Cecil service ()

Usage:
  Cecil-cli [command]

Available Commands:
  actions                      Perform an action on a lease
  add                          Add new cloudaccount
  addWhitelistedOwner          Add new email (plus optional KeyName) to owner tag whitelist
  create                       Create new account
  deleteFromDB                 Delete a lease from DB
  deleteWhitelistedOwner       Delete a whitelisted owner
  download                     Download file with given path
  downloadInitialSetupTemplate Download AWS initial setup cloudformation template
  downloadRegionSetupTemplate  Download AWS region setup cloudformation template
  help                         Help about any command
  listLeasesForAccount         List all leases for account
  listLeasesForCloudaccount    List all leases for a Cloudaccount
  listRegions                  List all regions and their status
  listWhitelistedOwners        List whitelisted owners
  mailerConfig                 Configure custom mailer
  newAPIToken                  Create new API token
  removeMailer                 Remove custom mailer
  removeSlack                  Remove slack
  setExpiry                    Set expiry of a lease
  show                         show action
  slackConfig                  Configure slack
  subscribeSNSToSQS            Subscribe SNS to SQS
  terminate                    Terminate a lease
  update                       Update a cloudaccount
  updateWhitelistedOwner       Modify a whitelisted owner
  verify                       Verify account and get API token

Flags:
      --dump               Dump HTTP request and response.
      --format string      Format used to create auth header or query from key (default "Bearer %s")
  -H, --host string        API hostname (default "127.0.0.1:8080")
      --key string         API key used for authentication
  -s, --scheme string      Set the requests scheme
  -t, --timeout duration   Set the request timeout (default 20s)

Use "Cecil-cli [command] --help" for more information about a command.

Postman Collection

There is also a postman file that can be imported rather than using curl.

  1. Open Postman

  2. Click on "Import"

  3. Import cecil.postman_collection.json

  4. Make sure to run it with a "cecil_environment"

Run the first API request with your name and email address.

After you receive the email with verification_token, paste it as payload in the second API request.

Now you can run the other endpoints as the JWT token from the second response has been added to the environment.

Slack Integration

Configure Slack

Setup steps:

  1. In your Slack app, go to Custom Integrations > Bots

  2. Add a new bot integration

  3. Choose a username like "@cecil"

  4. Slack will give you an API token, eg xoxb-000000000-aaaaaaaaaaaaa, which will be used in the API call to the Cecil REST API

If you don’t already have one, you’ll need to obtain an API token for the Authorization header. (See Obtain another API token in [this doc](ConfigureAWSAccount.md))

To add Slack as a mean of comunication between you and Cecil, use this endpoint.

curl -X POST \
-H "Authorization: $AUTH_TOKEN" \
-H "Content-Type: application/json" \
-H "Cache-Control: no-cache" \
-d '{
	"token":"xoxb-000000000-aaaaaaaaaaaaa",
	"channel_id":"#general"
}' \
"http://localhost:8080/accounts/1/slack_config"

Cecil will send messages to the specified channel, and you will be able to issue commands to Cecil.

E.g. To list all available commands, post this in the channel specified in the config, or to the Cecil bot user directly:

@cecil help

To interact with the bot via a channel rather than direct messaging, you can invite the bot to the channel.

Remove Slack

curl -X DELETE \
-H "Authorization: $AUTH_TOKEN" \
-H "Content-Type: application/json" \
-H "Cache-Control: no-cache" \
"http://localhost:8080/accounts/1/slack_config"

Cecil for Endusers 👼

Cloudformation fleets and AutoScalingGroups

Cecil automatically recognizes Cloudformation fleets and AutoScalingGroups as distinct entities, and will create the lease on the parent container rather on the EC2 instance itself. That means if you launch a Cloudformation template that contains multiple standalone EC2 instances, Cecil will only create a single lease.

In a complex Cloudformation template with standalone instances and several AutoScalingGroups, the lease assignment would be as follows:

Cecil Cloudformation ASG Lease

The lease termination behavior around Cloudformation and AutoScalingGroup instance containers are as follows:

  1. When a lease against a Clouformation expires, only the EC2 instances within the Cloudformation will be terminated, and all other resources in the Cloudformation will remained untouched

  2. When a lease against an AutoScalingGroup expires, only the EC2 instances will be terminated (by setting the DesiredCapacity to 0), and the AutoScalingGroup itself will remain. This is true even if the AutoScalingGroup is nested inside of a Cloudformation.

Manually grouping standalone instances into a single lease

Cecil doesn’t have a way to automatically group standalone EC2 instances into a single lease. If you launch multiple instances via aws ec2 run-instances --count X, Cecil won’t know any better and will create X leases, and you’ll get a barrage of X emails, which of course is not ideal.

To fix this, there is a special AWS tag called CecilInstanceGroup that you can pass to Cecil to tell it to group related EC2 instances into a single lease.

aws ec2 run-instances --image-id ami-abc12345 --count 50 \
--tag-specifications 'ResourceType=instance,Tags=[{Key=CecilInstanceGroup,Value=PerfTest25}]']'

See the Cecil AWS Tags Reference section below for more documentation on the CecilInstanceGroup tag.

Cecil AWS Tags Reference

The following AWS tags can be added to EC2 instances to control Cecil’s behavior.

Table 2. AWS TAGS
Tag Example Description

CecilOwner

you@yourcompany.com

The email address of the person who should own this lease. No prior registrion of this email / user required.

CecilInstanceGroup

PerfTest25

All EC2 instances with this tag will be grouped into a single lease. Useful when you want to treat EC2 instances as a group, but you are not using CloudFormation or AutoScalingGroups

CecilLeaseExpiresIn

2h

Override the default lease time and have the lease expire in this amount of time. Format is based on Go’s time.ParseDuration() rules

CecilLeaseExpiresOn

tonight at 11:10pm

Override the default lease time and have the lease expire on this particular datetime. Format is based on olebedev/when

Note
If you customize the ProductName configuration, Cecil will be replaced by whatever you use in the ProductName. So for example if ProductName is set to AcmeCloudBot then instead of naming your tag CecilOwner, you would need to name it AcmeCloudBotOwner.

Cecil for Developers 👽

Github repo

Generating goa code

./goagen.sh

Swagger Endpoint

To view the Swagger spec in JSON format, go to:

curl http://host:port/swagger.json

Replacing host:port with the host and port where you are running cecil

Regenerate gobindata email templates

$ ./go-bindata.sh

Publish release binary to github

  1. Add a tag (eg, v1.0.0) and push to github

  2. Set github token env variable (see goreleaser docs)

  3. On OSX, in the cecil project root directory run goreleaser with no args

TODO: figure out how to build linux binaries after getting past Cross compile failing

Listing of code directories/files and their purposes

This list is a bit out of date, but may help to follow the code.

  • add-owner-handler.go — Contains the handler function for adding a new owner to owner’s whitelist for a cloudaccount.

  • aws.go — Contains SQS structs and DefaultEc2ServiceFactory.

  • common.go — Contains common utility functions.

  • core.go — Contains the all the initialization code for the core package.

  • core_test.go — core package test.

  • db-models.go — Contains the database models.

  • email-action-handler.go — Contains the handler function for lease approval|extension|termination link endpoints.

  • email-templates.go — Will contain the templates of the emails sent out for specific scenarios (new lease, lease expired, instance terminated, etc.).

  • mock_ec2.go — Contains a mock of the EC2 API.

  • mock_mailgun.go — Contains a mock of the Mailgun API.

  • mock_sqs.go — Contains a mock of the SQS API.

  • new-lease-queue-consumer.go — Contains the consumer function for the NewInstanceQueue.

  • periodic-jobs.go — Contains the periodic job functions

  • service.go — Contains the Service struct and the initialization methods (to setup queues, db, external services, etc.)

  • task-consumers.go — Contains some of the functions that consume tasks from queues; some got their own file because are big.

  • task-structs.go — Contains the structs of the tasks passed in-out of queues.

  • transmission.go — Contains the Transmission and its methods; Transmission is what an SQS message is parsed to.