// create our base stack func stackInit(c *cli.Context) { stackName := c.Args().First() if stackName == "" { log.Fatal("ERROR: stack name required") } if c.String("region") != "" { stack.Region = c.String("region") } exists, err := stack.Exists(stackName) if exists { log.Fatalf("ERROR: stack %s already exists", stackName) } else if err != nil { fmt.Println("EXISTS ERROR") log.Fatal(err) } params := getInitOpts(c) stackTmpl, err := stack.GalaxyTemplate(params) if err != nil { log.Fatalf("ERROR: %s", err) } if c.Bool("print") { fmt.Println(string(stackTmpl)) return } opts := make(map[string]string) opts["tag.galaxy"] = "base" _, err = stack.Create(stackName, stackTmpl, opts) if err != nil { log.Fatalf("ERROR: %s", err) } log.Println("Initializing stack", stackName) }
func stackCreatePool(c *cli.Context) { var err error ensureEnvArg(c) ensurePoolArg(c) if c.String("region") != "" { stack.Region = c.String("region") } poolName := utils.GalaxyPool(c) baseStack := getBase(c) poolEnv := utils.GalaxyEnv(c) stackName := fmt.Sprintf("%s-%s-%s", baseStack, poolEnv, poolName) pool := stack.NewPool() // get the resources we need from the base stack // TODO: this may search for the base stack a second time resources := sharedResources(c, baseStack) desiredCap := c.Int("desired-size") if desiredCap == 0 { desiredCap = 1 } numZones := c.Int("availability-zones") if numZones == 0 { // default to running one host per zone numZones = desiredCap } minSize := c.Int("min-size") maxSize := c.Int("max-size") httpPort := c.Int("http-port") if httpPort == 0 { httpPort = 80 } sslCert := "" if cert := c.String("ssl-cert"); cert != "" { sslCert = resources.ServerCerts[cert] if sslCert == "" { log.Fatalf("Could not find certificate '%s'", cert) } } // Create our Launch Config lc := pool.LCTemplate lcName := "lc" + poolEnv + poolName if amiID := c.String("ami"); amiID != "" { lc.Properties.ImageId = amiID } else { lc.Properties.ImageId = resources.Parameters["PoolImageId"] } if insType := c.String("instance-type"); insType != "" { lc.Properties.InstanceType = insType } else { lc.Properties.InstanceType = resources.Parameters["PoolInstanceType"] } if keyName := c.String("keyname"); keyName != "" { lc.Properties.KeyName = keyName } else { lc.Properties.KeyName = resources.Parameters["KeyName"] } lc.Properties.IamInstanceProfile = resources.Roles["galaxyInstanceProfile"] lc.Properties.SecurityGroups = []string{ resources.SecurityGroups["sshSG"], resources.SecurityGroups["defaultSG"], } lc.SetVolumeSize(c.Int("volume-size")) pool.Resources[lcName] = lc // Create the Auto Scaling Group asg := pool.ASGTemplate asgName := "asg" + poolEnv + poolName asg.AddTag("Name", fmt.Sprintf("%s-%s-%s", baseStack, poolEnv, poolName), true) asg.AddTag("env", poolEnv, true) asg.AddTag("pool", poolName, true) asg.AddTag("galaxy", "pool", true) asg.Properties.DesiredCapacity = desiredCap // Don't always run in all zones subnets := resources.Subnets if numZones <= len(subnets) { subnets = subnets[:numZones] } else { log.Fatal("ERROR: cannot run in %d zones, only %d available.", numZones, len(subnets)) } // break the subnets info into separate subnet and AZ slices for the template subnetIDs := []string{} azIDs := []string{} for _, sn := range subnets { subnetIDs = append(subnetIDs, sn.ID) azIDs = append(azIDs, sn.AvailabilityZone) } asg.SetLaunchConfiguration(lcName) asg.Properties.AvailabilityZones = azIDs asg.Properties.VPCZoneIdentifier = subnetIDs if maxSize > 0 { asg.Properties.MaxSize = maxSize } if minSize > 0 { asg.Properties.MinSize = minSize } if c.Bool("auto-update") { asg.SetASGUpdatePolicy(c.Int("update-min"), c.Int("update-batch"), c.Duration("update-pause")) } pool.Resources[asgName] = asg // Optionally create the Elastic Load Balancer if c.Bool("elb") { elb := pool.ELBTemplate elbName := "elb" + poolEnv + poolName // make sure to add this to the ASG asg.AddLoadBalancer(elbName) elb.Properties.Subnets = subnetIDs elb.Properties.SecurityGroups = []string{ resources.SecurityGroups["webSG"], resources.SecurityGroups["defaultSG"], } elb.Properties.HealthCheck.Target = c.String("http-health-check") elb.AddListener(80, "HTTP", httpPort, "HTTP", "", nil) if sslCert != "" { elb.AddListener(443, "HTTPS", httpPort, "HTTP", sslCert, nil) } pool.Resources[elbName] = elb } // add autoscaling if it's required setCPUAutoScale(c, pool) poolTmpl, err := json.MarshalIndent(pool, "", " ") if err != nil { log.Fatal(err) } if c.Bool("print") { fmt.Println(string(poolTmpl)) return } opts := make(map[string]string) opts["tag.env"] = poolEnv opts["tag.pool"] = poolName opts["tag.galaxy"] = "pool" _, err = stack.Create(stackName, poolTmpl, opts) if err != nil { log.Fatal(err) } log.Println("Creating stack:", stackName) // do we want to wait on this by default? if err := stack.Wait(stackName, 5*time.Minute); err != nil { log.Error(err) log.Error("CreateStack Failed, attempting to delete") waitAndDelete(stackName) return } log.Println("CreateStack complete") }