Skip to content

Commit

Permalink
ammonite scripts to manage the cloud
Browse files Browse the repository at this point in the history
  • Loading branch information
Michele Sciabarra committed Oct 8, 2017
1 parent fd47278 commit 9d2078b
Show file tree
Hide file tree
Showing 14 changed files with 214 additions and 5 deletions.
7 changes: 3 additions & 4 deletions README.md
@@ -1,15 +1,14 @@
# Mosaico

by [Michele Sciabarra](http://michele.sciabarra.com) and [Sciabarra.com](http://sciabarra.com)
by [Michele Sciabarra](http://michele.sciabarra.com) and [Sciabarra.com](http://sciabarra.com)

A starter kit for building a Cloud in AWS

- Terraform for creating the cloud
- Ansible for privisioning Docker and Jenkins
- Docker-Compose and Docker-Swarm for management
- Ammonite Scripts for configuration and management
- SBT for building a collection of Docker images

- Ammonite Scripts for configuration and management
- Docker-Compose and Docker-Swarm for management

## Beginning

Expand Down
4 changes: 4 additions & 0 deletions ammonite/.gitignore
@@ -0,0 +1,4 @@
session
history
cache/
saved/
7 changes: 7 additions & 0 deletions ammonite/README.md
@@ -0,0 +1,7 @@
# Scripts

- `aws.sc`: manage aws

- `cmd.sc`: execute externa commads

at some point in time the scripts will be autodocumenting
55 changes: 55 additions & 0 deletions ammonite/aws.sc
@@ -0,0 +1,55 @@
import ammonite.ops._
import collection.JavaConversions._

import $file.lib.SSH
import $file.lib.EC2

val defaultUser = Option(sys.props("aws.ssh.user")).getOrElse("centos")

val defaultTag = (Option(sys.props("aws.tag.name")).getOrElse("Application"),
Option(sys.props("aws.tag.value")).getOrElse("Mosaico"))

def doSsh(tag: (String,String), args: Seq[String]) {
val instances = EC2.runningTaggedInstances(tag)
val exec = SSH.Ssh(defaultUser, EC2.ipAddresses(instances))
try {
exec(args: _*)
} catch {
case err: Throwable => println(err.toString)
}
}

@main def ssh(args: String*) = {
if(args.head(0) == '@') {
args.head.tail.split(",").foreach {
host =>
print(s"[${host}] ")
val tag = "Name" -> host
doSsh(tag, args.tail)
}
} else {
//println(args)
doSsh(defaultTag, args)
}
}

@main def list() {
val instances = EC2.withTag(EC2.instances(), defaultTag)
val out = instances map { x =>
val tags = x.getTags.toList.map {
y => s"${y.getKey}=${y.getValue}"
}.mkString("[", ",", "]")
s"${x.getState.getName}\t${x.getPublicIpAddress}\t${x.getPublicDnsName}\t${x.getPrivateIpAddress}\t${x.getPrivateDnsName}\t${tags}"
}
println(out.mkString("\n"))
}

@main def stop() {
val instances = EC2.runningTaggedInstances(defaultTag)
EC2.stopInstances(instances)
}

@main def start() {
val instances = EC2.withTag(EC2.instances(), defaultTag)
EC2.startInstances(instances)
}
17 changes: 17 additions & 0 deletions ammonite/build.sbt
@@ -0,0 +1,17 @@
watchTransitiveSources := Seq()

enablePlugins(MosaicoAmmonitePlugin,MosaicoConfigPlugin)

ammPredef := Some("predef.sc")

prpLookup += baseDirectory.value.getParentFile -> "config"

addCommandAlias("aws", "amm aws.sc")

addCommandAlias("awssh", "amm aws.sc ssh")

addCommandAlias("cmd", "amm cmd.sc")

addCommandAlias("terraform", "amm cmd.sc terraform --args")

addCommandAlias("ansible", "amm cmd.sc ansible")
13 changes: 13 additions & 0 deletions ammonite/cmd.sc
@@ -0,0 +1,13 @@
import ammonite.ops._
import $file.lib.Cmd


@main def ansible() {
val inventory = sys.props("ansible.inventory")
val script = sys.props("ansible.script")
Cmd.ansible(inventory, script)
}

@main def terraform(args: String*) {
Cmd.terraform(args)
}
12 changes: 12 additions & 0 deletions ammonite/lib/Cmd.sc
@@ -0,0 +1,12 @@
import ammonite.ops._


def ansible(inventory: String, script: String) = {
val ansibleDir = pwd/up/'ansible
%("ansible-playbook", "-i", inventory, script)(ansibleDir)
}

def terraform(args: Seq[String]) = {
implicit val wd = pwd/up/'terraform
%("terraform", args)
}
63 changes: 63 additions & 0 deletions ammonite/lib/EC2.sc
@@ -0,0 +1,63 @@
import $ivy.`com.amazonaws:aws-java-sdk:1.11.22`

import ammonite.ops._
import collection.JavaConverters._

import com.amazonaws.services.ec2._
import com.amazonaws.services.ec2.model._
import com.amazonaws.regions.{Region=>Ec2Region,Regions=>Ec2Regions}

// instances

val region = Option(sys.props("mosaico.region")).getOrElse("us-east-1")

// client
val ec2 = new AmazonEC2Client()
val regions = Ec2Regions.fromName(region)
ec2.setRegion(Ec2Region.getRegion(regions))

// instances
def instances() = (for {
reservation <- ec2.describeInstances.getReservations.asScala
instance <- reservation.getInstances.asScala
} yield {
instance
}).toSeq

def running(insts: Seq[Instance]) = insts.filter {
_.getState.getName == "running"
}

def hasTag(tags: Seq[Tag], kv: (String,String)) = {
tags
.map(t => t.getKey == kv._1 && t.getValue == kv._2)
.reduce(_ || _)
}

def withTag(insts: Seq[Instance], kv: (String,String)) =
insts.filter { x =>
hasTag(x.getTags.asScala.toSeq, kv)
}

def runningTaggedInstances(tag: (String,String)) =
withTag(running(instances), tag)

def ipAddresses(instances: Seq[Instance]) = instances map {
x=> x.getPrivateIpAddress -> x.getPublicIpAddress
}

def dnsNames(instances: Seq[Instance]) = instances map {
x=> x.getPrivateDnsName -> x.getPublicDnsName
}

def startInstances(instances: Seq[Instance]) = {
val ids = instances.map { _.getInstanceId }
val req = new StartInstancesRequest().withInstanceIds(ids: _*)
ec2.startInstances(req)
}

def stopInstances(instances: Seq[Instance]) = {
val ids = instances.map { _.getInstanceId }
val req = new StopInstancesRequest().withInstanceIds(ids: _*)
ec2.stopInstances(req)
}
32 changes: 32 additions & 0 deletions ammonite/lib/SSH.sc
@@ -0,0 +1,32 @@
import ammonite.ops._

class Ssh(user: String, ips: Seq[(String,String)])
{
def apply(cmd: Any*): Unit = {

val args = cmd map { obj =>
obj match {
case s: Symbol => s.name
case x: Any => x.toString
}
}

implicit val wd = pwd

ips map { ip =>
val tgt = s"${user}@${ip._2}"

val sshArgs: Seq[String] = Seq(
"-o", "StrictHostKeyChecking=no",
tgt
) ++ args

println(s"[${ip._1}] ${args.mkString(" ")}")
%ssh(sshArgs)
}
}
}

object Ssh {
def apply(user: String, ips: Seq[(String,String)]) = new Ssh(user, ips)
}
1 change: 1 addition & 0 deletions ammonite/predef.sc
@@ -0,0 +1 @@
interp.colors() = ammonite.util.Colors.Default
1 change: 1 addition & 0 deletions ammonite/project/build.properties
@@ -0,0 +1 @@
sbt.version=0.13.16
1 change: 1 addition & 0 deletions ammonite/project/plugins.sbt
@@ -0,0 +1 @@
addSbtPlugin("com.sciabarra" %% "mosaico-sbt" % "0.4-SNAPSHOT")
5 changes: 5 additions & 0 deletions config.properties
@@ -0,0 +1,5 @@
aws.tag.name=Application
aws.tag.value=Mosaico
aws.ssh.user=centos
ansible.inventory=ec2.py
ansible.script=ec2.yml
1 change: 0 additions & 1 deletion terraform/terraform-stack
Submodule terraform-stack deleted from a75802

0 comments on commit 9d2078b

Please sign in to comment.