Skip to content
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
14 changes: 10 additions & 4 deletions internal/pkg/aws/cloudformation/changeset.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,10 @@ func (cs *changeSet) String() string {

// create creates a ChangeSet, waits until it's created, and returns the ChangeSet ID on success.
func (cs *changeSet) create(conf *stackConfig) error {
out, err := cs.client.CreateChangeSet(&cloudformation.CreateChangeSetInput{
input := &cloudformation.CreateChangeSetInput{
ChangeSetName: aws.String(cs.name),
StackName: aws.String(cs.stackName),
ChangeSetType: aws.String(cs.csType.String()),
TemplateBody: aws.String(conf.Template),
Parameters: conf.Parameters,
Tags: conf.Tags,
RoleARN: conf.RoleARN,
Expand All @@ -104,7 +103,15 @@ func (cs *changeSet) create(conf *stackConfig) error {
cloudformation.CapabilityCapabilityNamedIam,
cloudformation.CapabilityCapabilityAutoExpand,
}),
})
}
if conf.TemplateBody != "" {
input.TemplateBody = aws.String(conf.TemplateBody)
}
if conf.TemplateURL != "" {
input.TemplateURL = aws.String(conf.TemplateURL)
}

out, err := cs.client.CreateChangeSet(input)
if err != nil {
return fmt.Errorf("create %s: %w", cs, err)
}
Expand All @@ -114,7 +121,6 @@ func (cs *changeSet) create(conf *stackConfig) error {
if err != nil {
return fmt.Errorf("wait for creation of %s: %w", cs, err)
}

// Since the ChangeSet creation succeeded, use the full ARN instead of the name.
// Using the full ID is essential in case the ChangeSet execution status is obsolete.
// If we call DescribeChangeSet using the ChangeSet name and Stack name on an obsolete changeset, the results is empty.
Expand Down
10 changes: 9 additions & 1 deletion internal/pkg/aws/cloudformation/cloudformation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,14 @@ func TestCloudFormation_Create(t *testing.T) {
return m
},
},
"creates the stack with templateURL": {
createMock: func(ctrl *gomock.Controller) client {
m := mocks.NewMockclient(ctrl)
m.EXPECT().DescribeStacks(gomock.Any()).Return(nil, errDoesNotExist)
addCreateDeployCalls(m)
return m
},
},
"creates the stack after cleaning the previously failed execution": {
createMock: func(ctrl *gomock.Controller) client {
m := mocks.NewMockclient(ctrl)
Expand Down Expand Up @@ -1184,7 +1192,7 @@ func addDeployCalls(m *mocks.Mockclient, changeSetType string) {
ChangeSetName: aws.String(mockChangeSetName),
StackName: aws.String(mockStack.Name),
ChangeSetType: aws.String(changeSetType),
TemplateBody: aws.String(mockStack.Template),
TemplateBody: aws.String(mockStack.TemplateBody),
Parameters: nil,
Tags: nil,
RoleARN: nil,
Expand Down
25 changes: 20 additions & 5 deletions internal/pkg/aws/cloudformation/stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ type Stack struct {
}

type stackConfig struct {
Template string
Parameters []*cloudformation.Parameter
Tags []*cloudformation.Tag
RoleARN *string
TemplateBody string
TemplateURL string
Parameters []*cloudformation.Parameter
Tags []*cloudformation.Tag
RoleARN *string
}

// StackOption allows you to initialize a Stack with additional properties.
Expand All @@ -29,7 +30,21 @@ func NewStack(name, template string, opts ...StackOption) *Stack {
s := &Stack{
Name: name,
stackConfig: &stackConfig{
Template: template,
TemplateBody: template,
},
}
for _, opt := range opts {
opt(s)
}
return s
}

// NewStackWithURL creates a stack with a URL to the template.
func NewStackWithURL(name, templateURL string, opts ...StackOption) *Stack {
s := &Stack{
Name: name,
stackConfig: &stackConfig{
TemplateURL: templateURL,
},
}
for _, opt := range opts {
Expand Down
31 changes: 30 additions & 1 deletion internal/pkg/aws/cloudformation/stack_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,36 @@ func TestNewStack(t *testing.T) {

// THEN
require.Equal(t, "hello", s.Name)
require.Equal(t, "world", s.Template)
require.Equal(t, "world", s.TemplateBody)
require.Equal(t, []*cloudformation.Parameter{
{
ParameterKey: aws.String("Port"),
ParameterValue: aws.String("80"),
},
}, s.Parameters)
require.Equal(t, []*cloudformation.Tag{
{
Key: aws.String("copilot-application"),
Value: aws.String("phonetool"),
},
}, s.Tags)
require.Equal(t, aws.String("arn"), s.RoleARN)
}

func TestNewStackWithURL(t *testing.T) {
// WHEN
s := NewStackWithURL("hello", "worldlyURL",
WithParameters(map[string]string{
"Port": "80",
}),
WithTags(map[string]string{
"copilot-application": "phonetool",
}),
WithRoleARN("arn"))

// THEN
require.Equal(t, "hello", s.Name)
require.Equal(t, "worldlyURL", s.TemplateURL)
require.Equal(t, []*cloudformation.Parameter{
{
ParameterKey: aws.String("Port"),
Expand Down
4 changes: 2 additions & 2 deletions internal/pkg/cli/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -334,8 +334,8 @@ type imageRemover interface {
}

type pipelineDeployer interface {
CreatePipeline(env *deploy.CreatePipelineInput) error
UpdatePipeline(env *deploy.CreatePipelineInput) error
CreatePipeline(env *deploy.CreatePipelineInput, bucketName string) error
UpdatePipeline(env *deploy.CreatePipelineInput, bucketName string) error
PipelineExists(env *deploy.CreatePipelineInput) (bool, error)
DeletePipeline(pipelineName string) error
AddPipelineResourcesToApp(app *config.Application, region string) error
Expand Down
32 changes: 16 additions & 16 deletions internal/pkg/cli/mocks/mock_interfaces.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading