magic-pocket-cli 0.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. magic_pocket_cli-0.2.0.dist-info/METADATA +14 -0
  2. magic_pocket_cli-0.2.0.dist-info/RECORD +65 -0
  3. magic_pocket_cli-0.2.0.dist-info/WHEEL +4 -0
  4. magic_pocket_cli-0.2.0.dist-info/entry_points.txt +2 -0
  5. pocket_cli/__init__.py +0 -0
  6. pocket_cli/cli/__init__.py +0 -0
  7. pocket_cli/cli/aws_auth.py +48 -0
  8. pocket_cli/cli/awscontainer_cli.py +328 -0
  9. pocket_cli/cli/cloudfront_cli.py +116 -0
  10. pocket_cli/cli/cloudfront_keys_cli.py +68 -0
  11. pocket_cli/cli/cloudfront_waf_cli.py +68 -0
  12. pocket_cli/cli/deploy_cli.py +274 -0
  13. pocket_cli/cli/destroy_cli.py +358 -0
  14. pocket_cli/cli/dsql_cli.py +60 -0
  15. pocket_cli/cli/main_cli.py +91 -0
  16. pocket_cli/cli/migrate_cli.py +148 -0
  17. pocket_cli/cli/neon_cli.py +97 -0
  18. pocket_cli/cli/permissions_cli.py +46 -0
  19. pocket_cli/cli/rds_cli.py +63 -0
  20. pocket_cli/cli/runtime_config_cli.py +185 -0
  21. pocket_cli/cli/s3_cli.py +69 -0
  22. pocket_cli/cli/status_cli.py +56 -0
  23. pocket_cli/cli/tidb_cli.py +73 -0
  24. pocket_cli/cli/vpc_cli.py +92 -0
  25. pocket_cli/cli/waf_cli.py +182 -0
  26. pocket_cli/django_cli.py +412 -0
  27. pocket_cli/mediator.py +220 -0
  28. pocket_cli/resources/__init__.py +0 -0
  29. pocket_cli/resources/aws/__init__.py +0 -0
  30. pocket_cli/resources/aws/builders/__init__.py +57 -0
  31. pocket_cli/resources/aws/builders/codebuild.py +363 -0
  32. pocket_cli/resources/aws/builders/depot.py +84 -0
  33. pocket_cli/resources/aws/builders/docker.py +34 -0
  34. pocket_cli/resources/aws/builders/dockerignore.py +44 -0
  35. pocket_cli/resources/aws/cloudformation.py +790 -0
  36. pocket_cli/resources/aws/ecr.py +145 -0
  37. pocket_cli/resources/aws/efs.py +138 -0
  38. pocket_cli/resources/aws/lambdahandler.py +182 -0
  39. pocket_cli/resources/aws/s3_utils.py +58 -0
  40. pocket_cli/resources/aws/state.py +74 -0
  41. pocket_cli/resources/awscontainer.py +265 -0
  42. pocket_cli/resources/cloudfront.py +491 -0
  43. pocket_cli/resources/cloudfront_acm.py +55 -0
  44. pocket_cli/resources/cloudfront_keys.py +81 -0
  45. pocket_cli/resources/cloudfront_waf.py +67 -0
  46. pocket_cli/resources/dsql.py +142 -0
  47. pocket_cli/resources/neon.py +353 -0
  48. pocket_cli/resources/rds.py +680 -0
  49. pocket_cli/resources/s3.py +307 -0
  50. pocket_cli/resources/tidb.py +298 -0
  51. pocket_cli/resources/upstash.py +152 -0
  52. pocket_cli/resources/vpc.py +67 -0
  53. pocket_cli/templates/cloudformation/awscontainer.yaml +516 -0
  54. pocket_cli/templates/cloudformation/cf_function_api_host.js +5 -0
  55. pocket_cli/templates/cloudformation/cf_function_spa_auth.js +28 -0
  56. pocket_cli/templates/cloudformation/cf_function_spa_fallback.js +8 -0
  57. pocket_cli/templates/cloudformation/cloudfront.yaml +309 -0
  58. pocket_cli/templates/cloudformation/cloudfront_acm.yaml +43 -0
  59. pocket_cli/templates/cloudformation/cloudfront_keys.yaml +32 -0
  60. pocket_cli/templates/cloudformation/cloudfront_waf.yaml +97 -0
  61. pocket_cli/templates/cloudformation/vpc.yaml +213 -0
  62. pocket_cli/templates/init/django-dotenv.env +3 -0
  63. pocket_cli/templates/init/django-settings.py +140 -0
  64. pocket_cli/templates/init/pocket.Dockerfile +26 -0
  65. pocket_cli/templates/init/pocket_simple.toml +31 -0
