Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
f381319
retention for VPC flowlog
KollaAdithya Nov 8, 2022
a1bb794
add retention to env manifest
KollaAdithya Nov 10, 2022
e4c1315
change loggroup name
KollaAdithya Nov 11, 2022
6a9bb53
address @efekarakus fb
KollaAdithya Nov 14, 2022
302ee5e
add comement
KollaAdithya Nov 14, 2022
d1638cc
add comment to a function
KollaAdithya Nov 14, 2022
05af96e
address more feedback
KollaAdithya Nov 14, 2022
534fe62
change function description
KollaAdithya Nov 15, 2022
198a771
chore: read environment addons from the workspace (#4147)
Lou1415926 Nov 8, 2022
e82c877
fix: access logs bucket policy applied after ALB update (#4169)
dannyrandall Nov 11, 2022
bd916a1
chore: implement new api for the `workspace` package (#4166)
Lou1415926 Nov 11, 2022
d894d60
chore: fix e2e and integration tests failed by 4166 (#4171)
Lou1415926 Nov 11, 2022
986ec50
fix: Check to see if an application exists globally before creating i…
KollaAdithya Nov 14, 2022
c8a3d2a
chore: Bump github.com/onsi/gomega from 1.24.0 to 1.24.1 (#4178)
dependabot[bot] Nov 14, 2022
358583e
chore: Bump github.com/aws/aws-sdk-go from 1.44.131 to 1.44.136 (#4177)
dependabot[bot] Nov 14, 2022
7f27636
feat: `env deploy --no-rollback` flag (#4168)
dannyrandall Nov 16, 2022
2287f15
feat: add AutoScalingConfiguration to RDWS (#4186)
KollaAdithya Nov 17, 2022
d313de9
chore: set tasks fewer than `spot_from` to fargate cp when `min` and …
huanjani Nov 17, 2022
bfed98a
chore: generic union transformer and detect zero using reflection (#4…
dannyrandall Nov 18, 2022
ab8bd8d
change flowlog to *bool
KollaAdithya Nov 19, 2022
53c2004
Merge branch 'aws:mainline' into flowlogretention
KollaAdithya Nov 21, 2022
13ba6e6
Merge branch 'mainline' into flowlogretention
mergify[bot] Nov 21, 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
6 changes: 5 additions & 1 deletion internal/pkg/deploy/cloudformation/stack/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -433,12 +433,16 @@ func (e *EnvStackConfig) vpcConfig() (template.VPCConfig, error) {
if err != nil {
return template.VPCConfig{}, err
}
flowLogs, err := convertFlowLogsConfig(e.in.Mft)
if err != nil {
return template.VPCConfig{}, err
}
return template.VPCConfig{
Imported: e.importVPC(),
Managed: e.managedVPC(),
AllowVPCIngress: e.in.Mft.HTTPConfig.Private.HasVPCIngress(),
SecurityGroupConfig: securityGroupConfig,
FlowLogs: aws.BoolValue(e.in.Mft.Network.VPC.Flowlogs),
FlowLogs: flowLogs,
}, nil
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,8 @@ type: Environment`
type: Environment
network:
vpc:
flow_logs: on`
flow_logs:
retention: 60`
var mft manifest.Environment
err := yaml.Unmarshal([]byte(rawMft), &mft)
require.NoError(t, err)
Expand Down
1 change: 1 addition & 0 deletions internal/pkg/deploy/cloudformation/stack/env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ func TestEnv_Template(t *testing.T) {
PublicSubnetCIDRs: DefaultPublicSubnetCIDRs,
},
SecurityGroupConfig: nil,
FlowLogs: nil,
},
LatestVersion: deploy.LatestEnvTemplateVersion,
CustomResources: map[string]template.S3ObjectLocation{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ Metadata:
type: Environment
network:
vpc:
flow_logs: on
flow_logs:
retention: 60

Parameters:
AppName:
Expand Down Expand Up @@ -1003,14 +1004,21 @@ Resources:
DomainName: !Ref AppDNSName
PublicAccessDNS: !GetAtt PublicLoadBalancer.DNSName
PublicAccessHostedZone: !GetAtt PublicLoadBalancer.CanonicalHostedZoneID
VpcFlowLogGroup:
Type: AWS::Logs::LogGroup
Metadata:
'aws:copilot:description': 'A CloudWatch log group to store VPC flow log data'
Properties:
LogGroupName: !Join ['-', [!Ref AppName, !Ref EnvironmentName, FlowLogs]]
RetentionInDays: 60
FlowLog:
Metadata:
'aws:copilot:description': 'A flow log for the VPC to capture information about the IP traffic'
Type: AWS::EC2::FlowLog
Properties:
DeliverLogsPermissionArn: !GetAtt FlowLogRole.Arn
LogDestinationType: cloud-watch-logs
LogGroupName: !Join ['-', [!Ref AppName, !Ref EnvironmentName, FlowLogGroup]]
LogGroupName: !Ref VpcFlowLogGroup
MaxAggregationInterval: 60
ResourceId: !Ref VPC
ResourceType: VPC
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -833,14 +833,21 @@ Resources:
DomainName: !Ref AppDNSName
PublicAccessDNS: !GetAtt PublicLoadBalancer.DNSName
PublicAccessHostedZone: !GetAtt PublicLoadBalancer.CanonicalHostedZoneID
VpcFlowLogGroup:
Type: AWS::Logs::LogGroup
Metadata:
'aws:copilot:description': 'A CloudWatch log group to store VPC flow log data'
Properties:
LogGroupName: !Join ['-', [!Ref AppName, !Ref EnvironmentName, FlowLogs]]
RetentionInDays: 14
FlowLog:
Metadata:
'aws:copilot:description': 'A flow log for the VPC to capture information about the IP traffic'
Type: AWS::EC2::FlowLog
Properties:
DeliverLogsPermissionArn: !GetAtt FlowLogRole.Arn
LogDestinationType: cloud-watch-logs
LogGroupName: !Join ['-', [!Ref AppName, !Ref EnvironmentName, FlowLogGroup]]
LogGroupName: !Ref VpcFlowLogGroup
MaxAggregationInterval: 60
ResourceId: vpc-12345
ResourceType: VPC
Expand Down
16 changes: 16 additions & 0 deletions internal/pkg/deploy/cloudformation/stack/transformers.go
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,22 @@ func convertELBAccessLogsConfig(mft *manifest.Environment) (*template.ELBAccessL
}, nil
}

// convertFlowLogsConfig converts the VPC FlowLog configuration into a format parsable by the templates pkg.
func convertFlowLogsConfig(mft *manifest.Environment) (*template.VPCFlowLogs, error) {
vpcFlowLogs := mft.EnvironmentConfig.Network.VPC.FlowLogs
if vpcFlowLogs.IsZero() {
return nil, nil
}
retentionInDays := aws.Int(14)
if vpcFlowLogs.Advanced.Retention != nil {
retentionInDays = vpcFlowLogs.Advanced.Retention
}
return &template.VPCFlowLogs{
Retention: retentionInDays,
}, nil

}

func convertEnvSecurityGroupCfg(mft *manifest.Environment) (*template.SecurityGroupConfig, error) {
securityGroupConfig, isSecurityConfigSet := mft.EnvSecurityGroup()
if !isSecurityConfigSet {
Expand Down
22 changes: 16 additions & 6 deletions internal/pkg/manifest/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,11 @@ type environmentNetworkConfig struct {
}

type environmentVPCConfig struct {
ID *string `yaml:"id,omitempty"`
CIDR *IPNet `yaml:"cidr,omitempty"`
Subnets subnetsConfiguration `yaml:"subnets,omitempty"`
SecurityGroupConfig securityGroupConfig `yaml:"security_group,omitempty"`
Flowlogs *bool `yaml:"flow_logs,omitempty"`
ID *string `yaml:"id,omitempty"`
CIDR *IPNet `yaml:"cidr,omitempty"`
Subnets subnetsConfiguration `yaml:"subnets,omitempty"`
SecurityGroupConfig securityGroupConfig `yaml:"security_group,omitempty"`
FlowLogs Union[*bool, VPCFlowLogsArgs] `yaml:"flow_logs,omitempty"`
}

type securityGroupConfig struct {
Expand Down Expand Up @@ -187,6 +187,16 @@ func (cfg *portsConfig) UnmarshalYAML(value *yaml.Node) error {
return nil
}

// VPCFlowLogsArgs holds the flow logs configuration.
type VPCFlowLogsArgs struct {
Retention *int `yaml:"retention,omitempty"`
}

// IsZero implements yaml.IsZeroer.
func (fl *VPCFlowLogsArgs) IsZero() bool {
return fl.Retention == nil
}

// EnvSecurityGroup returns the security group config if the user has set any values.
// If there is no env security group settings, then returns nil and false.
func (cfg *EnvironmentConfig) EnvSecurityGroup() (*securityGroupConfig, bool) {
Expand Down Expand Up @@ -262,7 +272,7 @@ func (cfg *EnvironmentCDNConfig) UnmarshalYAML(value *yaml.Node) error {

// IsEmpty returns true if vpc is not configured.
func (cfg environmentVPCConfig) IsEmpty() bool {
return cfg.ID == nil && cfg.CIDR == nil && cfg.Subnets.IsEmpty() && cfg.Flowlogs == nil
return cfg.ID == nil && cfg.CIDR == nil && cfg.Subnets.IsEmpty() && cfg.FlowLogs.IsZero()
}

func (cfg *environmentVPCConfig) loadVPCConfig(env *config.CustomizeEnv) {
Expand Down
15 changes: 14 additions & 1 deletion internal/pkg/manifest/env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -858,8 +858,21 @@ func TestEnvironmentVPCConfig_IsEmpty(t *testing.T) {
},
"not empty when flowlog is on": {
in: environmentVPCConfig{
Flowlogs: aws.Bool(true),
FlowLogs: Union[*bool, VPCFlowLogsArgs]{
Basic: aws.Bool(true),
},
},
wanted: true,
},
"not empty when flowlog with specific retention": {
in: environmentVPCConfig{
FlowLogs: Union[*bool, VPCFlowLogsArgs]{
Advanced: VPCFlowLogsArgs{
Retention: aws.Int(60),
},
},
},
wanted: true,
},
}
for name, tc := range testCases {
Expand Down
8 changes: 8 additions & 0 deletions internal/pkg/manifest/validate_env.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ func (cfg environmentVPCConfig) validate() error {
return fmt.Errorf(`validate "subnets" for an adjusted VPC: %w`, err)
}
}
if err := cfg.FlowLogs.validate(); err != nil {
return fmt.Errorf(`validate vpc "flowlogs": %w`, err)
}
return nil
}

Expand Down Expand Up @@ -269,6 +272,11 @@ func (c subnetConfiguration) validate() error {
return nil
}

// validate is a no-op for VPCFlowLogsArgs.
func (fl VPCFlowLogsArgs) validate() error {
return nil
}

// validate returns nil if environmentObservability is configured correctly.
func (o environmentObservability) validate() error {
return nil
Expand Down
24 changes: 24 additions & 0 deletions internal/pkg/manifest/validate_env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,30 @@ func TestEnvironmentConfig_validate(t *testing.T) {
},
wantedError: "CDN must be enabled to limit security group ingress to CloudFront",
},
"valid vpc flowlogs with default retention": {
in: EnvironmentConfig{
Network: environmentNetworkConfig{
VPC: environmentVPCConfig{
FlowLogs: Union[*bool, VPCFlowLogsArgs]{
Basic: aws.Bool(true),
},
},
},
},
},
"valid vpc flowlogs with a specified retention": {
in: EnvironmentConfig{
Network: environmentNetworkConfig{
VPC: environmentVPCConfig{
FlowLogs: Union[*bool, VPCFlowLogsArgs]{
Advanced: VPCFlowLogsArgs{
Retention: aws.Int(30),
},
},
},
},
},
},
"valid elb access logs config with bucket_prefix": {
in: EnvironmentConfig{
HTTPConfig: EnvironmentHTTPConfig{
Expand Down
7 changes: 6 additions & 1 deletion internal/pkg/template/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ type VPCConfig struct {
Managed ManagedVPC
AllowVPCIngress bool
SecurityGroupConfig *SecurityGroupConfig
FlowLogs bool
FlowLogs *VPCFlowLogs
}

// ImportVPC holds the fields to import VPC resources.
Expand Down Expand Up @@ -215,6 +215,11 @@ type SecurityGroupRule struct {
ToPort int
}

// VPCFlowLogs holds the fields to configure logging IP traffic using VPC flow logs.
type VPCFlowLogs struct {
Comment thread
KollaAdithya marked this conversation as resolved.
Retention *int
}

// ParseEnv parses an environment's CloudFormation template with the specified data object and returns its content.
func (t *Template) ParseEnv(data *EnvOpts) (*Content, error) {
tpl, err := t.parse("base", envCFTemplatePath, withEnvParsingFuncs())
Expand Down
11 changes: 9 additions & 2 deletions internal/pkg/template/templates/environment/cf.yml
Original file line number Diff line number Diff line change
Expand Up @@ -587,15 +587,22 @@ Resources:
{{- if not .VPCConfig.Imported}}
{{include "ar-vpc-connector" . | indent 2}}
{{- end}}
{{- if .VPCConfig.FlowLogs }}
{{- if .VPCConfig.FlowLogs}}
VpcFlowLogGroup:
Type: AWS::Logs::LogGroup
Metadata:
'aws:copilot:description': 'A CloudWatch log group to store VPC flow log data'
Properties:
LogGroupName: !Join ['-', [!Ref AppName, !Ref EnvironmentName, FlowLogs]]
RetentionInDays: {{.VPCConfig.FlowLogs.Retention}}
FlowLog:
Metadata:
'aws:copilot:description': 'A flow log for the VPC to capture information about the IP traffic'
Type: AWS::EC2::FlowLog
Properties:
DeliverLogsPermissionArn: !GetAtt FlowLogRole.Arn
LogDestinationType: cloud-watch-logs
LogGroupName: !Join ['-', [!Ref AppName, !Ref EnvironmentName, FlowLogGroup]]
LogGroupName: !Ref VpcFlowLogGroup
MaxAggregationInterval: 60
{{- if .VPCConfig.Imported}}
ResourceId: {{.VPCConfig.Imported.ID}}
Expand Down