Skip to content

Commit 01546e1

Browse files
authored
Merge pull request #15 from theonestack/feature/cloudwatch-logs
add support for exporting postgres logs to cloudwatch
2 parents b24e925 + a7a7bee commit 01546e1

File tree

3 files changed

+303
-0
lines changed

3 files changed

+303
-0
lines changed

aurora-postgres.cfndsl.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,11 +167,13 @@
167167
storage_encrypted = external_parameters.fetch(:storage_encrypted, nil)
168168
kms = external_parameters.fetch(:kms, false)
169169
cluster_maintenance_window = external_parameters.fetch(:cluster_maintenance_window, nil)
170+
cloudwatch_log_exports = external_parameters.fetch(:cloudwatch_log_exports, [])
170171

171172
RDS_DBCluster(:DBCluster) {
172173
Engine 'aurora-postgresql'
173174
EngineVersion engine_version unless engine_version.nil?
174175
DBClusterParameterGroupName Ref(:DBClusterParameterGroup)
176+
EnableCloudwatchLogsExports cloudwatch_log_exports if cloudwatch_log_exports.any?
175177
PreferredMaintenanceWindow cluster_maintenance_window unless cluster_maintenance_window.nil?
176178
SnapshotIdentifier FnIf('UseSnapshotID',Ref(:SnapshotID), Ref('AWS::NoValue'))
177179
MasterUsername FnIf('UseUsernameAndPassword', instance_username, Ref('AWS::NoValue'))
Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
1+
require 'yaml'
2+
3+
describe 'compiled component aurora-postgres' do
4+
5+
context 'cftest' do
6+
it 'compiles test' do
7+
expect(system("cfhighlander cftest #{@validate} --tests tests/cloudwatch_log_exports.test.yaml")).to be_truthy
8+
end
9+
end
10+
11+
let(:template) { YAML.load_file("#{File.dirname(__FILE__)}/../out/tests/cloudwatch_log_exports/aurora-postgres.compiled.yaml") }
12+
13+
context "Resource" do
14+
15+
16+
context "SecurityGroup" do
17+
let(:resource) { template["Resources"]["SecurityGroup"] }
18+
19+
it "is of type AWS::EC2::SecurityGroup" do
20+
expect(resource["Type"]).to eq("AWS::EC2::SecurityGroup")
21+
end
22+
23+
it "to have property VpcId" do
24+
expect(resource["Properties"]["VpcId"]).to eq({"Ref"=>"VPCId"})
25+
end
26+
27+
it "to have property GroupDescription" do
28+
expect(resource["Properties"]["GroupDescription"]).to eq({"Fn::Sub"=>"Aurora postgres aurora-postgres access for the ${EnvironmentName} environment"})
29+
end
30+
31+
it "to have property SecurityGroupEgress" do
32+
expect(resource["Properties"]["SecurityGroupEgress"]).to eq([{"CidrIp"=>"0.0.0.0/0", "Description"=>"outbound all for ports", "IpProtocol"=>-1}])
33+
end
34+
35+
it "to have property Tags" do
36+
expect(resource["Properties"]["Tags"]).to eq([{"Key"=>"Name", "Value"=>{"Fn::Sub"=>"${EnvironmentName}-aurora-postgres"}}, {"Key"=>"Environment", "Value"=>{"Ref"=>"EnvironmentName"}}, {"Key"=>"EnvironmentType", "Value"=>{"Ref"=>"EnvironmentType"}}])
37+
end
38+
39+
end
40+
41+
context "DBClusterSubnetGroup" do
42+
let(:resource) { template["Resources"]["DBClusterSubnetGroup"] }
43+
44+
it "is of type AWS::RDS::DBSubnetGroup" do
45+
expect(resource["Type"]).to eq("AWS::RDS::DBSubnetGroup")
46+
end
47+
48+
it "to have property SubnetIds" do
49+
expect(resource["Properties"]["SubnetIds"]).to eq({"Ref"=>"SubnetIds"})
50+
end
51+
52+
it "to have property DBSubnetGroupDescription" do
53+
expect(resource["Properties"]["DBSubnetGroupDescription"]).to eq({"Fn::Sub"=>"Aurora postgres aurora-postgres subnets for the ${EnvironmentName} environment"})
54+
end
55+
56+
it "to have property Tags" do
57+
expect(resource["Properties"]["Tags"]).to eq([{"Key"=>"Name", "Value"=>{"Fn::Sub"=>"${EnvironmentName}-aurora-postgres"}}, {"Key"=>"Environment", "Value"=>{"Ref"=>"EnvironmentName"}}, {"Key"=>"EnvironmentType", "Value"=>{"Ref"=>"EnvironmentType"}}])
58+
end
59+
60+
end
61+
62+
context "DBClusterParameterGroup" do
63+
let(:resource) { template["Resources"]["DBClusterParameterGroup"] }
64+
65+
it "is of type AWS::RDS::DBClusterParameterGroup" do
66+
expect(resource["Type"]).to eq("AWS::RDS::DBClusterParameterGroup")
67+
end
68+
69+
it "to have property Description" do
70+
expect(resource["Properties"]["Description"]).to eq({"Fn::Sub"=>"Aurora postgres aurora-postgres cluster parameters for the ${EnvironmentName} environment"})
71+
end
72+
73+
it "to have property Family" do
74+
expect(resource["Properties"]["Family"]).to eq("aurora-postgresql12")
75+
end
76+
77+
it "to have property Parameters" do
78+
expect(resource["Properties"]["Parameters"]).to eq({"timezone"=>"UTC"})
79+
end
80+
81+
it "to have property Tags" do
82+
expect(resource["Properties"]["Tags"]).to eq([{"Key"=>"Name", "Value"=>{"Fn::Sub"=>"${EnvironmentName}-aurora-postgres"}}, {"Key"=>"Environment", "Value"=>{"Ref"=>"EnvironmentName"}}, {"Key"=>"EnvironmentType", "Value"=>{"Ref"=>"EnvironmentType"}}])
83+
end
84+
85+
end
86+
87+
context "DBCluster" do
88+
let(:resource) { template["Resources"]["DBCluster"] }
89+
90+
it "is of type AWS::RDS::DBCluster" do
91+
expect(resource["Type"]).to eq("AWS::RDS::DBCluster")
92+
end
93+
94+
it "to have property Engine" do
95+
expect(resource["Properties"]["Engine"]).to eq("aurora-postgresql")
96+
end
97+
98+
it "to have property DBClusterParameterGroupName" do
99+
expect(resource["Properties"]["DBClusterParameterGroupName"]).to eq({"Ref"=>"DBClusterParameterGroup"})
100+
end
101+
102+
it "to have property EnableCloudwatchLogsExports" do
103+
expect(resource["Properties"]["EnableCloudwatchLogsExports"]).to eq(["postgresql"])
104+
end
105+
106+
it "to have property SnapshotIdentifier" do
107+
expect(resource["Properties"]["SnapshotIdentifier"]).to eq({"Fn::If"=>["UseSnapshotID", {"Ref"=>"SnapshotID"}, {"Ref"=>"AWS::NoValue"}]})
108+
end
109+
110+
it "to have property MasterUsername" do
111+
expect(resource["Properties"]["MasterUsername"]).to eq({"Fn::If"=>["UseUsernameAndPassword", {"Fn::Join"=>["", ["{{resolve:ssm:", {"Fn::Sub"=>"/rds/AURORA_POSTGRES_MASTER_USERNAME"}, ":1}}"]]}, {"Ref"=>"AWS::NoValue"}]})
112+
end
113+
114+
it "to have property MasterUserPassword" do
115+
expect(resource["Properties"]["MasterUserPassword"]).to eq({"Fn::If"=>["UseUsernameAndPassword", {"Fn::Join"=>["", ["{{resolve:ssm-secure:", {"Fn::Sub"=>"/rds/AURORA_POSTGRES_MASTER_PASSWORD"}, ":1}}"]]}, {"Ref"=>"AWS::NoValue"}]})
116+
end
117+
118+
it "to have property DBSubnetGroupName" do
119+
expect(resource["Properties"]["DBSubnetGroupName"]).to eq({"Ref"=>"DBClusterSubnetGroup"})
120+
end
121+
122+
it "to have property VpcSecurityGroupIds" do
123+
expect(resource["Properties"]["VpcSecurityGroupIds"]).to eq([{"Ref"=>"SecurityGroup"}])
124+
end
125+
126+
it "to have property Port" do
127+
expect(resource["Properties"]["Port"]).to eq(5432)
128+
end
129+
130+
it "to have property Tags" do
131+
expect(resource["Properties"]["Tags"]).to eq([{"Key"=>"Name", "Value"=>{"Fn::Sub"=>"${EnvironmentName}-aurora-postgres"}}, {"Key"=>"Environment", "Value"=>{"Ref"=>"EnvironmentName"}}, {"Key"=>"EnvironmentType", "Value"=>{"Ref"=>"EnvironmentType"}}])
132+
end
133+
134+
end
135+
136+
context "DBInstanceParameterGroup" do
137+
let(:resource) { template["Resources"]["DBInstanceParameterGroup"] }
138+
139+
it "is of type AWS::RDS::DBParameterGroup" do
140+
expect(resource["Type"]).to eq("AWS::RDS::DBParameterGroup")
141+
end
142+
143+
it "to have property Description" do
144+
expect(resource["Properties"]["Description"]).to eq({"Fn::Sub"=>"Aurora postgres aurora-postgres instance parameters for the ${EnvironmentName} environment"})
145+
end
146+
147+
it "to have property Family" do
148+
expect(resource["Properties"]["Family"]).to eq("aurora-postgresql12")
149+
end
150+
151+
it "to have property Tags" do
152+
expect(resource["Properties"]["Tags"]).to eq([{"Key"=>"Name", "Value"=>{"Fn::Sub"=>"${EnvironmentName}-aurora-postgres"}}, {"Key"=>"Environment", "Value"=>{"Ref"=>"EnvironmentName"}}, {"Key"=>"EnvironmentType", "Value"=>{"Ref"=>"EnvironmentType"}}])
153+
end
154+
155+
end
156+
157+
context "DBClusterInstanceWriter" do
158+
let(:resource) { template["Resources"]["DBClusterInstanceWriter"] }
159+
160+
it "is of type AWS::RDS::DBInstance" do
161+
expect(resource["Type"]).to eq("AWS::RDS::DBInstance")
162+
end
163+
164+
it "to have property DBSubnetGroupName" do
165+
expect(resource["Properties"]["DBSubnetGroupName"]).to eq({"Ref"=>"DBClusterSubnetGroup"})
166+
end
167+
168+
it "to have property DBParameterGroupName" do
169+
expect(resource["Properties"]["DBParameterGroupName"]).to eq({"Ref"=>"DBInstanceParameterGroup"})
170+
end
171+
172+
it "to have property DBClusterIdentifier" do
173+
expect(resource["Properties"]["DBClusterIdentifier"]).to eq({"Ref"=>"DBCluster"})
174+
end
175+
176+
it "to have property Engine" do
177+
expect(resource["Properties"]["Engine"]).to eq("aurora-postgresql")
178+
end
179+
180+
it "to have property PubliclyAccessible" do
181+
expect(resource["Properties"]["PubliclyAccessible"]).to eq("false")
182+
end
183+
184+
it "to have property DBInstanceClass" do
185+
expect(resource["Properties"]["DBInstanceClass"]).to eq({"Ref"=>"WriterInstanceType"})
186+
end
187+
188+
it "to have property Tags" do
189+
expect(resource["Properties"]["Tags"]).to eq([{"Key"=>"Name", "Value"=>{"Fn::Sub"=>"${EnvironmentName}-aurora-postgres"}}, {"Key"=>"Environment", "Value"=>{"Ref"=>"EnvironmentName"}}, {"Key"=>"EnvironmentType", "Value"=>{"Ref"=>"EnvironmentType"}}])
190+
end
191+
192+
end
193+
194+
context "DBClusterInstanceReader" do
195+
let(:resource) { template["Resources"]["DBClusterInstanceReader"] }
196+
197+
it "is of type AWS::RDS::DBInstance" do
198+
expect(resource["Type"]).to eq("AWS::RDS::DBInstance")
199+
end
200+
201+
it "to have property DBSubnetGroupName" do
202+
expect(resource["Properties"]["DBSubnetGroupName"]).to eq({"Ref"=>"DBClusterSubnetGroup"})
203+
end
204+
205+
it "to have property DBParameterGroupName" do
206+
expect(resource["Properties"]["DBParameterGroupName"]).to eq({"Ref"=>"DBInstanceParameterGroup"})
207+
end
208+
209+
it "to have property DBClusterIdentifier" do
210+
expect(resource["Properties"]["DBClusterIdentifier"]).to eq({"Ref"=>"DBCluster"})
211+
end
212+
213+
it "to have property Engine" do
214+
expect(resource["Properties"]["Engine"]).to eq("aurora-postgresql")
215+
end
216+
217+
it "to have property PubliclyAccessible" do
218+
expect(resource["Properties"]["PubliclyAccessible"]).to eq("false")
219+
end
220+
221+
it "to have property DBInstanceClass" do
222+
expect(resource["Properties"]["DBInstanceClass"]).to eq({"Ref"=>"ReaderInstanceType"})
223+
end
224+
225+
it "to have property Tags" do
226+
expect(resource["Properties"]["Tags"]).to eq([{"Key"=>"Name", "Value"=>{"Fn::Sub"=>"${EnvironmentName}-aurora-postgres"}}, {"Key"=>"Environment", "Value"=>{"Ref"=>"EnvironmentName"}}, {"Key"=>"EnvironmentType", "Value"=>{"Ref"=>"EnvironmentType"}}])
227+
end
228+
229+
end
230+
231+
context "DBClusterReaderRecord" do
232+
let(:resource) { template["Resources"]["DBClusterReaderRecord"] }
233+
234+
it "is of type AWS::Route53::RecordSet" do
235+
expect(resource["Type"]).to eq("AWS::Route53::RecordSet")
236+
end
237+
238+
it "to have property HostedZoneName" do
239+
expect(resource["Properties"]["HostedZoneName"]).to eq({"Fn::Join"=>["", [{"Ref"=>"EnvironmentName"}, ".", {"Ref"=>"DnsDomain"}, "."]]})
240+
end
241+
242+
it "to have property Name" do
243+
expect(resource["Properties"]["Name"]).to eq({"Fn::Join"=>["", ["aurora2pg-read", ".", {"Ref"=>"EnvironmentName"}, ".", {"Ref"=>"DnsDomain"}, "."]]})
244+
end
245+
246+
it "to have property Type" do
247+
expect(resource["Properties"]["Type"]).to eq("CNAME")
248+
end
249+
250+
it "to have property TTL" do
251+
expect(resource["Properties"]["TTL"]).to eq("60")
252+
end
253+
254+
it "to have property ResourceRecords" do
255+
expect(resource["Properties"]["ResourceRecords"]).to eq([{"Fn::GetAtt"=>["DBCluster", "ReadEndpoint.Address"]}])
256+
end
257+
258+
end
259+
260+
context "DBHostRecord" do
261+
let(:resource) { template["Resources"]["DBHostRecord"] }
262+
263+
it "is of type AWS::Route53::RecordSet" do
264+
expect(resource["Type"]).to eq("AWS::Route53::RecordSet")
265+
end
266+
267+
it "to have property HostedZoneName" do
268+
expect(resource["Properties"]["HostedZoneName"]).to eq({"Fn::Join"=>["", [{"Ref"=>"EnvironmentName"}, ".", {"Ref"=>"DnsDomain"}, "."]]})
269+
end
270+
271+
it "to have property Name" do
272+
expect(resource["Properties"]["Name"]).to eq({"Fn::Join"=>["", ["aurora2pg", ".", {"Ref"=>"EnvironmentName"}, ".", {"Ref"=>"DnsDomain"}, "."]]})
273+
end
274+
275+
it "to have property Type" do
276+
expect(resource["Properties"]["Type"]).to eq("CNAME")
277+
end
278+
279+
it "to have property TTL" do
280+
expect(resource["Properties"]["TTL"]).to eq("60")
281+
end
282+
283+
it "to have property ResourceRecords" do
284+
expect(resource["Properties"]["ResourceRecords"]).to eq([{"Fn::GetAtt"=>["DBCluster", "Endpoint.Address"]}])
285+
end
286+
287+
end
288+
289+
end
290+
291+
end
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
test_metadata:
2+
type: config
3+
name: cloudwatch_log_exports
4+
description: set the description for your test
5+
6+
family: aurora-postgresql12
7+
engine: 12.10
8+
9+
cloudwatch_log_exports:
10+
- postgresql

0 commit comments

Comments
 (0)