Skip to content
This repository has been archived by the owner on Jan 21, 2020. It is now read-only.

New flags for playbook backends with AWS examples #828

Merged
merged 4 commits into from
Jan 8, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/infrakit/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ import (
// CLI backends
_ "github.com/docker/infrakit/pkg/cli/backend/http"
_ "github.com/docker/infrakit/pkg/cli/backend/instance"
_ "github.com/docker/infrakit/pkg/cli/backend/manager"
_ "github.com/docker/infrakit/pkg/cli/backend/print"
_ "github.com/docker/infrakit/pkg/cli/backend/sh"
_ "github.com/docker/infrakit/pkg/cli/backend/ssh"
_ "github.com/docker/infrakit/pkg/cli/backend/stack"
_ "github.com/docker/infrakit/pkg/cli/backend/vmwscript"

// Supported "kinds"
Expand Down
21 changes: 21 additions & 0 deletions examples/playbooks/aws/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Example Playbook for AWS
========================

This playbook contains example of working with AWS. There are commands for
starting up infrakit (which assumes you have used AWS CLI on your local computer and
the `.aws/credentials` file exists) and commands for spinning up an on-demand or
spot instance configured with Docker, Git and Go compiler.

## Adding this playbook

Adding files locally:

```
infrakit playbook add aws file://$(pwd)/index.yml
```

Adding the playbook from Github:

```
infrakit playbook add aws https://raw.githubusercontent.com/docker/infrakit/master/examples/playbooks/aws/index.yml
```
9 changes: 9 additions & 0 deletions examples/playbooks/aws/index.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

# Start infrakit
start : start.sh

# Create a single instance
ondemand : provision-instance.yml

# Create a spot instance
spot : provision-spot-instance.yml
56 changes: 56 additions & 0 deletions examples/playbooks/aws/provision-instance.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{{/* Input to create instance using the AWS instance plugin */}}
{{/* =% instanceProvision `aws/ec2-instance` %= */}}

{{ $user := flag "user" "string" "username" | prompt "Please enter your user name:" "string" (env "USER")}}
{{ $project := flag "project" "string" "project" | prompt "Project?" "string" "myproject" }}
{{ $imageId := flag "image-id" "string" "Image ID" | prompt "AMI?" "string" "ami-df8406b0" }}
{{ $instanceType := flag "instance-type" "string" "instance type" | prompt "Instance type?" "string" "t2.micro" }}
{{ $privateIp := flag "private-ip" "string" "Private IP" | prompt "Private IP address (IPv4)?" "string" "172.31.20.100" }}


{{ $keyName := flag "key" "string" "ssh key name" | prompt "SSH key?" "string" "infrakit"}}
{{ $az := flag "az" "string" "availability zone" | prompt "Availability zone?" "string" "eu-central-1b"}}
{{ $subnetId := flag "subnet" "string" "subnet id" | prompt "Subnet ID?" "string" "subnet-11b8376a" }}
{{ $securityGroupId := flag "security-group-id" "string" "security group id" | prompt "Security group ID?" "string" "sg-975500fe" }}

Tags:
infrakit.scope: {{ $project }}
infrakit.created: {{ now | htmlDate }}
infrakit.user: {{ $user }}

Init: |
#!/bin/bash
sudo add-apt-repository ppa:gophers/archive
sudo apt-get update -y
sudo apt-get install -y wget curl git golang-1.9-go
wget -qO- https://get.docker.com | sh
ln -s /usr/lib/go-1.9/bin/go /usr/local/bin/go

Properties:
RunInstancesInput:
BlockDeviceMappings: null
DisableApiTermination: null
EbsOptimized: null
IamInstanceProfile: null
ImageId: {{ $imageId }}
InstanceInitiatedShutdownBehavior: null
InstanceType: {{ $instanceType }}
KeyName: {{ $keyName }}
NetworkInterfaces:
- AssociatePublicIpAddress: true
PrivateIpAddress: {{ $privateIp }}
DeleteOnTermination: true
DeviceIndex: 0
Groups:
- {{ $securityGroupId }}
NetworkInterfaceId: null
SubnetId: {{ $subnetId }}
Placement:
Affinity: null
AvailabilityZone: {{ $az }}
Tenancy: null
RamdiskId: null
SubnetId: null
UserData: null
Tags:
infrakit.user: {{ $user }}
49 changes: 49 additions & 0 deletions examples/playbooks/aws/provision-spot-instance.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{{/* Input to create a spot instance using the AWS instance plugin */}}
{{/* =% instanceProvision `aws/ec2-spot-instance` %= */}}

{{ $user := flag "user" "string" "username" | prompt "Please enter your user name:" "string" (env "USER")}}
{{ $project := flag "project" "string" "project" | prompt "Project?" "string" "myproject" }}
{{ $imageId := flag "image-id" "string" "Image ID" | prompt "AMI?" "string" "ami-df8406b0" }}
{{ $instanceType := flag "instance-type" "string" "instance type" | prompt "Instance type?" "string" "t2.micro" }}
{{ $privateIp := flag "private-ip" "string" "Private IP" | prompt "Private IP address (IPv4)?" "string" "172.31.20.100" }}
{{ $spotPrice := flag "spot-price" "string" "Spot price" | prompt "Spot price?" "string" "0.03" }}

{{ $keyName := flag "key" "string" "ssh key name" | prompt "SSH key?" "string" "infrakit"}}
{{ $az := flag "az" "string" "availability zone" | prompt "Availability zone?" "string" "eu-central-1b"}}
{{ $subnetId := flag "subnet" "string" "subnet id" | prompt "Subnet ID?" "string" "subnet-11b8376a" }}
{{ $securityGroupId := flag "security-group-id" "string" "security group id" | prompt "Security group ID?" "string" "sg-975500fe" }}

Tags:
infrakit.scope: {{ $project }}
infrakit.created: {{ now | htmlDate }}
infrakit.user: {{ $user }}

Init: |
#!/bin/bash
sudo add-apt-repository ppa:gophers/archive
sudo apt-get update -y
sudo apt-get install -y wget curl git golang-1.9-go
wget -qO- https://get.docker.com | sh
ln -s /usr/lib/go-1.9/bin/go /usr/local/bin/go

Properties:
RequestSpotInstancesInput:
LaunchSpecification:
ImageId: {{ $imageId }}
InstanceType: {{ $instanceType }}
KeyName: infrakit
NetworkInterfaces:
- AssociatePublicIpAddress: true
DeleteOnTermination: true
DeviceIndex: 0
Groups:
- {{ $securityGroupId }}
NetworkInterfaceId: null
PrivateIpAddress: {{ $privateIp }}
PrivateIpAddresses: null
SecondaryPrivateIpAddressCount: null
SubnetId: {{ $subnetId }}
Placement:
AvailabilityZone: {{ $az }}
SpotPrice: "{{ $spotPrice }}"
Type: one-time
26 changes: 26 additions & 0 deletions examples/playbooks/aws/start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{{/* =% sh %= */}}

{{ $profile := flag "aws-cred-profile" "string" "Profile name" | prompt "Profile for your .aws/credentials?" "string" "default" }}
{{ $region := flag "region" "string" "aws region" | prompt "Region?" "string" "eu-central-1"}}
{{ $project := flag "project" "string" "project name" | prompt "Project?" "string" "myproject" }}

echo "Starting infrakit with aws plugin..."

{{/* Pick a credential from the local user's ~/.aws folder. You should have this if you use awscli. */}}
{{ $creds := (source (cat "file://" (env "HOME") "/.aws/credentials" | nospace) | iniDecode | k $profile ) }}
FOUND="{{ not (empty $creds) }}"

if [ $FOUND = "false" ]; then
echo "no credentials found. bye"
exit 1
fi

{{ echo "Found your credential for profile" $profile }}

AWS_ACCESS_KEY_ID={{ $creds.aws_access_key_id }} \
AWS_SECRET_ACCESS_KEY={{ $creds.aws_secret_access_key }} \
INFRAKIT_AWS_REGION={{ $region }} \
INFRAKIT_AWS_STACK_NAME={{ $project }} \
INFRAKIT_AWS_NAMESPACE_TAGS="infrakit.scope={{ $project }}" \
INFRAKIT_AWS_MONITOR_POLL_INTERVAL=5s \
infrakit plugin start aws
54 changes: 25 additions & 29 deletions pkg/cli/backend/instance/provision.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,51 +8,47 @@ import (
"github.com/docker/infrakit/pkg/spi/instance"
"github.com/docker/infrakit/pkg/types"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)

func init() {
backend.Register("instanceProvision", Provision, nil)
backend.Register("instanceProvision", Provision,
func(flags *pflag.FlagSet) {
flags.String("plugin", "", "plugin")
})
}

// Provision backend requires the name of the plugin and a boolean to indicate if the content is yaml.
// It then returns an executable function based on that specification to call the named instance plugin's provision
// method.
// Provision returns an executable function based on that specification to call the named instance plugin's provision
// method. The optional parameter in the playbook script can be overridden by the value of the `--plugin` flag
// in the command line.
func Provision(scope scope.Scope, test bool, opt ...interface{}) (backend.ExecFunc, error) {

if len(opt) != 2 {
return nil, fmt.Errorf("require params: pluginName (string) and isYAML (bool)")
}

name, is := opt[0].(string)
if !is {
return nil, fmt.Errorf("first param (pluginName) must be string")
}
return func(script string, cmd *cobra.Command, args []string) error {

isYAML, is := opt[1].(bool)
if !is {
return nil, fmt.Errorf("second param (isYAML) must be a bool")
}
var name string

return func(script string, cmd *cobra.Command, args []string) error {
// Optional parameter for plugin name can be overridden by the value of the flag (--plugin):
if len(opt) > 0 {
s, is := opt[0].(string)
if !is {
return fmt.Errorf("first param (pluginName) must be string")
}
name = s
}
if n, err := cmd.Flags().GetString("plugin"); err != nil {
return err
} else if n != "" {
name = n
}

plugin, err := scope.Instance(name)
if err != nil {
return err
}

spec := instance.Spec{}
if isYAML {
y, err := types.AnyYAML([]byte(script))
if err != nil {
return err
}
if err := y.Decode(&spec); err != nil {
return err
}
} else {
if err := types.AnyString(script).Decode(&spec); err != nil {
return err
}
if err := types.Decode([]byte(script), &spec); err != nil {
return err
}

id, err := plugin.Provision(spec)
Expand Down
85 changes: 0 additions & 85 deletions pkg/cli/backend/manager/commit.go

This file was deleted.

54 changes: 54 additions & 0 deletions pkg/cli/backend/stack/enforce.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package stack

import (
"fmt"

"github.com/docker/infrakit/pkg/cli/backend"
"github.com/docker/infrakit/pkg/run/scope"
"github.com/docker/infrakit/pkg/types"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)

func init() {
backend.Register("stackEnforce", Enforce,
func(flags *pflag.FlagSet) {
flags.String("stack", "", "Name of stack")
})
}

// Enforce backend requires the name of the plugin and a boolean to indicate if the content is yaml.
// It then returns an executable function based on that specification to call the named instance plugin's provision
// method.
func Enforce(scope scope.Scope, test bool, opt ...interface{}) (backend.ExecFunc, error) {

return func(script string, cmd *cobra.Command, args []string) error {

var name string

// Optional parameter for plugin name can be overridden by the value of the flag (--stack):
if len(opt) > 0 {
n, is := opt[0].(string)
if !is {
return fmt.Errorf("first param (stackName) must be string")
}
name = n
}
name, err := cmd.Flags().GetString("stack")
if err != nil {
return err
}

stack, err := scope.Stack(name)
if err != nil {
return err
}

specs := types.Specs{}
if err := types.Decode([]byte(script), &specs); err != nil {
return err
}

return stack.Enforce(specs)
}, nil
}
Loading