Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
c3cc8df
chore(manifest): add cdn bool to env manifest
Jun 27, 2022
d85dc7c
chore(manifest): add cdn bool to env manifest
Jun 27, 2022
b6d9890
Merge branch 'aws:mainline' into env-manifest-cdn
CaptainCarpensir Jun 27, 2022
b03957d
allow cfn to create barebones cf dist via stack
Jun 29, 2022
5161cc8
Update CDN stack template
Jun 30, 2022
ad38e53
add test, change cf public lb ingress
Jun 30, 2022
9ae4661
Merge branch 'mainline' into env-manifest-cdn
Jul 1, 2022
edebc10
get prefix list for public lb security group
Jul 5, 2022
fbc6ba6
correct ingress logic
Jul 5, 2022
2b43fcf
Merge branch 'mainline' into env-manifest-cdn
CaptainCarpensir Jul 5, 2022
507f86e
rename manifest tag to be more clear
Jul 5, 2022
023e34b
Merge branch 'env-manifest-cdn' of github.com:CaptainCarpensir/copilo…
Jul 5, 2022
58e4879
fix unit test manifest example
Jul 5, 2022
c6a8b4d
prefix-list changes
Jul 6, 2022
613b619
refactor pr scope
Jul 6, 2022
3edd667
Merge branch 'mainline' into env-manifest-cdn
CaptainCarpensir Jul 6, 2022
3e46ef1
fix missed merge overwrite conflict
Jul 6, 2022
26e4d44
fix merge conflicts
Jul 6, 2022
c500169
allow env manifest to restrict ingress to cf
Jul 8, 2022
ca60727
merge current build
Jul 8, 2022
539f30f
fix prefix list port specification
Jul 8, 2022
2c55f94
Merge branch 'mainline' into env-alb-prefix-list
CaptainCarpensir Jul 8, 2022
516bf62
split http/https security groups to allow secure port usage with cf
Jul 8, 2022
3a214ce
Merge branch 'env-alb-prefix-list' of github.com:CaptainCarpensir/cop…
Jul 8, 2022
e161ed2
fix accidental overwrite
Jul 8, 2022
b8240c3
Merge branch 'env-alb-prefix-list' of github.com:CaptainCarpensir/cop…
Jul 8, 2022
1c9dfa7
add mocks
Jul 8, 2022
45bdcc3
fix env integ test ymls
Jul 8, 2022
ede3738
implement iamhopaul123's feedback
Jul 11, 2022
a56809d
Merge branch 'mainline' into env-alb-prefix-list
Jul 14, 2022
e87bd63
address efekarakus feedback
Jul 15, 2022
8f2b16c
Merge branch 'mainline' into env-alb-prefix-list
CaptainCarpensir Jul 15, 2022
bd16406
Merge branch 'mainline' into env-alb-prefix-list
CaptainCarpensir Jul 15, 2022
972822e
fix env_test conflict manually
Jul 15, 2022
a2ed659
Merge branch 'mainline' into env-alb-prefix-list
CaptainCarpensir Jul 21, 2022
54d808a
fix local integ test
Jul 22, 2022
bc87660
refactor ingress
Jul 22, 2022
9a004fd
nit
Jul 22, 2022
395bcff
finalize prefix list getter structure
Jul 22, 2022
777ab6b
revert to before merge, fix nit
Jul 22, 2022
0815e34
address efekarakus and Lou1415926 feedback
Jul 25, 2022
f903a20
Merge branch 'mainline' into env-alb-prefix-list
Jul 25, 2022
f1d7afa
Merge branch 'mainline' into env-alb-prefix-list
CaptainCarpensir Jul 25, 2022
19ca126
merge conflict fixes
Jul 25, 2022
baa4bc7
Merge branch 'mainline' into env-alb-prefix-list
mergify[bot] Jul 25, 2022
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
12 changes: 6 additions & 6 deletions internal/pkg/aws/ec2/ec2.go
Original file line number Diff line number Diff line change
Expand Up @@ -472,24 +472,24 @@ func (c *EC2) managedPrefixList(prefixListName string) (*ec2.DescribeManagedPref
}