@@ -0,0 +1,309 @@
1
+ AWSTemplateFormatVersion: "2010-09-09"
2
+ Description: spa configuration for webapp
3
+
4
+ Resources:
5
+ OriginAccessControl:
6
+ Type: AWS::CloudFront::OriginAccessControl
7
+ Properties:
8
+ OriginAccessControlConfig:
9
+ Name: "{{ slug }}-oac"
10
+ OriginAccessControlOriginType: s3
11
+ SigningBehavior: always
12
+ SigningProtocol: sigv4
13
+
14
+ # {% if has_token_kvs %}
15
+ TokenKvs:
16
+ Type: AWS::CloudFront::KeyValueStore
17
+ Properties:
18
+ Name: "{{ slug }}-token-kvs"
19
+ Comment: "KVS for SPA token secret"
20
+ # {% endif %}
21
+
22
+ # {% for route in routes %}
23
+ # {% if route.is_spa %}
24
+ UrlFallbackFunction{{ route.yaml_key }}:
25
+ Type: AWS::CloudFront::Function
26
+ Properties:
27
+ Name: "{{ slug }}-{{ route.name }}-fallback"
28
+ AutoPublish: true
29
+ # {% if route.require_token %}
30
+ FunctionCode:
31
+ Fn::Sub:
32
+ - |
33
+ {{ function_codes[route.yaml_key] }}
34
+ - TokenKvs:
35
+ Fn::GetAtt: TokenKvs.Id
36
+ # {% else %}
37
+ FunctionCode: |
38
+ {{ function_codes[route.yaml_key] }}
39
+ # {% endif %}
40
+ FunctionConfig:
41
+ Comment: "CloudFront function for {{ route.name }}"
42
+ Runtime: cloudfront-js-2.0
43
+ # {% if route.require_token %}
44
+ KeyValueStoreAssociations:
45
+ - KeyValueStoreARN:
46
+ Fn::GetAtt: TokenKvs.Arn
47
+ # {% endif %}
48
+ # {% endif %}
49
+ # {% if route.versioning %}
50
+ ResponseHeadersPolicy{{ route.yaml_key }}:
51
+ Type: AWS::CloudFront::ResponseHeadersPolicy
52
+ Properties:
53
+ ResponseHeadersPolicyConfig:
54
+ Name: "{{ slug }}-{{ route.name }}-headers"
55
+ CustomHeadersConfig:
56
+ Items:
57
+ - Header: "cache-control"
58
+ Value: "public, max-age={{ route.versioned_max_age }}, immutable"
59
+ Override: true
60
+ # {% endif %}
61
+ # {% if route.is_deploy_hash %}
62
+ DeployHashStripFunction{{ route.yaml_key }}:
63
+ Type: AWS::CloudFront::Function
64
+ Properties:
65
+ Name: "{{ slug }}-{{ route.name }}-deploy-hash-strip"
66
+ AutoPublish: true
67
+ FunctionCode: |
68
+ {{ deploy_hash_function_codes[route.yaml_key] }}
69
+ FunctionConfig:
70
+ Comment: "Strip deploy hash prefix for {{ route.name }}"
71
+ Runtime: cloudfront-js-2.0
72
+ # {% endif %}
73
+ # {% endfor %}
74
+
75
+ # {% if has_lambda_route %}
76
+ ApiHostFunction:
77
+ Type: AWS::CloudFront::Function
78
+ Properties:
79
+ Name: "{{ slug }}-api-host"
80
+ AutoPublish: true
81
+ FunctionCode: |
82
+ {{ api_host_function_code }}
83
+ FunctionConfig:
84
+ Comment: "Add X-Forwarded-Host for API routes"
85
+ Runtime: cloudfront-js-2.0
86
+ # {% endif %}
87
+
88
+ CloudFrontDistribution:
89
+ Type: AWS::CloudFront::Distribution
90
+ DependsOn:
91
+ - OriginAccessControl
92
+ # {% for route in routes %}
93
+ # {% if route.is_spa %}
94
+ - UrlFallbackFunction{{ route.yaml_key }}
95
+ # {% endif %}
96
+ # {% if route.versioning %}
97
+ - ResponseHeadersPolicy{{ route.yaml_key }}
98
+ # {% endif %}
99
+ # {% if route.is_deploy_hash %}
100
+ - DeployHashStripFunction{{ route.yaml_key }}
101
+ # {% endif %}
102
+ # {% endfor %}
103
+ # {% if has_lambda_route %}
104
+ - ApiHostFunction
105
+ # {% endif %}
106
+ Properties:
107
+ DistributionConfig:
108
+ # {% if domain %}
109
+ Aliases:
110
+ - "{{ domain }}"
111
+ # {% endif %}
112
+ Enabled: true
113
+ Origins:
114
+ # {% for route in routes %}
115
+ # {% if not route.is_lambda %}
116
+ - Id: "{{ resource_prefix }}{{ route.name }}"
117
+ DomainName: "{{ bucket_name }}.s3.{{ s3_region }}.amazonaws.com"
118
+ OriginPath: "{{ route.origin_path }}"
119
+ OriginAccessControlId:
120
+ Fn::GetAtt: OriginAccessControl.Id
121
+ S3OriginConfig:
122
+ OriginAccessIdentity: "" # Leave this blank because we use OAC(Origin Access Control)
123
+ # {% endif %}
124
+ # {% endfor %}
125
+ # {% for handler_key, export_name in api_origins.items() %}
126
+ - Id: "{{ resource_prefix }}api-{{ handler_key }}"
127
+ DomainName:
128
+ Fn::ImportValue: "{{ export_name }}"
129
+ CustomOriginConfig:
130
+ OriginProtocolPolicy: https-only
131
+ HTTPSPort: 443
132
+ # {% endfor %}
133
+ # {% if managed_asset_files %}
134
+ - Id: "{{ resource_prefix }}pocket-managed"
135
+ DomainName: "{{ bucket_name }}.s3.{{ s3_region }}.amazonaws.com"
136
+ OriginPath: "/pocket_managed"
137
+ OriginAccessControlId:
138
+ Fn::GetAtt: OriginAccessControl.Id
139
+ S3OriginConfig:
140
+ OriginAccessIdentity: ""
141
+ # {% endif %}
142
+ # {% if default_route.is_lambda %}
143
+ DefaultCacheBehavior:
144
+ CachePolicyId: "4135ea2d-6df8-44a3-9df3-4b5a84be39ad" # Managed-CachingDisabled
145
+ OriginRequestPolicyId: "b689b0a8-53d0-40ab-baf2-68738e2966ac" # Managed-AllViewerExceptHostHeader
146
+ TargetOriginId: "{{ resource_prefix }}api-{{ default_route.handler }}"
147
+ ViewerProtocolPolicy: "redirect-to-https"
148
+ FunctionAssociations:
149
+ - EventType: viewer-request
150
+ FunctionARN:
151
+ Fn::GetAtt: ApiHostFunction.FunctionMetadata.FunctionARN
152
+ AllowedMethods:
153
+ - GET
154
+ - HEAD
155
+ - OPTIONS
156
+ - PUT
157
+ - PATCH
158
+ - POST
159
+ - DELETE
160
+ # {% else %}
161
+ DefaultCacheBehavior:
162
+ CachePolicyId: "658327ea-f89d-4fab-a63d-7e88639e58f6" # Managed-CachingOptimized
163
+ TargetOriginId: "{{ resource_prefix }}{{ default_route.name }}"
164
+ ViewerProtocolPolicy: "redirect-to-https"
165
+ # {% if default_route.is_spa %}
166
+ FunctionAssociations:
167
+ - EventType: viewer-request
168
+ FunctionARN:
169
+ Fn::GetAtt: UrlFallbackFunction{{ default_route.yaml_key }}.FunctionMetadata.FunctionARN
170
+ # {% endif %}
171
+ # {% if default_route.versioning %}
172
+ ResponseHeadersPolicyId:
173
+ Ref: ResponseHeadersPolicy{{ default_route.yaml_key }}
174
+ # {% endif %}
175
+ # {% if default_route.signed and signing_key %}
176
+ TrustedKeyGroups:
177
+ - Fn::ImportValue: "{{ export.key_group_id }}"
178
+ # {% endif %}
179
+ # {% endif %}
180
+ # {% if extra_s3_routes or extra_lambda_routes or managed_asset_files %}
181
+ CacheBehaviors:
182
+ # {% for route in extra_s3_routes %}
183
+ - CachePolicyId: "658327ea-f89d-4fab-a63d-7e88639e58f6" # Managed-CachingOptimized
184
+ TargetOriginId: "{{ resource_prefix }}{{ route.name }}"
185
+ ViewerProtocolPolicy: "redirect-to-https"
186
+ PathPattern: "{{ route.path_pattern }}"
187
+ # {% if route.is_spa %}
188
+ FunctionAssociations:
189
+ - EventType: viewer-request
190
+ FunctionARN:
191
+ Fn::GetAtt: UrlFallbackFunction{{ route.yaml_key }}.FunctionMetadata.FunctionARN
192
+ # {% endif %}
193
+ # {% if route.is_deploy_hash %}
194
+ FunctionAssociations:
195
+ - EventType: viewer-request
196
+ FunctionARN:
197
+ Fn::GetAtt: DeployHashStripFunction{{ route.yaml_key }}.FunctionMetadata.FunctionARN
198
+ # {% endif %}
199
+ # {% if route.versioning %}
200
+ ResponseHeadersPolicyId:
201
+ Ref: ResponseHeadersPolicy{{ route.yaml_key }}
202
+ # {% endif %}
203
+ # {% if route.signed and signing_key %}
204
+ TrustedKeyGroups:
205
+ - Fn::ImportValue: "{{ export.key_group_id }}"
206
+ # {% endif %}
207
+ # {% endfor %}
208
+ # {% for route in extra_lambda_routes %}
209
+ - CachePolicyId: "4135ea2d-6df8-44a3-9df3-4b5a84be39ad" # Managed-CachingDisabled
210
+ OriginRequestPolicyId: "b689b0a8-53d0-40ab-baf2-68738e2966ac" # Managed-AllViewerExceptHostHeader
211
+ TargetOriginId: "{{ resource_prefix }}api-{{ route.handler }}"
212
+ ViewerProtocolPolicy: "redirect-to-https"
213
+ PathPattern: "{{ route.path_pattern }}"
214
+ FunctionAssociations:
215
+ - EventType: viewer-request
216
+ FunctionARN:
217
+ Fn::GetAtt: ApiHostFunction.FunctionMetadata.FunctionARN
218
+ AllowedMethods:
219
+ - GET
220
+ - HEAD
221
+ - OPTIONS
222
+ - PUT
223
+ - PATCH
224
+ - POST
225
+ - DELETE
226
+ # {% endfor %}
227
+ # {% for filename in managed_asset_files %}
228
+ - CachePolicyId: "658327ea-f89d-4fab-a63d-7e88639e58f6" # Managed-CachingOptimized
229
+ TargetOriginId: "{{ resource_prefix }}pocket-managed"
230
+ ViewerProtocolPolicy: "redirect-to-https"
231
+ PathPattern: "/{{ filename }}"
232
+ # {% endfor %}
233
+ # {% endif %}
234
+ ViewerCertificate:
235
+ # {% if acm_certificate_arn %}
236
+ AcmCertificateArn: "{{ acm_certificate_arn }}"
237
+ SslSupportMethod: sni-only
238
+ # {% else %}
239
+ CloudFrontDefaultCertificate: true
240
+ # {% endif %}
241
+ # {% if waf_acl_arn %}
242
+ WebACLId: "{{ waf_acl_arn }}"
243
+ # {% endif %}
244
+
245
+ # {% if domain %}
246
+ DNSRecord:
247
+ Type: AWS::Route53::RecordSet
248
+ DependsOn:
249
+ - CloudFrontDistribution
250
+ Properties:
251
+ HostedZoneId: "{{ hosted_zone_id }}"
252
+ Name: "{{ domain }}"
253
+ Type: A
254
+ AliasTarget:
255
+ HostedZoneId: Z2FDTNDATAQYW2 # Z2FDTNDATAQYW2 is the fixed hosted zone id for cloudfront
256
+ DNSName:
257
+ Fn::GetAtt: CloudFrontDistribution.DomainName
258
+ # {% endif %}
259
+
260
+ # {% for rf in redirect_from %}
261
+ "CloudFrontDistribution{{ rf.yaml_key }}":
262
+ Type: AWS::CloudFront::Distribution
263
+ Properties:
264
+ DistributionConfig:
265
+ Aliases:
266
+ - "{{ rf.domain }}"
267
+ Enabled: true
268
+ Origins:
269
+ - Id: "redirect-from"
270
+ DomainName:
271
+ Fn::Sub: "{{ rf.bucket_website_domain }}"
272
+ CustomOriginConfig:
273
+ OriginProtocolPolicy: http-only
274
+ DefaultCacheBehavior:
275
+ CachePolicyId: "4135ea2d-6df8-44a3-9df3-4b5a84be39ad" # Managed-CachingDisabled
276
+ TargetOriginId: "redirect-from"
277
+ ViewerProtocolPolicy: "redirect-to-https"
278
+ ViewerCertificate:
279
+ AcmCertificateArn: "{{ acm_redirect_arns[rf.yaml_key] }}"
280
+ SslSupportMethod: sni-only
281
+
282
+ "DNSRecord{{ rf.yaml_key }}":
283
+ Type: AWS::Route53::RecordSet
284
+ DependsOn:
285
+ - "CloudFrontDistribution{{ rf.yaml_key }}"
286
+ Properties:
287
+ HostedZoneId: "{{ hosted_zone_id }}"
288
+ Name: "{{ rf.domain }}"
289
+ Type: A
290
+ AliasTarget:
291
+ HostedZoneId: Z2FDTNDATAQYW2 # Z2FDTNDATAQYW2 is the fixed hosted zone id for cloudfront
292
+ DNSName:
293
+ Fn::GetAtt: "CloudFrontDistribution{{ rf.yaml_key }}.DomainName"
294
+ # {% endfor %}
295
+
296
+ Outputs:
297
+ DistributionId:
298
+ Value:
299
+ Ref: CloudFrontDistribution
300
+ DistributionDomainName:
301
+ Value:
302
+ Fn::GetAtt: CloudFrontDistribution.DomainName
303
+ # {% if has_token_kvs %}
304
+ TokenKvsArn:
305
+ Value:
306
+ Fn::GetAtt: TokenKvs.Arn
307
+ Export:
308
+ Name: "{{ export.kvs_arn }}"
309
+ # {% endif %}
@@ -0,0 +1,43 @@
1
+ AWSTemplateFormatVersion: "2010-09-09"
2
+ Description: ACM certificates for CloudFront (us-east-1)
3
+
4
+ Resources:
5
+ # {% if domain %}
6
+ Certificate:
7
+ Type: AWS::CertificateManager::Certificate
8
+ Properties:
9
+ DomainName: "{{ domain }}"
10
+ DomainValidationOptions:
11
+ - DomainName: "{{ domain }}"
12
+ HostedZoneId: "{{ hosted_zone_id }}"
13
+ Tags:
14
+ - Key: Name
15
+ Value: "{{ resource_prefix }}cloudfront-cert"
16
+ ValidationMethod: DNS
17
+ # {% endif %}
18
+
19
+ # {% for rf in redirect_from %}
20
+ "Certificate{{ rf.yaml_key }}":
21
+ Type: AWS::CertificateManager::Certificate
22
+ Properties:
23
+ DomainName: "{{ rf.domain }}"
24
+ DomainValidationOptions:
25
+ - DomainName: "{{ rf.domain }}"
26
+ HostedZoneId: "{{ rf.hosted_zone_id }}"
27
+ Tags:
28
+ - Key: Name
29
+ Value: "{{ resource_prefix }}spa-cert-{{ rf.yaml_key }}"
30
+ ValidationMethod: DNS
31
+ # {% endfor %}
32
+
33
+ Outputs:
34
+ # {% if domain %}
35
+ CertificateArn:
36
+ Value:
37
+ Ref: Certificate
38
+ # {% endif %}
39
+ # {% for rf in redirect_from %}
40
+ "CertificateArn{{ rf.yaml_key }}":
41
+ Value:
42
+ Ref: "Certificate{{ rf.yaml_key }}"
43
+ # {% endfor %}
@@ -0,0 +1,32 @@
1
+ AWSTemplateFormatVersion: "2010-09-09"
2
+ Description: CloudFront signing key resources
3
+
4
+ Resources:
5
+ PublicKey:
6
+ Type: AWS::CloudFront::PublicKey
7
+ Properties:
8
+ PublicKeyConfig:
9
+ Name: "{{ resource_prefix }}publickey"
10
+ CallerReference: "{{ resource_prefix }}publickey"
11
+ EncodedKey: |
12
+ {{ signing_public_key_pem | indent(10, first=False) }}
13
+
14
+ KeyGroup:
15
+ Type: AWS::CloudFront::KeyGroup
16
+ DependsOn:
17
+ - PublicKey
18
+ Properties:
19
+ KeyGroupConfig:
20
+ Name: "{{ resource_prefix }}keygroup"
21
+ Items:
22
+ - !Ref PublicKey
23
+
24
+ Outputs:
25
+ PublicKeyId:
26
+ Value: !Ref PublicKey
27
+ Export:
28
+ Name: "{{ export.public_key_id }}"
29
+ KeyGroupId:
30
+ Value: !Ref KeyGroup
31
+ Export:
32
+ Name: "{{ export.key_group_id }}"
@@ -0,0 +1,97 @@
1
+ AWSTemplateFormatVersion: "2010-09-09"
2
+ Description: WAFv2 IPSet + WebACL for CloudFront (us-east-1)
3
+
4
+ # Notes:
5
+ # - Scope=CLOUDFRONT requires us-east-1.
6
+ # - waf.enable_ip_set = true (default):
7
+ # - DefaultAction = Block
8
+ # - IPSet (Addresses=[]) + ip-allow Rule (Allow on IPSet match) を出力
9
+ # - 初回 deploy 直後は deny-all。`pocket waf ip add self ...` で CIDR を投入
10
+ # - IPSet の Addresses は CFn template 上は常に空で、CLI が side-channel
11
+ # 更新する仕様 (CFn 視点では常に drift だが意図的)
12
+ # - waf.enable_ip_set = false:
13
+ # - DefaultAction = Allow
14
+ # - IPSet / ip-allow Rule は出力しない
15
+ # - managed_rule_groups (必須) で「許可ベース + 怪しいリクエストのみ block」
16
+
17
+ Resources:
18
+ # {% if waf.enable_ip_set %}
19
+ IPSet:
20
+ Type: AWS::WAFv2::IPSet
21
+ Properties:
22
+ Name: "{{ slug }}-waf-allow"
23
+ Description: "CloudFront IP allowlist - managed by pocket waf ip CLI"
24
+ Scope: CLOUDFRONT
25
+ IPAddressVersion: IPV4
26
+ Addresses: []
27
+ Tags:
28
+ - Key: Name
29
+ Value: "{{ resource_prefix }}cloudfront-waf-allow"
30
+ # {% endif %}
31
+
32
+ WebACL:
33
+ Type: AWS::WAFv2::WebACL
34
+ Properties:
35
+ Name: "{{ slug }}-waf"
36
+ Description: "CloudFront WAF - IP allowlist plus optional managed rules"
37
+ Scope: CLOUDFRONT
38
+ DefaultAction:
39
+ # {% if waf.enable_ip_set %}
40
+ Block: {}
41
+ # {% else %}
42
+ Allow: {}
43
+ # {% endif %}
44
+ VisibilityConfig:
45
+ SampledRequestsEnabled: true
46
+ CloudWatchMetricsEnabled: true
47
+ MetricName: "{{ slug }}-waf"
48
+ Rules:
49
+ # {% if waf.enable_ip_set %}
50
+ - Name: ip-allow
51
+ Priority: 0
52
+ Action:
53
+ Allow: {}
54
+ Statement:
55
+ IPSetReferenceStatement:
56
+ Arn:
57
+ Fn::GetAtt: IPSet.Arn
58
+ VisibilityConfig:
59
+ SampledRequestsEnabled: true
60
+ CloudWatchMetricsEnabled: true
61
+ MetricName: "{{ slug }}-waf-ip-allow"
62
+ # {% endif %}
63
+ # {% for group_name in waf.managed_rule_groups %}
64
+ - Name: "managed-{{ loop.index0 }}-{{ group_name }}"
65
+ Priority: {{ loop.index if waf.enable_ip_set else loop.index0 }}
66
+ OverrideAction:
67
+ None: {}
68
+ Statement:
69
+ ManagedRuleGroupStatement:
70
+ VendorName: AWS
71
+ Name: "{{ group_name }}"
72
+ VisibilityConfig:
73
+ SampledRequestsEnabled: true
74
+ CloudWatchMetricsEnabled: true
75
+ MetricName: "{{ slug }}-waf-managed-{{ loop.index0 }}"
76
+ # {% endfor %}
77
+ Tags:
78
+ - Key: Name
79
+ Value: "{{ resource_prefix }}cloudfront-waf"
80
+
81
+ Outputs:
82
+ WebACLArn:
83
+ Value:
84
+ Fn::GetAtt: WebACL.Arn
85
+ # {% if waf.enable_ip_set %}
86
+ IPSetArn:
87
+ Value:
88
+ Fn::GetAtt: IPSet.Arn
89
+ # AWS::WAFv2::IPSet の Ref は "<Name>|<UUID>|<Scope>" の合成 string を返す。
90
+ # WAFv2 API (GetIPSet / UpdateIPSet) は UUID 単体 (36 char) を要求するので、
91
+ # ここでは Fn::GetAtt の Id (= UUID) を使う必要がある。
92
+ IPSetId:
93
+ Value:
94
+ Fn::GetAtt: IPSet.Id
95
+ IPSetName:
96
+ Value: "{{ slug }}-waf-allow"
97
+ # {% endif %}
@@ -0,0 +1,213 @@
1
+ AWSTemplateFormatVersion: "2010-09-09"
2
+ Description: vpc stack created by zerode
3
+
4
+ Resources:
5
+ VPC:
6
+ Type: AWS::EC2::VPC
7
+ Properties:
8
+ CidrBlock: 10.0.0.0/16
9
+ EnableDnsHostnames: true
10
+ EnableDnsSupport: true
11
+ Tags:
12
+ - Key: Name
13
+ Value: "{{ name }}"
14
+
15
+ # {% if internet_gateway %}
16
+ InternetGateway:
17
+ Type: AWS::EC2::InternetGateway
18
+ Properties:
19
+ Tags:
20
+ - Key: Name
21
+ Value: "{{ name }}"
22
+
23
+ InternetGatewayAttachment:
24
+ Type: AWS::EC2::VPCGatewayAttachment
25
+ Properties:
26
+ InternetGatewayId:
27
+ Ref: InternetGateway
28
+ VpcId:
29
+ Ref: VPC
30
+
31
+ PublicRouteTable:
32
+ Type: AWS::EC2::RouteTable
33
+ Properties:
34
+ VpcId:
35
+ Ref: VPC
36
+ Tags:
37
+ - Key: Name
38
+ Value: "{{ name }}-public"
39
+
40
+ DefaultPublicRoute:
41
+ Type: AWS::EC2::Route
42
+ DependsOn: InternetGatewayAttachment
43
+ Properties:
44
+ RouteTableId:
45
+ Ref: PublicRouteTable
46
+ DestinationCidrBlock: 0.0.0.0/0
47
+ GatewayId:
48
+ Ref: InternetGateway
49
+
50
+ # {% for zone in zones %}
51
+ PublicSubnet{{ loop.index }}:
52
+ Type: AWS::EC2::Subnet
53
+ Properties:
54
+ VpcId:
55
+ Ref: VPC
56
+ AvailabilityZone: "{{ zone }}"
57
+ CidrBlock: 10.0.1{{ loop.index0 }}.0/24
58
+ MapPublicIpOnLaunch: true
59
+ Tags:
60
+ - Key: Name
61
+ Value: "{{ name }}-public-{{ loop.index }}"
62
+
63
+ PublicSubnetRouteTableAssociation{{ loop.index }}:
64
+ Type: AWS::EC2::SubnetRouteTableAssociation
65
+ Properties:
66
+ RouteTableId:
67
+ Ref: PublicRouteTable
68
+ SubnetId:
69
+ Ref: PublicSubnet{{ loop.index }}
70
+ # {% endfor %}
71
+ # {% endif %}
72
+
73
+ # {% for zone in zones %}
74
+ PrivateSubnet{{ loop.index }}:
75
+ Type: AWS::EC2::Subnet
76
+ Properties:
77
+ VpcId:
78
+ Ref: VPC
79
+ AvailabilityZone: "{{ zone }}"
80
+ CidrBlock: 10.0.2{{ loop.index0 }}.0/24
81
+ MapPublicIpOnLaunch: false
82
+ Tags:
83
+ - Key: Name
84
+ Value: "{{ name }}-private-{{ loop.index }}"
85
+
86
+ # {% if private_route_table %}
87
+ PrivateRouteTable{{ loop.index }}:
88
+ Type: AWS::EC2::RouteTable
89
+ Properties:
90
+ VpcId:
91
+ Ref: VPC
92
+ Tags:
93
+ - Key: Name
94
+ Value: "{{ name }}-private-{{ loop.index }}"
95
+
96
+ PrivateSubnetRouteTableAssociation{{ loop.index }}:
97
+ Type: AWS::EC2::SubnetRouteTableAssociation
98
+ Properties:
99
+ RouteTableId:
100
+ Ref: PrivateRouteTable{{ loop.index }}
101
+ SubnetId:
102
+ Ref: PrivateSubnet{{ loop.index }}
103
+ # {% endif %}
104
+
105
+ # {% if nat_gateway %}
106
+ NATGatewayIP{{ loop.index }}:
107
+ Type: "AWS::EC2::EIP"
108
+ Properties:
109
+ Domain: vpc
110
+ Tags:
111
+ - Key: Name
112
+ Value: "{{ name }}-natgateway-{{ loop.index }}"
113
+
114
+ NATGateway{{ loop.index }}:
115
+ Type: AWS::EC2::NatGateway
116
+ Properties:
117
+ AllocationId:
118
+ Fn::GetAtt:
119
+ - NATGatewayIP{{ loop.index }}
120
+ - AllocationId
121
+ SubnetId:
122
+ Ref: PublicSubnet{{ loop.index }}
123
+ Tags:
124
+ - Key: Name
125
+ Value: "{{ name }}-{{ loop.index }}"
126
+
127
+ PrivateRoute{{ loop.index }}:
128
+ Type: AWS::EC2::Route
129
+ DependsOn: PrivateSubnetRouteTableAssociation{{ loop.index }}
130
+ Properties:
131
+ RouteTableId:
132
+ Ref: PrivateRouteTable{{ loop.index }}
133
+ DestinationCidrBlock: 0.0.0.0/0
134
+ NatGatewayId:
135
+ Ref: NATGateway{{ loop.index }}
136
+ # {% endif %}
137
+ # {% endfor %}
138
+
139
+ # {% if efs %}
140
+ EFSSecurityGroup:
141
+ Type: AWS::EC2::SecurityGroup
142
+ Properties:
143
+ GroupDescription: "{{ name }}-efs"
144
+ GroupName: "{{ name }}-efs"
145
+ SecurityGroupEgress:
146
+ - CidrIp: 0.0.0.0/0
147
+ Description: Allow all outbound traffic by default
148
+ IpProtocol: "-1"
149
+ Tags:
150
+ - Key: Name
151
+ Value: "{{ name }}-efs"
152
+ VpcId:
153
+ Ref: VPC
154
+
155
+ EfsAccessPoint:
156
+ Type: AWS::EFS::AccessPoint
157
+ Properties:
158
+ FileSystemId: "{{ resource.efs.filesystem_id }}"
159
+ PosixUser:
160
+ Uid: "1000"
161
+ Gid: "1000"
162
+ RootDirectory:
163
+ CreationInfo:
164
+ OwnerGid: "1000"
165
+ OwnerUid: "1000"
166
+ Permissions: "0777"
167
+ Path: "{{ efs.access_point_path }}"
168
+ # {% for zone in zones %}
169
+ MountTarget{{ loop.index }}:
170
+ Type: AWS::EFS::MountTarget
171
+ Properties:
172
+ FileSystemId: "{{ resource.efs.filesystem_id }}"
173
+ SubnetId:
174
+ Ref: PrivateSubnet{{ loop.index }}
175
+ SecurityGroups:
176
+ - Ref: EFSSecurityGroup
177
+ # {% endfor %}
178
+ # {% endif %}
179
+
180
+ Outputs:
181
+ VPC:
182
+ Value:
183
+ Ref: VPC
184
+ Export:
185
+ Name: "{{ export.vpc_id }}"
186
+
187
+ # {% for zone in zones %}
188
+ PrivateSubnet{{ loop.index }}:
189
+ Value:
190
+ Ref: PrivateSubnet{{ loop.index }}
191
+ Export:
192
+ Name: "{{ export.private_subnet_ }}{{ loop.index }}"
193
+
194
+ # {% if nat_gateway %}
195
+ NATGatewayIP{{ loop.index }}:
196
+ Value:
197
+ Ref: NATGatewayIP{{ loop.index }}
198
+ # {% endif %}
199
+ # {% endfor %}
200
+
201
+ # {% if efs %}
202
+ EFSAccessPointArn:
203
+ Value:
204
+ Fn::GetAtt: EfsAccessPoint.Arn
205
+ Export:
206
+ Name: "{{ export.efs_access_point_arn }}"
207
+
208
+ EFSSecurityGroup:
209
+ Value:
210
+ Ref: EFSSecurityGroup
211
+ Export:
212
+ Name: "{{ export.efs_security_group }}"
213
+ # {% endif %}
@@ -0,0 +1,3 @@
1
+ DEBUG=true
2
+ SECRET_KEY={{ secret_key }}
3
+ DATABASE_URL=sqlite:///db.sqlite3