Skip to content

Commit 0c0205f

Browse files
committed
resource: use regex replace to match the stack name for cloudformation
1 parent a613a99 commit 0c0205f

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

resource/stack.go

+14
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package resource
22

33
import (
44
"fmt"
5+
"regexp"
56
"strings"
67
"time"
78

@@ -100,6 +101,9 @@ func (s Stack) CloudformationParametersType() ([]*cloudformation.Parameter, erro
100101
return params, nil
101102
}
102103

104+
// CloudformationStackName returns the corresponding stack name to create in cloudformation.
105+
//
106+
// The name needs to match [a-zA-Z][-a-zA-Z0-9]*|arn:[-a-zA-Z0-9:/._+]*
103107
func (s Stack) CloudformationStackName() *string {
104108
// Replace:
105109
// - "/" with "-", "/" appears in the path
@@ -112,6 +116,16 @@ func (s Stack) CloudformationStackName() *string {
112116
name = name + "-" + s.Region
113117
}
114118

119+
// Stack name needs to start with [a-zA-Z]
120+
// Remove leading characters that are not alphabetic
121+
firstAlphaRegex := regexp.MustCompile(`^[^a-zA-Z]*`)
122+
name = firstAlphaRegex.ReplaceAllString(name, "")
123+
124+
// Ensure the first character is alphabetic (already guaranteed by the previous step)
125+
// Remove or replace all characters that do not match [-a-zA-Z0-9]
126+
validCharsRegex := regexp.MustCompile(`[^-a-zA-Z0-9]+`)
127+
name = validCharsRegex.ReplaceAllString(name, "-")
128+
115129
return &name
116130
}
117131

resource/stack_test.go

+37
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,40 @@ func setFields(s *Stack) {
4141
}
4242
}
4343
}
44+
45+
func TestCloudformationStackName(t *testing.T) {
46+
tests := []struct {
47+
input Stack
48+
49+
want string
50+
}{
51+
{
52+
input: Stack{
53+
Name: "name",
54+
Path: "path",
55+
Region: "us-west-2",
56+
},
57+
want: "name-path-us-west-2",
58+
},
59+
{
60+
input: Stack{
61+
Path: "./path",
62+
Region: "us-west-2",
63+
},
64+
want: "path-us-west-2",
65+
},
66+
{
67+
input: Stack{
68+
Name: "@danny",
69+
Path: "./path",
70+
Region: "us-west-2",
71+
},
72+
want: "danny---path-us-west-2",
73+
},
74+
}
75+
76+
for _, tc := range tests {
77+
assert.Equal(t, tc.want, *tc.input.CloudformationStackName())
78+
}
79+
80+
}

0 commit comments

Comments
 (0)