// CloudFrontManagedPrefixListID returns the PrefixListId of the associated cloudfront prefix list as a *string.
func (c *EC2) CloudFrontManagedPrefixListID() (*string, error) {
func (c *EC2) CloudFrontManagedPrefixListID() (string, error) {
prefixListsOutput, err := c.managedPrefixList(cloudFrontPrefixListName)

if err != nil {
return nil, err
return "", err
}

var ids []*string
var ids []string
for _, v := range prefixListsOutput.PrefixLists {
ids = append(ids, v.PrefixListId)
ids = append(ids, *v.PrefixListId)
}

if len(ids) == 0 {
return nil, fmt.Errorf("cannot find any prefix list with name: %s", cloudFrontPrefixListName)
return "", fmt.Errorf("cannot find any prefix list with name: %s", cloudFrontPrefixListName)
}

if len(ids) > 1 {
return nil, fmt.Errorf("found more than one prefix list with the name %s: %v", cloudFrontPrefixListName, ids)
return "", fmt.Errorf("found more than one prefix list with the name %s: %v", cloudFrontPrefixListName, ids)
}

return ids[0], nil
Expand Down
4 changes: 2 additions & 2 deletions internal/pkg/aws/ec2/ec2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ func TestEC2_CloudFrontManagedPrefixListId(t *testing.T) {

wantedError error
wantedErrorMsgPrefix string
wantedId *string
wantedId string
}{
"query returns error": {
mockEC2Client: func(m *mocks.Mockapi) {
Expand Down Expand Up @@ -418,7 +418,7 @@ func TestEC2_CloudFrontManagedPrefixListId(t *testing.T) {
},
}, nil)
},
wantedId: aws.String(mockPrefixListId),
wantedId: mockPrefixListId,
},
}

Expand Down
45 changes: 41 additions & 4 deletions internal/pkg/cli/deploy/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

awscfn "github.com/aws/aws-sdk-go/service/cloudformation"
"github.com/aws/copilot-cli/internal/pkg/aws/cloudformation"
"github.com/aws/copilot-cli/internal/pkg/aws/ec2"
"github.com/aws/copilot-cli/internal/pkg/aws/s3"
"github.com/aws/copilot-cli/internal/pkg/aws/sessions"
"github.com/aws/copilot-cli/internal/pkg/config"
Expand All @@ -34,13 +35,18 @@ type environmentDeployer interface {
ForceUpdateOutputID(app, env string) (string, error)
}

type prefixListGetter interface {
CloudFrontManagedPrefixListID() (string, error)
}

