labs

package module
v0.3.8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 21, 2022 License: Apache-2.0 Imports: 22 Imported by: 0

README

labs

Create AWS CloudFormation lab environment with convention based configuration.

  1. A user is created, named awsstudent
  2. Access key and secret for the user is created
  3. Key and secret written to "credentials.txt"
  4. An EC2 ssh key is created, named labkey
  5. The ssh key is written to labkey.pem
  6. The CloudFormation template is taken from the path lab${x}/cloudformation_template.txt
  7. The policy file lab${x)/iam_policy.json is
    • created as policy `lab${x)-policy``
    • attached to the user
  8. Info log file log/cfd.log is written

Overview

Architecture

Example

Given:

  • A subdirectory "lab1" with:
lab1/iam_policy.json 
lab1/cloudformation_template.txt 

Where iam_policy.json contains a AWS policy and cloudformation_template.txt contains a AWS CloudFormation template.

With

labs deploy -l 1

You get the output:

2021/07/30 09:04:14 Region used:  eu-central-1
2021/07/30 09:04:14 Region used:  eu-central-1
2021/07/30 09:04:14 Lab number:  1
2021/07/30 09:04:14 Create EC2 Key:  labkey
2021/07/30 09:04:14 Writing ssh key local:  labkey.pem
2021/07/30 09:04:14 Create User
2021/07/30 09:04:15 Create Access Key
2021/07/30 09:04:16 Create Lab Policy  lab1-policy  from:  ./lab1/iam_policy.json
2021/07/30 09:04:16 Create Stack
2021/07/30 09:04:17 Show Status
...

After the template is deployed, you get:

File  purpose
credentials.txt AWS_ACCESS_KEY_ID&AWS_SECRET_ACCESS_KEY of awsstudent iam user
labkey.pem  ssh private key
password.txt  password for awsstudent

Now you have the restriced user awsstudent, but you may also use privileged users in your account.

Destroy

After the lab you should tear the Cfn Stack and the associated resources down:

labs destroy -l 1

AMI search results

If the template references an AMI, it is automatically set

Example:

  AWSAmiId:
    Description: The name of the Windows AMI to find based on search
    Type: String
    Default: 'x86_64,Windows_Server-2012-R2_RTM-English-64Bit-Base'
Resources:
...

It uses something like:

aws ssm get-parameters-by-path \
    --path /aws/service/ami-windows-latest \
    --query 'Parameters[].[Name,Value]'

Troubleshooting

IAM user can not be deleted
panic: operation error IAM: DeleteUser, https response error StatusCode: 409, RequestID: bc97e79f-2438-4c9b-bb8b-6e7bd4bf149e, api error DeleteConflict: Cannot delete entity, must detach all policies first.

If you manually attach more policies to the user or if another lab, which cloudformation stack has not been deleted attaches policies to the user, then you have to detach them manually.

policy called lab1-policy already exists
CreateLabPolicy error:  operation error IAM: CreatePolicy, https response error StatusCode: 409, RequestID: c66d58ed-b772-4a42-adfe-6bdd9801e91c, EntityAlreadyExists: A policy called lab1-policy already exists

Run labs destroy -l 1 before deploy.

Documentation

Index

Constants

View Source
const (
	// ColorDefault default color
	ColorDefault = "\x1b[39m"
	// ColorRed red for screen
	ColorRed = "\x1b[91m"
	// ColorGreen green for screen
	ColorGreen = "\x1b[32m"
	// ColorBlue blue for screen
	ColorBlue = "\x1b[94m"
	// ColorGray for screen
	ColorGray = "\x1b[90m"
)
View Source
const StatusCreateComplete = "CREATE_COMPLETE"

StatusCreateComplete CloudFormation Status

View Source
const StatusCreateInProgress = "CREATE_IN_PROGRESS"

StatusCreateInProgress CloudFormation Status

View Source
const StatusDeleteComplete = "DELETE_COMPLETE"

StatusDeleteComplete CloudFormation Status

Variables

This section is empty.

Functions

func ClientEC2

func ClientEC2() *ec2.Client

ClientEC2 an ec2client

func ClientIAM

func ClientIAM() *iam.Client

ClientIAM IAM

func CountParameter

func CountParameter(template []byte) int

CountParameter - how mny params in the cfn template

func CreateAccessKey

func CreateAccessKey(client IAMInterface)

CreateAccessKey create key

func CreateKeyIfNotExist

func CreateKeyIfNotExist(client Ec2Interface)

CreateKeyIfNotExist ssh key handling

func CreateLabPolicy

func CreateLabPolicy(client IAMInterface, lab int)

CreateLabPolicy policy for awsstudent

func CreateStack

func CreateStack(client DeployInterface, name string, template []byte)

CreateStack creates a lab stack

func CreateUserIfnotExist

func CreateUserIfnotExist(client IAMInterface)

CreateUserIfnotExist awsstudent go

func DeleteAccessKey

func DeleteAccessKey(client IAMInterface)

DeleteAccessKey deletes

func DeleteKey

func DeleteKey(client Ec2Interface)

DeleteKey ec2 ssh key

func DeleteLabPolicy

func DeleteLabPolicy(client IAMInterface, lab int)

DeleteLabPolicy policy for awsstudent

func DeleteUserIfExist

func DeleteUserIfExist(client IAMInterface)

DeleteUserIfExist cleanup

func FindAmi

func FindAmi(client Ec2Interface, amiParameter string) string

FindAmi find ami id

func GenerateMyPassword

func GenerateMyPassword() string

func GetAccount

func GetAccount() string

GetAccount Current Account

func GetRegion

func GetRegion() string

GetRegion Current Region

func Getenv

func Getenv(key, fallback string) string

Getenv with fallback

func IsStackCompleted

func IsStackCompleted(data map[string]CloudFormationResource) bool

IsStackCompleted check for everything "completed"

func PolicyIAMAdditionalName

func PolicyIAMAdditionalName(lab int) string

func PolicyIAMName

func PolicyIAMName(lab int) string

func PopulateData

func PopulateData(client DeployInterface, name string, data map[string]CloudFormationResource) (map[string]CloudFormationResource, time.Time)

PopulateData update status from describe call

func ShowStatus

func ShowStatus(client DeployInterface, name string, template []byte)

ShowStatus status of stack

Types

type AccessKey

type AccessKey struct {
	AccessKeyID     string
	SecretAccessKey string
}

AccessKey short access key structure

type CloudFormationResource

type CloudFormationResource struct {
	LogicalResourceID  string
	PhysicalResourceID string
	Status             string
	Type               string
	Timestamp          time.Time
}

CloudFormationResource holder for status

type DeployInterface

type DeployInterface interface {
	CreateStack(ctx context.Context, params *cfn.CreateStackInput, optFns ...func(*cfn.Options)) (*cfn.CreateStackOutput, error)
	DescribeStackEvents(ctx context.Context, params *cfn.DescribeStackEventsInput, optFns ...func(*cfn.Options)) (*cfn.DescribeStackEventsOutput, error)
	DeleteStack(ctx context.Context, params *cfn.DeleteStackInput, optFns ...func(*cfn.Options)) (*cfn.DeleteStackOutput, error)
	UpdateStack(ctx context.Context, params *cfn.UpdateStackInput, optFns ...func(*cfn.Options)) (*cfn.UpdateStackOutput, error)
}

DeployInterface interface for deployment

type Ec2Interface

type Ec2Interface interface {
	DescribeKeyPairs(ctx context.Context, params *ec2.DescribeKeyPairsInput, optFns ...func(*ec2.Options)) (*ec2.DescribeKeyPairsOutput, error)
	CreateKeyPair(ctx context.Context, params *ec2.CreateKeyPairInput, optFns ...func(*ec2.Options)) (*ec2.CreateKeyPairOutput, error)
	DeleteKeyPair(ctx context.Context, params *ec2.DeleteKeyPairInput, optFns ...func(*ec2.Options)) (*ec2.DeleteKeyPairOutput, error)
	DescribeImages(ctx context.Context, params *ec2.DescribeImagesInput, optFns ...func(*ec2.Options)) (*ec2.DescribeImagesOutput, error)
}

Ec2Interface all actions which are used from ec2

type IAMInterface

type IAMInterface interface {
	AttachUserPolicy(ctx context.Context, params *iam.AttachUserPolicyInput, optFns ...func(*iam.Options)) (*iam.AttachUserPolicyOutput, error)
	DetachUserPolicy(ctx context.Context, params *iam.DetachUserPolicyInput, optFns ...func(*iam.Options)) (*iam.DetachUserPolicyOutput, error)

	CreateAccessKey(ctx context.Context, params *iam.CreateAccessKeyInput, optFns ...func(*iam.Options)) (*iam.CreateAccessKeyOutput, error)
	DeleteAccessKey(ctx context.Context, params *iam.DeleteAccessKeyInput, optFns ...func(*iam.Options)) (*iam.DeleteAccessKeyOutput, error)
	ListAccessKeys(ctx context.Context, params *iam.ListAccessKeysInput, optFns ...func(*iam.Options)) (*iam.ListAccessKeysOutput, error)

	CreateLoginProfile(ctx context.Context, params *iam.CreateLoginProfileInput, optFns ...func(*iam.Options)) (*iam.CreateLoginProfileOutput, error)
	DeleteLoginProfile(ctx context.Context, params *iam.DeleteLoginProfileInput, optFns ...func(*iam.Options)) (*iam.DeleteLoginProfileOutput, error)

	ListAttachedUserPolicies(ctx context.Context, params *iam.ListAttachedUserPoliciesInput, optFns ...func(*iam.Options)) (*iam.ListAttachedUserPoliciesOutput, error)

	ListUsers(ctx context.Context, params *iam.ListUsersInput, optFns ...func(*iam.Options)) (*iam.ListUsersOutput, error)
	CreateUser(ctx context.Context, params *iam.CreateUserInput, optFns ...func(*iam.Options)) (*iam.CreateUserOutput, error)
	DeleteUser(ctx context.Context, params *iam.DeleteUserInput, optFns ...func(*iam.Options)) (*iam.DeleteUserOutput, error)

	ListPolicies(ctx context.Context, params *iam.ListPoliciesInput, optFns ...func(*iam.Options)) (*iam.ListPoliciesOutput, error) //
	CreatePolicy(ctx context.Context, params *iam.CreatePolicyInput, optFns ...func(*iam.Options)) (*iam.CreatePolicyOutput, error)
	DeletePolicy(ctx context.Context, params *iam.DeletePolicyInput, optFns ...func(*iam.Options)) (*iam.DeletePolicyOutput, error)
}

IAMInterface used iam actions

type Parameter

type Parameter struct {
	Type                  string      `yaml:"Type"`
	Description           string      `yaml:"Description,omitempty"`
	Default               interface{} `yaml:"Default,omitempty"`
	AllowedPattern        string      `yaml:"AllowedPattern,omitempty"`
	AllowedValues         []string    `yaml:"AllowedValues,omitempty"`
	ConstraintDescription string      `yaml:"ConstraintDescription,omitempty"`
	MaxLength             int         `yaml:"MaxLength,omitempty"`
	MinLength             int         `yaml:"MinLength,omitempty"`
	MaxValue              float64     `yaml:"MaxValue,omitempty"`
	MinValue              float64     `yaml:"MinValue,omitempty"`
	NoEcho                bool        `yaml:"NoEcho,omitempty"`
}

Parameter map parms

type Parameters

type Parameters map[string]Parameter

Parameters map parms

func ReadParameter

func ReadParameter(template []byte) Parameters

ReadParameter - return parameters in template

func (*Parameters) ReadParameter

func (p *Parameters) ReadParameter() *Parameters

ReadParameter read cloudformation parameter - NO USED YET

type Template

type Template struct {
	AWSTemplateFormatVersion string                 `yaml:"AWSTemplateFormatVersion,omitempty"`
	Description              string                 `yaml:"Description,omitempty"`
	Metadata                 map[string]interface{} `yaml:"Metadata,omitempty"`
	Parameters               Parameters             `yaml:"Parameters,omitempty"`
	Mappings                 map[string]interface{} `yaml:"Mappings,omitempty"`
	Conditions               map[string]interface{} `yaml:"Conditions,omitempty"`
}

Template Parameters Cloudformation parameters

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL