Create Public and Private VPC With VPC Flow Logs Using Cloudformation
In this blog we will learn how to add true/false option in cloudformation to configure VPC flow logs.
Note: To learn basic of cloudformation, please check our old blog: Click me
Main Script:
This script will create a VPC, 3 private subnet, 3 public subnet, enable VPC flow logs(Optional), NAT gateway for private instances, IGW for public and custom Route tables.
1
2{
3 "AWSTemplateFormatVersion": "2010-09-09",
4 "Description" : "Create 3 private subnet for APP and 3 Public subnet for WEB with New VPC and VPC Flow Logs enabler",
5
6"Parameters": {
7 "myVPCcidr": {
8 "Description": "Enter VPC CIDR",
9 "Type": "String",
10 "MinLength": "9",
11 "MaxLength": "18",
12 "Default": "10.10.0.0/16",
13 "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
14 "ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x."
15 },
16 "myVPCName":{
17 "Description":"Enter the name of Your VPC",
18 "Type":"String",
19 "ConstraintDescription": "This name is will assign to Name tag"
20 },
21 "myPrivateSubnet1" : {
22 "Description": "Enter your APP private subnet 1 CIDR here",
23 "Type": "String",
24 "MinLength": "9",
25 "MaxLength": "18",
26 "Default": "10.10.1.0/24",
27 "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
28 "ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x."
29 },
30 "myPrivateSubnet1Name":{
31 "Description":"Enter the name of 1st App Private Subnet name",
32 "Type":"String"
33 },
34 "myPrivateSubnet1AZ" : {
35
36 "Description":"Select the AZ in which you want to create the subnet:",
37 "Type": "AWS::EC2::AvailabilityZone::Name"
38
39 },
40
41 "myPrivateSubnet2" : {
42 "Description": "Enter your APP subnet 2 CIDR here",
43 "Type": "String",
44 "MinLength": "9",
45 "MaxLength": "18",
46 "Default": "10.10.2.0/24",
47 "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
48 "ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x."
49
50
51 },
52 "myPrivateSubnet2Name":{
53 "Description":"Enter the name of 2nd APP Private Subnet name",
54 "Type":"String"
55 },
56 "myPrivateSubnet2AZ" : {
57
58 "Description":"Select the AZ in which you want to create the subnet:",
59 "Type": "AWS::EC2::AvailabilityZone::Name"
60
61 },
62
63
64 "myPrivateSubnet3" : {
65 "Description": "Enter your APP subnet 3 CIDR here",
66 "Type": "String",
67 "MinLength": "9",
68 "MaxLength": "18",
69 "Default": "10.10.3.0/24",
70 "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
71 "ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x."
72
73 },
74 "myPrivateSubnet3Name":{
75 "Description":"Enter the name of 3rd APP Private Subnet name",
76 "Type":"String"
77 },
78 "myPrivateSubnet3AZ" : {
79
80 "Description":"Select the AZ in which you want to create the subnet:",
81 "Type": "AWS::EC2::AvailabilityZone::Name"
82
83 },
84
85
86 "myPublicSubnet1" : {
87 "Description": "Enter your public Web subnet 1 CIDR here",
88 "Type": "String",
89 "MinLength": "9",
90 "MaxLength": "18",
91 "Default": "10.10.7.0/24",
92 "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
93 "ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x."
94
95 },
96 "myPublicSubnet1Name":{
97 "Description":"Enter the name of 1st Web Public Subnet name",
98 "Type":"String"
99 },
100 "myPublicSubnet1AZ" : {
101
102 "Description":"Select the AZ in which you want to create the subnet:",
103 "Type": "AWS::EC2::AvailabilityZone::Name"
104
105 },
106
107
108 "myPublicSubnet2" : {
109 "Description": "Enter your Public Web subnet 2 CIDR here",
110 "Type": "String",
111 "MinLength": "9",
112 "MaxLength": "18",
113 "Default": "10.10.8.0/24",
114 "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
115 "ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x."
116 },
117 "myPublicSubnet2Name":{
118 "Description":"Enter the name of 2nd Public Subnet name",
119 "Type":"String"
120 },
121 "myPublicSubnet2AZ" : {
122
123 "Description":"Select the AZ in which you want to create the subnet:",
124 "Type": "AWS::EC2::AvailabilityZone::Name"
125
126 },
127
128
129 "myPublicSubnet3" : {
130 "Description": "Enter your Public subnet 3 CIDR here",
131 "Type": "String",
132 "MinLength": "9",
133 "MaxLength": "18",
134 "Default": "10.10.9.0/24",
135 "AllowedPattern": "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})",
136 "ConstraintDescription": "must be a valid IP CIDR range of the form x.x.x.x/x."
137 },
138 "myPublicSubnet3Name":{
139 "Description":"Enter the name of 3rd Public Subnet name",
140 "Type":"String"
141 },
142 "myPublicSubnet3AZ" : {
143
144 "Description":"Select the AZ in which you want to create the subnet:",
145 "Type": "AWS::EC2::AvailabilityZone::Name"
146
147 },
148
149
150"myPrivateRouteName":{
151 "Description":"Enter the name of Private RouteTable ",
152 "Type":"String"
153 },
154"myPublicRouteName":{
155 "Description":"Enter the name of Public RouteTable name",
156 "Type":"String"
157 },
158"myIGWName":{
159 "Description":"Enter the name of IGW",
160 "Type":"String"
161 },
162"myNATName":{
163 "Description":"Enter the name of Private RouteTable",
164 "Type":"String"
165 },
166"myNATEIPName":{
167 "Description":"Enter the name of NAT EIP",
168 "Type":"String"
169 },
170
171
172"ApplicationTagName" : {
173 "Description":"Enter the name of Application Name",
174 "Type":"String"
175 },
176"ApplicationVersionName" : {
177 "Description":"Enter the name of Application Version",
178 "Type":"String"
179 },
180 "EnableVPCFlow" : {
181 "Description": "Whether you want to enable VPC Flow logs.",
182 "Default" : "false",
183 "Type" : "String",
184 "AllowedValues" : ["true", "false"]
185 }
186
187
188},
189"Conditions" : {
190 "createVPCFlow" : {"Fn::Equals" : [{"Ref" : "EnableVPCFlow"}, "true"]}
191 },
192"Metadata" : {
193 "AWS::CloudFormation::Interface" : {
194 "ParameterGroups" : [
195 {
196 "Label" : { "default" : "VPC Details" },
197 "Parameters" : [ "myVPCcidr","myVPCName" ]
198 },
199 {
200 "Label" : { "default" : "Private Private Subnet 1 Details" },
201 "Parameters" : [ "myPrivateSubnet1","myPrivateSubnet1AZ","myPrivateSubnet1Name" ]
202 },
203 {
204 "Label" : { "default" : "Private private Subnet 2 Details" },
205 "Parameters" : [ "myPrivateSubnet2","myPrivateSubnet2AZ","myPrivateSubnet2Name" ]
206 },
207 {
208 "Label" : { "default" : "Private Private Subnet 3 Details" },
209 "Parameters" : [ "myPrivateSubnet3","myPrivateSubnet3AZ","myPrivateSubnet3Name" ]
210 },
211 {
212 "Label" : { "default" : "Public Public Subnet 1 Details" },
213 "Parameters" : [ "myPublicSubnet1","myPublicSubnet1AZ","myPublicSubnet1Name" ]
214 },
215 {
216 "Label" : { "default" : "Public Public Subnet 2 Details" },
217 "Parameters" : [ "myPublicSubnet2","myPublicSubnet2AZ","myPublicSubnet2Name" ]
218 },
219 {
220 "Label" : { "default" : "Public Public Subnet 3 Details" },
221 "Parameters" : [ "myPublicSubnet3","myPublicSubnet3AZ","myPublicSubnet3Name" ]
222 },
223 {
224 "Label" : { "default" : "Add All Tags Details" },
225 "Parameters" : [ "ApplicationTagName","ApplicationVersionName"]
226 },
227 {
228 "Label" : { "default" : "Add All Nat Gateway Tags Details" },
229 "Parameters" : [ "myNATEIPName","myNATName" ]
230 },
231 {
232 "Label" : { "default" : "Add All Route Table Tags Details" },
233 "Parameters" : [ "myPrivateRouteName","myPublicRouteName"]
234 },
235 {
236 "Label" : { "default" : "Add IGW Tags Details" },
237 "Parameters" : [ "myIGWName"]
238 }
239 ]
240
241 }
242 },
243"Resources" : {
244 "myVPC" : {
245 "Type" : "AWS::EC2::VPC",
246 "Properties" : {
247 "CidrBlock" : { "Ref" : "myVPCcidr" },
248 "EnableDnsSupport" : "true",
249 "EnableDnsHostnames" : "true",
250 "InstanceTenancy" : "default",
251 "Tags" : [ {"Key" : "Name", "Value" : { "Ref" : "myVPCName" }} ]
252 }
253 },
254 "myAWSVPCsubnet1": {
255 "Type": "AWS::EC2::Subnet",
256 "Properties": {
257 "VpcId": {
258 "Ref": "myVPC"
259 },
260 "CidrBlock": { "Ref" : "myPrivateSubnet1" },
261 "AvailabilityZone": { "Ref" : "myPrivateSubnet1AZ" },
262 "Tags": [{
263 "Key": "Name",
264 "Value": { "Ref" : "myPrivateSubnet1Name" }
265 },
266 {
267 "Key": "appname",
268 "Value": { "Ref" : "ApplicationTagName" }
269 },
270 {
271 "Key": "appversion",
272 "Value": { "Ref" : "ApplicationVersionName" }
273 }
274 ]
275 }
276 },
277 "myAWSVPCsubnet2": {
278 "Type": "AWS::EC2::Subnet",
279 "Properties": {
280 "VpcId": {
281 "Ref": "myVPC"
282 },
283 "CidrBlock": { "Ref" : "myPrivateSubnet2" },
284 "AvailabilityZone": { "Ref" : "myPrivateSubnet2AZ" },
285 "Tags": [{
286 "Key": "Name",
287 "Value": { "Ref" : "myPrivateSubnet2Name" }
288 },
289 {
290 "Key": "appname",
291 "Value": { "Ref" : "ApplicationTagName" }
292 },
293 {
294 "Key": "appversion",
295 "Value": { "Ref" : "ApplicationVersionName" }
296 }]
297 }
298 },
299 "myAWSVPCsubnet3": {
300 "Type": "AWS::EC2::Subnet",
301 "Properties": {
302 "VpcId": {
303 "Ref": "myVPC"
304 },
305 "CidrBlock": { "Ref" : "myPrivateSubnet3" },
306 "AvailabilityZone": { "Ref" : "myPrivateSubnet3AZ" },
307 "Tags": [{
308 "Key": "Name",
309 "Value": { "Ref" : "myPrivateSubnet3Name" }
310 },
311 {
312 "Key": "appname",
313 "Value": { "Ref" : "ApplicationTagName" }
314 },
315 {
316 "Key": "appversion",
317 "Value": { "Ref" : "ApplicationVersionName" }
318 }]
319 }
320 },
321 "myAWSVPCsubnet7": {
322 "Type": "AWS::EC2::Subnet",
323 "Properties": {
324 "VpcId": {
325 "Ref": "myVPC"
326 },
327 "CidrBlock": { "Ref" : "myPublicSubnet1" },
328 "AvailabilityZone": { "Ref" : "myPublicSubnet1AZ" },
329 "Tags": [{
330 "Key": "Name",
331 "Value": { "Ref" : "myPublicSubnet1Name" }
332 },
333 {
334 "Key": "appname",
335 "Value": { "Ref" : "ApplicationTagName" }
336 },
337 {
338 "Key": "appversion",
339 "Value": { "Ref" : "ApplicationVersionName" }
340 }]
341 }
342 },
343 "myAWSVPCsubnet8": {
344 "Type": "AWS::EC2::Subnet",
345 "Properties": {
346 "VpcId": {
347 "Ref": "myVPC"
348 },
349 "CidrBlock": { "Ref" : "myPublicSubnet2" },
350 "AvailabilityZone": { "Ref" : "myPublicSubnet2AZ" },
351 "Tags": [{
352 "Key": "Name",
353 "Value": { "Ref" : "myPublicSubnet2Name" }
354 },
355 {
356 "Key": "appname",
357 "Value": { "Ref" : "ApplicationTagName" }
358 },
359 {
360 "Key": "appversion",
361 "Value": { "Ref" : "ApplicationVersionName" }
362 }]
363 }
364 },
365 "myAWSVPCsubnet9": {
366 "Type": "AWS::EC2::Subnet",
367 "Properties": {
368 "VpcId": {
369 "Ref": "myVPC"
370 },
371 "CidrBlock": { "Ref" : "myPublicSubnet3" },
372 "AvailabilityZone": { "Ref" : "myPublicSubnet3AZ" },
373 "Tags": [{
374 "Key": "Name",
375 "Value": { "Ref" : "myPublicSubnet3Name" }
376 },
377 {
378 "Key": "appname",
379 "Value": { "Ref" : "ApplicationTagName" }
380 },
381 {
382 "Key": "appversion",
383 "Value": { "Ref" : "ApplicationVersionName" }
384 }]
385 }
386 },
387 "myVPCpublicRoute" : {
388 "Type" : "AWS::EC2::RouteTable",
389 "Properties" : {
390 "VpcId" : { "Ref" : "myVPC" },
391 "Tags" : [ { "Key" : "Name", "Value" : { "Ref" : "myPublicRouteName" } },
392 {
393 "Key": "appname",
394 "Value": { "Ref" : "ApplicationTagName" }
395 },
396 {
397 "Key": "appversion",
398 "Value": { "Ref" : "ApplicationVersionName" }
399 }]
400 }
401 },
402 "myVPCprivateRoute" : {
403 "Type" : "AWS::EC2::RouteTable",
404 "Properties" : {
405 "VpcId" : { "Ref" : "myVPC" },
406 "Tags" : [ { "Key" : "Name", "Value" : { "Ref" : "myPrivateRouteName" } },
407 {
408 "Key": "appname",
409 "Value": { "Ref" : "ApplicationTagName" }
410 },
411 {
412 "Key": "appversion",
413 "Value": { "Ref" : "ApplicationVersionName" }
414 } ]
415 }
416 },
417 "PublicSubnet1RouteTableAssociation" : {
418 "Type" : "AWS::EC2::SubnetRouteTableAssociation",
419 "Properties" : {
420 "SubnetId" : { "Ref" : "myAWSVPCsubnet7" },
421 "RouteTableId" : { "Ref" : "myVPCpublicRoute" }
422 }
423 },
424 "PublicSubnet2RouteTableAssociation" : {
425 "Type" : "AWS::EC2::SubnetRouteTableAssociation",
426 "Properties" : {
427 "SubnetId" : { "Ref" : "myAWSVPCsubnet8" },
428 "RouteTableId" : { "Ref" : "myVPCpublicRoute" }
429 }
430 },
431 "PublicSubnet3RouteTableAssociation" : {
432 "Type" : "AWS::EC2::SubnetRouteTableAssociation",
433 "Properties" : {
434 "SubnetId" : { "Ref" : "myAWSVPCsubnet9" },
435 "RouteTableId" : { "Ref" : "myVPCpublicRoute" }
436 }
437 },
438 "PrivateSubnet1RouteTableAssociation" : {
439 "Type" : "AWS::EC2::SubnetRouteTableAssociation",
440 "Properties" : {
441 "SubnetId" : { "Ref" : "myAWSVPCsubnet1"},
442 "RouteTableId" : { "Ref" : "myVPCprivateRoute" }
443 }
444 },
445 "PrivateSubnet2RouteTableAssociation" : {
446 "Type" : "AWS::EC2::SubnetRouteTableAssociation",
447 "Properties" : {
448 "SubnetId" : { "Ref" : "myAWSVPCsubnet2"},
449 "RouteTableId" : { "Ref" : "myVPCprivateRoute" }
450 }
451 },
452 "PrivateSubnet3RouteTableAssociation" : {
453 "Type" : "AWS::EC2::SubnetRouteTableAssociation",
454 "Properties" : {
455 "SubnetId" : { "Ref" : "myAWSVPCsubnet3"},
456 "RouteTableId" : { "Ref" : "myVPCprivateRoute" }
457 }
458 },
459 "myInternetGateway" : {
460 "Type" : "AWS::EC2::InternetGateway",
461 "Properties" : {
462 "Tags" : [ {"Key" : "Name", "Value" : { "Ref" : "myIGWName" }}]
463 }
464 },
465 "AttachIGWGateway" : {
466 "Type" : "AWS::EC2::VPCGatewayAttachment",
467 "Properties" : {
468 "VpcId" : { "Ref" : "myVPC" },
469 "InternetGatewayId" : { "Ref" : "myInternetGateway" }
470 }
471 },
472 "AttachedtoPublicRoute" : {
473 "Type" : "AWS::EC2::Route",
474 "DependsOn" : "myInternetGateway",
475 "Properties" : {
476 "RouteTableId" : { "Ref" : "myVPCpublicRoute" },
477 "DestinationCidrBlock" : "0.0.0.0/0",
478 "GatewayId" : { "Ref" : "myInternetGateway" }
479 }
480 },
481 "myAWSVPCNAT" : {
482 "Type" : "AWS::EC2::NatGateway",
483 "Properties" : {
484 "AllocationId" : { "Fn::GetAtt" : ["EIP", "AllocationId"]},
485 "SubnetId" : { "Ref" : "myAWSVPCsubnet7"},
486 "Tags" : [ {"Key" : "Name", "Value" : { "Ref" : "myNATName" } },
487 {
488 "Key": "appname",
489 "Value": { "Ref" : "ApplicationTagName" }
490 },
491 {
492 "Key": "appversion",
493 "Value": { "Ref" : "ApplicationVersionName" }
494 } ]
495 }
496 },
497 "EIP" : {
498 "Type" : "AWS::EC2::EIP",
499 "Properties" : {
500 "Domain" : "vpc",
501 "Tags" : [ {"Key" : "Name", "Value" : { "Ref" : "myNATEIPName" } },
502 {
503 "Key": "appname",
504 "Value": { "Ref" : "ApplicationTagName" }
505 },
506 {
507 "Key": "appversion",
508 "Value": { "Ref" : "ApplicationVersionName" }
509 } ]
510 }
511 },
512 "AttachNATtoPrivateRoute" : {
513 "Type" : "AWS::EC2::Route",
514 "Properties" : {
515 "RouteTableId" : { "Ref" : "myVPCprivateRoute" },
516 "DestinationCidrBlock" : "0.0.0.0/0",
517 "NatGatewayId" : { "Ref" : "myAWSVPCNAT" }
518 }
519 },
520
521 "VPCFlowRole": {
522 "Type": "AWS::IAM::Role",
523 "Condition": "createVPCFlow",
524 "Properties": {
525 "AssumeRolePolicyDocument": {
526 "Version": "2012-10-17",
527 "Statement": [
528 {
529 "Effect": "Allow",
530 "Principal": {
531 "Service": "vpc-flow-logs.amazonaws.com"
532 },
533 "Action": "sts:AssumeRole"
534 }
535 ]
536 },
537 "Policies": [
538 {
539 "PolicyName": "flowlogs-policy",
540 "PolicyDocument": {
541 "Version": "2012-10-17",
542 "Statement": [
543 {
544 "Effect": "Allow",
545 "Action": [
546 "logs:CreateLogStream",
547 "logs:PutLogEvents",
548 "logs:DescribeLogGroups",
549 "logs:DescribeLogStreams"
550 ],
551 "Resource": {
552 "Fn::GetAtt": [
553 "VPCLogGroup",
554 "Arn"
555 ]
556 }
557 }
558 ]
559 }
560 }
561 ]
562 }
563 },
564 "VPCLogGroup": {
565 "Type": "AWS::Logs::LogGroup",
566 "Condition": "createVPCFlow",
567 "Properties": {
568 "LogGroupName" : { "Fn::Join" : [ "-", [ {
569 "Ref": "myVPCName"
570 },"FlowLogsGroup" ] ]
571 }
572 }
573 },
574 "FlowLog": {
575 "Type": "AWS::EC2::FlowLog",
576 "Condition": "createVPCFlow",
577 "Properties": {
578 "DeliverLogsPermissionArn": {
579 "Fn::GetAtt": [
580 "VPCFlowRole",
581 "Arn"
582 ]
583 },
584 "LogGroupName": { "Fn::Join" : [ "-", [ {
585 "Ref": "myVPCName"
586 },"FlowLogsGroup" ] ]
587 },
588 "ResourceId": {
589 "Ref": "myVPC"
590 },
591 "ResourceType": "VPC",
592 "TrafficType": "ALL"
593 }
594 }
595}
596}
Use above script and share your feedback. We love to hear your thoughts and if you need any new script, please let us know.