type envDeployer struct {
app *config.Application
env *config.Environment

// Dependencies to upload artifacts.
templateFS template.Reader
s3 uploader
templateFS template.Reader
s3 uploader
prefixListGetter prefixListGetter
// Dependencies to deploy an environment.
appCFN appResourcesGetter
envDeployer environmentDeployer
Expand Down Expand Up @@ -75,8 +81,9 @@ func NewEnvDeployer(in *NewEnvDeployerInput) (*envDeployer, error) {
app: in.App,
env: in.Env,

templateFS: template.New(),
s3: s3.New(envRegionSession),
templateFS: template.New(),
s3: s3.New(envRegionSession),
prefixListGetter: ec2.New(envRegionSession),

appCFN: deploycfn.New(defaultSession),
envDeployer: deploycfn.New(envManagerSession),
Expand Down Expand Up @@ -109,6 +116,31 @@ func (d *envDeployer) uploadCustomResources(bucket string) (map[string]string, e
return urls, nil
}

func (d *envDeployer) cidrPrefixLists(in *DeployEnvironmentInput) ([]string, error) {
var cidrPrefixListIDs []string

// Check if ingress is allowed from cloudfront
if in.Manifest == nil || !in.Manifest.IsIngressRestrictedToCDN() {
return nil, nil
}
cfManagedPrefixListID, err := d.cfManagedPrefixListID()
if err != nil {
return nil, err
}
cidrPrefixListIDs = append(cidrPrefixListIDs, cfManagedPrefixListID)

return cidrPrefixListIDs, nil
Comment on lines +120 to +132
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
var cidrPrefixListIDs []string
// Check if ingress is allowed from cloudfront
if in.Manifest == nil || !in.Manifest.IsIngressRestrictedToCDN() {
return nil, nil
}
cfManagedPrefixListID, err := d.cfManagedPrefixListID()
if err != nil {
return nil, err
}
cidrPrefixListIDs = append(cidrPrefixListIDs, cfManagedPrefixListID)
return cidrPrefixListIDs, nil
// Check if ingress is allowed from cloudfront
if in.Manifest == nil || !in.Manifest.IsIngressRestrictedToCDN() {
return nil, nil
}
id, err := d.cfManagedPrefixListID()
if err != nil {
return nil, err
}
return []string{id}, nil

}

func (d *envDeployer) cfManagedPrefixListID() (string, error) {
id, err := d.prefixListGetter.CloudFrontManagedPrefixListID()
if err != nil {
return "", fmt.Errorf("retrieve CloudFront managed prefix list id: %w", err)
}

return id, nil
}

// DeployEnvironmentInput contains information used to deploy the environment.
type DeployEnvironmentInput struct {
RootUserARN string
Expand Down Expand Up @@ -188,6 +220,10 @@ func (d *envDeployer) buildStackInput(in *DeployEnvironmentInput) (*deploy.Creat
if err != nil {
return nil, err
}
cidrPrefixListIDs, err := d.cidrPrefixLists(in)
if err != nil {
return nil, err
}
return &deploy.CreateEnvironmentInput{
Name: d.env.Name,
App: deploy.AppInformation{
Expand All @@ -199,6 +235,7 @@ func (d *envDeployer) buildStackInput(in *DeployEnvironmentInput) (*deploy.Creat
CustomResourcesURLs: in.CustomResourcesURLs,
ArtifactBucketARN: s3.FormatARN(partition.ID(), resources.S3Bucket),
ArtifactBucketKeyARN: resources.KMSKeyARN,
CIDRPrefixListIDs: cidrPrefixListIDs,
Mft: in.Manifest,
ForceUpdate: in.ForceNewUpdate,
RawMft: in.RawManifest,
Expand Down
59 changes: 52 additions & 7 deletions internal/pkg/cli/deploy/env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ import (
"strings"
"testing"

"github.com/aws/aws-sdk-go/aws"
awscfn "github.com/aws/aws-sdk-go/service/cloudformation"
"github.com/aws/copilot-cli/internal/pkg/cli/deploy/mocks"
"github.com/aws/copilot-cli/internal/pkg/config"
"github.com/aws/copilot-cli/internal/pkg/deploy"
"github.com/aws/copilot-cli/internal/pkg/deploy/cloudformation/stack"
"github.com/aws/copilot-cli/internal/pkg/deploy/upload/customresource"
"github.com/aws/copilot-cli/internal/pkg/manifest"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -116,9 +118,10 @@ func TestEnvDeployer_UploadArtifacts(t *testing.T) {
}

type deployEnvironmentMock struct {
appCFN *mocks.MockappResourcesGetter
envDeployer *mocks.MockenvironmentDeployer
stackSerializer *mocks.MockstackSerializer
appCFN *mocks.MockappResourcesGetter
envDeployer *mocks.MockenvironmentDeployer
stackSerializer *mocks.MockstackSerializer
prefixListGetter *mocks.MockprefixListGetter
}

func TestEnvDeployer_GenerateCloudFormationTemplate(t *testing.T) {
Expand Down Expand Up @@ -248,6 +251,7 @@ func TestEnvDeployer_DeployEnvironment(t *testing.T) {
}
testCases := map[string]struct {
setUpMocks func(m *deployEnvironmentMock)
inManifest *manifest.Environment
wantedError error
}{
"fail to get app resources by region": {
Expand All @@ -257,6 +261,42 @@ func TestEnvDeployer_DeployEnvironment(t *testing.T) {
},
wantedError: fmt.Errorf("get app resources in region %s: some error", mockEnvRegion),
},
"fail to get prefix list id": {
setUpMocks: func(m *deployEnvironmentMock) {
m.appCFN.EXPECT().GetAppResourcesByRegion(mockApp, mockEnvRegion).Return(&stack.AppRegionalResources{
S3Bucket: "mockS3Bucket",
}, nil)
m.prefixListGetter.EXPECT().CloudFrontManagedPrefixListID().Return("", errors.New("some error"))
},
inManifest: &manifest.Environment{
EnvironmentConfig: manifest.EnvironmentConfig{
HTTPConfig: manifest.EnvironmentHTTPConfig{
Public: manifest.PublicHTTPConfig{
SecurityGroupConfig: manifest.ALBSecurityGroupsConfig{
Ingress: manifest.Ingress{
RestrictiveIngress: manifest.RestrictiveIngress{
CDNIngress: aws.Bool(true),
},
},
},
},
},
},
},
wantedError: fmt.Errorf("retrieve CloudFront managed prefix list id: some error"),
},
"prefix list not retrieved when manifest not present": {
Comment thread
CaptainCarpensir marked this conversation as resolved.
setUpMocks: func(m *deployEnvironmentMock) {
m.appCFN.EXPECT().GetAppResourcesByRegion(mockApp, mockEnvRegion).Return(&stack.AppRegionalResources{
S3Bucket: "mockS3Bucket",
}, nil)
m.envDeployer.EXPECT().EnvironmentParameters(gomock.Any(), gomock.Any()).Return(nil, nil)
m.envDeployer.EXPECT().ForceUpdateOutputID(gomock.Any(), gomock.Any()).Return("", nil)
m.prefixListGetter.EXPECT().CloudFrontManagedPrefixListID().Return("mockPrefixListID", nil).Times(0)
m.envDeployer.EXPECT().UpdateAndRenderEnvironment(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
},
inManifest: nil,
},
"fail to get existing parameters": {
setUpMocks: func(m *deployEnvironmentMock) {
m.appCFN.EXPECT().GetAppResourcesByRegion(gomock.Any(), gomock.Any()).Return(&stack.AppRegionalResources{
Expand All @@ -281,6 +321,7 @@ func TestEnvDeployer_DeployEnvironment(t *testing.T) {
m.appCFN.EXPECT().GetAppResourcesByRegion(mockApp, mockEnvRegion).Return(&stack.AppRegionalResources{
S3Bucket: "mockS3Bucket",
}, nil)
m.prefixListGetter.EXPECT().CloudFrontManagedPrefixListID().Return("mockPrefixListID", nil).Times(0)
m.envDeployer.EXPECT().EnvironmentParameters(gomock.Any(), gomock.Any()).Return(nil, nil)
m.envDeployer.EXPECT().ForceUpdateOutputID(gomock.Any(), gomock.Any()).Return("", nil)
m.envDeployer.EXPECT().UpdateAndRenderEnvironment(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New("some error"))
Expand All @@ -292,6 +333,7 @@ func TestEnvDeployer_DeployEnvironment(t *testing.T) {
m.appCFN.EXPECT().GetAppResourcesByRegion(mockApp, mockEnvRegion).Return(&stack.AppRegionalResources{
S3Bucket: "mockS3Bucket",
}, nil)
m.prefixListGetter.EXPECT().CloudFrontManagedPrefixListID().Return("mockPrefixListID", nil).Times(0)
m.envDeployer.EXPECT().EnvironmentParameters(gomock.Any(), gomock.Any()).Return(nil, nil)
m.envDeployer.EXPECT().ForceUpdateOutputID(gomock.Any(), gomock.Any()).Return("", nil)
m.envDeployer.EXPECT().UpdateAndRenderEnvironment(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
Expand All @@ -304,8 +346,9 @@ func TestEnvDeployer_DeployEnvironment(t *testing.T) {
defer ctrl.Finish()

m := &deployEnvironmentMock{
appCFN: mocks.NewMockappResourcesGetter(ctrl),
envDeployer: mocks.NewMockenvironmentDeployer(ctrl),
appCFN: mocks.NewMockappResourcesGetter(ctrl),
envDeployer: mocks.NewMockenvironmentDeployer(ctrl),
prefixListGetter: mocks.NewMockprefixListGetter(ctrl),
}
tc.setUpMocks(m)
d := envDeployer{
Expand All @@ -315,14 +358,16 @@ func TestEnvDeployer_DeployEnvironment(t *testing.T) {
ManagerRoleARN: mockManagerRoleARN,
Region: mockEnvRegion,
},
appCFN: m.appCFN,
envDeployer: m.envDeployer,
appCFN: m.appCFN,
envDeployer: m.envDeployer,
prefixListGetter: m.prefixListGetter,
}
mockIn := &DeployEnvironmentInput{
RootUserARN: "mockRootUserARN",
CustomResourcesURLs: map[string]string{
"mockResource": "mockURL",
},
Manifest: tc.inManifest,
}
gotErr := d.DeployEnvironment(mockIn)
if tc.wantedError != nil {
Expand Down
38 changes: 38 additions & 0 deletions internal/pkg/cli/deploy/mocks/mock_env.go

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

25 changes: 13 additions & 12 deletions internal/pkg/deploy/cloudformation/stack/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,18 +96,19 @@ func (e *EnvStackConfig) Template() (string, error) {
forceUpdateID = id.String()
}
content, err := e.parser.ParseEnv(&template.EnvOpts{
AppName: e.in.App.Name,
EnvName: e.in.Name,
CustomResources: crs,
ArtifactBucketARN: e.in.ArtifactBucketARN,
ArtifactBucketKeyARN: e.in.ArtifactBucketKeyARN,
PublicImportedCertARNs: e.importPublicCertARNs(),
PrivateImportedCertARNs: e.importPrivateCertARNs(),
VPCConfig: e.vpcConfig(),
CustomInternalALBSubnets: e.internalALBSubnets(),
AllowVPCIngress: aws.BoolValue(e.in.Mft.HTTPConfig.Private.SecurityGroupsConfig.Ingress.VPCIngress),
Telemetry: e.telemetryConfig(),
CDNConfig: e.cdnConfig(),
AppName: e.in.App.Name,
EnvName: e.in.Name,
CustomResources: crs,
ArtifactBucketARN: e.in.ArtifactBucketARN,
ArtifactBucketKeyARN: e.in.ArtifactBucketKeyARN,
PublicFacingCIDRPrefixListIDs: e.in.CIDRPrefixListIDs,
PublicImportedCertARNs: e.importPublicCertARNs(),
PrivateImportedCertARNs: e.importPrivateCertARNs(),
VPCConfig: e.vpcConfig(),
CustomInternalALBSubnets: e.internalALBSubnets(),
AllowVPCIngress: aws.BoolValue(e.in.Mft.HTTPConfig.Private.SecurityGroupsConfig.Ingress.VPCIngress),
Telemetry: e.telemetryConfig(),
CDNConfig: e.cdnConfig(),

Version: e.in.Version,
LatestVersion: deploy.LatestEnvTemplateVersion,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,13 @@ func TestEnvStack_Template(t *testing.T) {
rawMft := `name: test
type: Environment
# Create the public ALB with certificates attached.
cdn: true
http:
public:
security_groups:
ingress:
restrict_to:
cdn: true
certificates:
- cert-1
- cert-2
Expand All @@ -51,6 +56,7 @@ observability:
Name: "demo",
},
Name: "test",
CIDRPrefixListIDs: []string{"pl-mockid"},
ArtifactBucketARN: "arn:aws:s3:::mockbucket",
ArtifactBucketKeyARN: "arn:aws:kms:us-west-2:000000000:key/1234abcd-12ab-34cd-56ef-1234567890ab",
CustomResourcesURLs: map[string]string{
Expand Down
Loading