mirror of https://github.com/docker/compose.git
`up` can update an existing stack using CloudFormation Changeset
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
parent
efeded2670
commit
2d931dab9d
|
@ -26,14 +26,6 @@ func (b *Backend) Up(ctx context.Context, options cli.ProjectOptions) error {
|
|||
return err
|
||||
}
|
||||
|
||||
update, err := b.api.StackExists(ctx, project.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if update {
|
||||
return fmt.Errorf("we do not (yet) support updating an existing CloudFormation stack")
|
||||
}
|
||||
|
||||
template, err := b.Convert(project)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -62,17 +54,34 @@ func (b *Backend) Up(ctx context.Context, options cli.ProjectOptions) error {
|
|||
ParameterLoadBalancerARN: lb,
|
||||
}
|
||||
|
||||
err = b.api.CreateStack(ctx, project.Name, template, parameters)
|
||||
update, err := b.api.StackExists(ctx, project.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
operation := compose.StackCreate
|
||||
if update {
|
||||
operation = compose.StackUpdate
|
||||
changeset, err := b.api.CreateChangeSet(ctx, project.Name, template, parameters)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = b.api.UpdateStack(ctx, changeset)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
err = b.api.CreateStack(ctx, project.Name, template, parameters)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println()
|
||||
w := console.NewProgressWriter()
|
||||
for k := range template.Resources {
|
||||
w.ResourceEvent(k, "PENDING", "")
|
||||
}
|
||||
return b.WaitStackCompletion(ctx, project.Name, compose.StackCreate, w)
|
||||
return b.WaitStackCompletion(ctx, project.Name, operation, w)
|
||||
}
|
||||
|
||||
func (b Backend) GetVPC(ctx context.Context, project *types.Project) (string, error) {
|
||||
|
|
|
@ -23,6 +23,8 @@ type API interface {
|
|||
GetStackID(ctx context.Context, name string) (string, error)
|
||||
WaitStackComplete(ctx context.Context, name string, operation int) error
|
||||
DescribeStackEvents(ctx context.Context, stackID string) ([]*cf.StackEvent, error)
|
||||
CreateChangeSet(ctx context.Context, name string, template *cloudformation.Template, parameters map[string]string) (string, error)
|
||||
UpdateStack(ctx context.Context, changeset string) error
|
||||
|
||||
DescribeServices(ctx context.Context, cluster string, arns []string) ([]compose.ServiceStatus, error)
|
||||
|
||||
|
|
|
@ -175,9 +175,8 @@ func (s sdk) CreateStack(ctx context.Context, name string, template *cf.Template
|
|||
param := []*cloudformation.Parameter{}
|
||||
for name, value := range parameters {
|
||||
param = append(param, &cloudformation.Parameter{
|
||||
ParameterKey: aws.String(name),
|
||||
ParameterValue: aws.String(value),
|
||||
UsePreviousValue: aws.Bool(true),
|
||||
ParameterKey: aws.String(name),
|
||||
ParameterValue: aws.String(value),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -194,6 +193,60 @@ func (s sdk) CreateStack(ctx context.Context, name string, template *cf.Template
|
|||
return err
|
||||
}
|
||||
|
||||
func (s sdk) CreateChangeSet(ctx context.Context, name string, template *cf.Template, parameters map[string]string) (string, error) {
|
||||
logrus.Debug("Create CloudFormation Changeset")
|
||||
json, err := template.JSON()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
param := []*cloudformation.Parameter{}
|
||||
for name := range parameters {
|
||||
param = append(param, &cloudformation.Parameter{
|
||||
ParameterKey: aws.String(name),
|
||||
UsePreviousValue: aws.Bool(true),
|
||||
})
|
||||
}
|
||||
|
||||
update := fmt.Sprintf("Update%s", time.Now().Format("2006-01-02-15-04-05"))
|
||||
changeset, err := s.CF.CreateChangeSetWithContext(ctx, &cloudformation.CreateChangeSetInput{
|
||||
ChangeSetName: aws.String(update),
|
||||
ChangeSetType: aws.String(cloudformation.ChangeSetTypeUpdate),
|
||||
StackName: aws.String(name),
|
||||
TemplateBody: aws.String(string(json)),
|
||||
Parameters: param,
|
||||
Capabilities: []*string{
|
||||
aws.String(cloudformation.CapabilityCapabilityIam),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
err = s.CF.WaitUntilChangeSetCreateCompleteWithContext(ctx, &cloudformation.DescribeChangeSetInput{
|
||||
ChangeSetName: changeset.Id,
|
||||
})
|
||||
return *changeset.Id, err
|
||||
}
|
||||
|
||||
func (s sdk) UpdateStack(ctx context.Context, changeset string) error {
|
||||
desc, err := s.CF.DescribeChangeSetWithContext(ctx, &cloudformation.DescribeChangeSetInput{
|
||||
ChangeSetName: aws.String(changeset),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if strings.HasPrefix(aws.StringValue(desc.StatusReason), "The submitted information didn't contain changes.") {
|
||||
return nil
|
||||
}
|
||||
|
||||
_, err = s.CF.ExecuteChangeSet(&cloudformation.ExecuteChangeSetInput{
|
||||
ChangeSetName: aws.String(changeset),
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
func (s sdk) WaitStackComplete(ctx context.Context, name string, operation int) error {
|
||||
input := &cloudformation.DescribeStacksInput{
|
||||
StackName: aws.String(name),
|
||||
|
|
|
@ -19,6 +19,7 @@ type ServiceStatus struct {
|
|||
|
||||
const (
|
||||
StackCreate = iota
|
||||
StackUpdate
|
||||
StackDelete
|
||||
)
|
||||
|
||||
|
|
Loading…
Reference in New Issue