dbt-platform-helper 11.4.0__py3-none-any.whl → 12.0.1__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.

Potentially problematic release.


This version of dbt-platform-helper might be problematic. Click here for more details.

Files changed (32) hide show
  1. dbt_platform_helper/COMMANDS.md +3 -252
  2. dbt_platform_helper/addons-template-map.yml +7 -33
  3. dbt_platform_helper/commands/application.py +8 -7
  4. dbt_platform_helper/commands/conduit.py +1 -4
  5. dbt_platform_helper/commands/copilot.py +14 -110
  6. dbt_platform_helper/commands/environment.py +0 -5
  7. dbt_platform_helper/commands/pipeline.py +1 -13
  8. dbt_platform_helper/domain/database_copy.py +2 -2
  9. dbt_platform_helper/domain/maintenance_page.py +9 -4
  10. dbt_platform_helper/templates/addon-instructions.txt +1 -1
  11. dbt_platform_helper/templates/addons/svc/s3-policy.yml +0 -8
  12. dbt_platform_helper/utils/platform_config.py +2 -7
  13. dbt_platform_helper/utils/validation.py +3 -78
  14. {dbt_platform_helper-11.4.0.dist-info → dbt_platform_helper-12.0.1.dist-info}/METADATA +1 -1
  15. {dbt_platform_helper-11.4.0.dist-info → dbt_platform_helper-12.0.1.dist-info}/RECORD +19 -32
  16. platform_helper.py +0 -8
  17. dbt_platform_helper/commands/check_cloudformation.py +0 -87
  18. dbt_platform_helper/commands/dns.py +0 -952
  19. dbt_platform_helper/custom_resources/__init__.py +0 -0
  20. dbt_platform_helper/custom_resources/s3_object.py +0 -85
  21. dbt_platform_helper/templates/addons/env/addons.parameters.yml +0 -19
  22. dbt_platform_helper/templates/addons/env/aurora-postgres.yml +0 -604
  23. dbt_platform_helper/templates/addons/env/monitoring.yml +0 -121
  24. dbt_platform_helper/templates/addons/env/opensearch.yml +0 -257
  25. dbt_platform_helper/templates/addons/env/rds-postgres.yml +0 -603
  26. dbt_platform_helper/templates/addons/env/redis-cluster.yml +0 -171
  27. dbt_platform_helper/templates/addons/env/s3.yml +0 -219
  28. dbt_platform_helper/templates/addons/env/vpc.yml +0 -120
  29. dbt_platform_helper/utils/cloudformation.py +0 -34
  30. {dbt_platform_helper-11.4.0.dist-info → dbt_platform_helper-12.0.1.dist-info}/LICENSE +0 -0
  31. {dbt_platform_helper-11.4.0.dist-info → dbt_platform_helper-12.0.1.dist-info}/WHEEL +0 -0
  32. {dbt_platform_helper-11.4.0.dist-info → dbt_platform_helper-12.0.1.dist-info}/entry_points.txt +0 -0
@@ -1,604 +0,0 @@
1
- # {% extra_header %}
2
- # {% version_info %}
3
-
4
- Parameters:
5
- # Copilot required Parameters...
6
- App:
7
- Type: String
8
- Description: Your application's name.
9
- Env:
10
- Type: String
11
- Description: The environment name your service, job, or workflow is being deployed to.
12
-
13
- # Parameters from the parent stack brought in via addons.parameters.yml...
14
- EnvironmentSecurityGroup:
15
- Type: String
16
- DefaultPublicRoute:
17
- Type: String
18
- InternetGateway:
19
- Type: String
20
- InternetGatewayAttachment:
21
- Type: String
22
- PrivateSubnets:
23
- Type: String
24
- PublicRouteTable:
25
- Type: String
26
- PublicSubnet1RouteTableAssociation:
27
- Type: String
28
- PublicSubnet2RouteTableAssociation:
29
- Type: String
30
- VpcId:
31
- Type: String
32
-
33
- # Other parameters...
34
- # Customize your Aurora Postgres cluster by setting the default value of the following parameters.
35
- {{ addon_config.prefix }}DBName:
36
- Type: String
37
- Description: The name of the initial database to be created in the Aurora Serverless v2 cluster.
38
- Default: main
39
- # Cannot have special characters
40
- # Naming constraints: https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_Limits.html#RDS_Limits.Constraints
41
-
42
- Mappings:
43
- {{ addon_config.prefix }}EnvironmentConfigMap:
44
- {%- for environment_name, config in addon_config.environments.items() %}
45
- {{ environment_name }}:
46
- DBMinCapacity: {{ config.min_capacity }}
47
- DBMaxCapacity: {{ config.max_capacity }}
48
- DeletionPolicy: {{ config.deletion_policy }}
49
- SnapshotIdentifier: {{ config.snapshot_id if config.snapshot_id else '""' }}
50
- DeletionProtection: {{ config.deletion_protection if config.deletion_protection else false }}
51
- {%- endfor %}
52
-
53
- Conditions:
54
- {{ addon_config.prefix }}CreateProdSubFilter: !Or [!Equals [!Ref Env, prod], !Equals [!Ref Env, production], !Equals [!Ref Env, PROD], !Equals [!Ref Env, PRODUCTION]]
55
- {{ addon_config.prefix }}UseSnapshot: !Not [!Equals [!FindInMap [{{ addon_config.prefix }}EnvironmentConfigMap, !Ref Env, SnapshotIdentifier], ""]]
56
-
57
- Resources:
58
- {{ addon_config.prefix }}DBSubnetGroup:
59
- Type: 'AWS::RDS::DBSubnetGroup'
60
- DeletionPolicy: !FindInMap [{{ addon_config.prefix }}EnvironmentConfigMap, !Ref Env, DeletionPolicy]
61
- UpdateReplacePolicy: Retain
62
- Properties:
63
- DBSubnetGroupDescription: Group of Copilot private subnets for Aurora Serverless v2 cluster.
64
- SubnetIds: !Split [ ",", !Ref PrivateSubnets ]
65
-
66
- {{ addon_config.prefix }}SecurityGroup:
67
- Metadata:
68
- 'aws:copilot:description': 'A security group for your workload to access the Aurora Serverless v2 cluster {{ addon_config.prefix }}'
69
- Type: 'AWS::EC2::SecurityGroup'
70
- DeletionPolicy: !FindInMap [{{ addon_config.prefix }}EnvironmentConfigMap, !Ref Env, DeletionPolicy]
71
- UpdateReplacePolicy: Retain
72
- Properties:
73
- GroupDescription: 'The Security Group for {{ addon_config.name }} to access Aurora Serverless v2 cluster {{ addon_config.prefix }}.'
74
- VpcId: !Ref VpcId
75
- Tags:
76
- - Key: Name
77
- Value: !Sub 'copilot-${App}-${Env}-{{ addon_config.name }}-Aurora'
78
-
79
- {{ addon_config.prefix }}DBClusterSecurityGroup:
80
- Metadata:
81
- 'aws:copilot:description': 'A security group for your Aurora Serverless v2 cluster {{ addon_config.prefix }}'
82
- Type: AWS::EC2::SecurityGroup
83
- DeletionPolicy: !FindInMap [{{ addon_config.prefix }}EnvironmentConfigMap, !Ref Env, DeletionPolicy]
84
- UpdateReplacePolicy: Retain
85
- Properties:
86
- GroupDescription: The Security Group for the Aurora Serverless v2 cluster.
87
- SecurityGroupIngress:
88
- - ToPort: 5432
89
- FromPort: 5432
90
- IpProtocol: tcp
91
- Description: 'From the Aurora Security Group of the workload {{ addon_config.name }}.'
92
- SourceSecurityGroupId: !Ref {{ addon_config.prefix }}SecurityGroup
93
- VpcId: !Ref VpcId
94
-
95
- {{ addon_config.prefix }}AuroraSecret:
96
- Metadata:
97
- 'aws:copilot:description': 'A Secrets Manager secret to store your DB credentials'
98
- Type: AWS::SecretsManager::Secret
99
- Properties:
100
- Name: !Sub '/copilot/${App}/${Env}/secrets/{{ addon_config.name|upper|replace("-", "_") }}'
101
- Description: !Sub Aurora main user secret for ${AWS::StackName}
102
- GenerateSecretString:
103
- SecretStringTemplate: '{"username": "postgres"}'
104
- GenerateStringKey: "password"
105
- ExcludePunctuation: true
106
- IncludeSpace: false
107
- PasswordLength: 16
108
- ExcludeCharacters: '[]{}()"@/\;=?&`><:|#'
109
-
110
- {{ addon_config.prefix }}DBClusterParameterGroup:
111
- Metadata:
112
- 'aws:copilot:description': 'A DB parameter group for engine configuration values'
113
- Type: 'AWS::RDS::DBClusterParameterGroup'
114
- DeletionPolicy: !FindInMap [{{ addon_config.prefix }}EnvironmentConfigMap, !Ref Env, DeletionPolicy]
115
- UpdateReplacePolicy: Retain
116
- Properties:
117
- Description: !Ref 'AWS::StackName'
118
- Family: 'aurora-postgresql{{ addon_config.version|round(0, "floor")|int }}'
119
- Parameters:
120
- client_encoding: 'UTF8'
121
- log_statement: ddl
122
- log_statement_sample_rate: '1.0'
123
-
124
- {{ addon_config.prefix }}KMSKey:
125
- Type: "AWS::KMS::Key"
126
- DeletionPolicy: !FindInMap [{{ addon_config.prefix }}EnvironmentConfigMap, !Ref Env, DeletionPolicy]
127
- UpdateReplacePolicy: Retain
128
- Properties:
129
- Description: "KMS Key for Aurora encryption"
130
- KeyPolicy:
131
- Version: '2012-10-17'
132
- Id: !Sub '${App}-${Env}-{{ addon_config.prefix }}-cluster-key'
133
- Statement:
134
- - Sid: Enable IAM User Permissions
135
- Effect: Allow
136
- Principal:
137
- AWS: !Sub "arn:aws:iam::${AWS::AccountId}:root"
138
- Action: kms:*
139
- Resource: '*'
140
-
141
- {{ addon_config.prefix }}KeyAlias:
142
- Type: 'AWS::KMS::Alias'
143
- Properties:
144
- AliasName: !Sub 'alias/${App}-${Env}-{{ addon_config.prefix }}-cluster-key'
145
- TargetKeyId: !Ref {{ addon_config.prefix }}KMSKey
146
-
147
- {{ addon_config.prefix }}DBCluster:
148
- Metadata:
149
- 'aws:copilot:description': 'The {{ addon_config.prefix }} Aurora Serverless v2 database cluster'
150
- Type: 'AWS::RDS::DBCluster'
151
- DeletionPolicy: !FindInMap [{{ addon_config.prefix }}EnvironmentConfigMap, !Ref Env, DeletionPolicy]
152
- UpdateReplacePolicy: Retain
153
- Properties:
154
- AutoMinorVersionUpgrade: true
155
- BackupRetentionPeriod: 8
156
- MasterUsername:
157
- !If [
158
- {{ addon_config.prefix }}UseSnapshot,
159
- !Ref AWS::NoValue,
160
- !Join [ "", [ '{% raw %}{{{% endraw %}resolve:secretsmanager:', !Ref {{ addon_config.prefix }}AuroraSecret, ":SecretString:username{% raw %}}}{% endraw %}" ]]
161
- ]
162
- MasterUserPassword:
163
- !If [
164
- {{ addon_config.prefix }}UseSnapshot,
165
- !Ref AWS::NoValue,
166
- !Join [ "", [ '{% raw %}{{{% endraw %}resolve:secretsmanager:', !Ref {{ addon_config.prefix }}AuroraSecret, ":SecretString:password{% raw %}}}{% endraw %}" ]]
167
- ]
168
- DatabaseName: !Ref {{ addon_config.prefix }}DBName
169
- Engine: 'aurora-postgresql'
170
- EngineVersion: '{{ addon_config.version }}'
171
- EnableCloudwatchLogsExports:
172
- - postgresql
173
- DBClusterParameterGroupName: !Ref {{ addon_config.prefix }}DBClusterParameterGroup
174
- DBSubnetGroupName: !Ref {{ addon_config.prefix }}DBSubnetGroup
175
- KmsKeyId: !Ref {{ addon_config.prefix }}KMSKey
176
- Port: 5432
177
- VpcSecurityGroupIds:
178
- - !Ref {{ addon_config.prefix }}DBClusterSecurityGroup
179
- ServerlessV2ScalingConfiguration:
180
- MinCapacity: !FindInMap [{{ addon_config.prefix }}EnvironmentConfigMap, !Ref Env, DBMinCapacity]
181
- MaxCapacity: !FindInMap [{{ addon_config.prefix }}EnvironmentConfigMap, !Ref Env, DBMaxCapacity]
182
- SnapshotIdentifier: !If [{{ addon_config.prefix }}UseSnapshot, !FindInMap [{{ addon_config.prefix }}EnvironmentConfigMap, !Ref Env, SnapshotIdentifier], !Ref AWS::NoValue]
183
- StorageEncrypted: true
184
- DeletionProtection: !FindInMap [{{ addon_config.prefix }}EnvironmentConfigMap, !Ref Env, DeletionProtection]
185
-
186
- {{ addon_config.prefix }}DBWriterInstance:
187
- Metadata:
188
- 'aws:copilot:description': 'The {{ addon_config.prefix }} Aurora Serverless v2 writer instance'
189
- Type: 'AWS::RDS::DBInstance'
190
- DeletionPolicy: !FindInMap [{{ addon_config.prefix }}EnvironmentConfigMap, !Ref Env, DeletionPolicy]
191
- UpdateReplacePolicy: Retain
192
- Properties:
193
- DBClusterIdentifier: !Ref {{ addon_config.prefix }}DBCluster
194
- DBInstanceClass: db.serverless
195
- EnablePerformanceInsights: true
196
- Engine: 'aurora-postgresql'
197
- PromotionTier: 1
198
- AvailabilityZone: !Select
199
- - 0
200
- - !GetAZs
201
- Ref: AWS::Region
202
-
203
- {{ addon_config.prefix }}SecretAuroraClusterAttachment:
204
- Type: AWS::SecretsManager::SecretTargetAttachment
205
- Properties:
206
- SecretId: !Ref {{ addon_config.prefix }}AuroraSecret
207
- TargetId: !Ref {{ addon_config.prefix }}DBCluster
208
- TargetType: AWS::RDS::DBCluster
209
-
210
- # Enable ingress from other ECS services created within the environment.
211
- {{ addon_config.prefix }}EnvironmentIngress:
212
- Metadata:
213
- 'aws:copilot:description': 'Allow ingress from containers in my application to the OpenSearch cluster'
214
- Type: AWS::EC2::SecurityGroupIngress
215
- DeletionPolicy: !FindInMap [{{ addon_config.prefix }}EnvironmentConfigMap, !Ref Env, DeletionPolicy]
216
- UpdateReplacePolicy: Retain
217
- Properties:
218
- Description: Ingress Security Group from Fargate containers
219
- GroupId: !Ref '{{ addon_config.prefix }}DBClusterSecurityGroup'
220
- IpProtocol: tcp
221
- FromPort: 5432
222
- ToPort: 5432
223
- SourceSecurityGroupId: !Ref EnvironmentSecurityGroup
224
-
225
- {{ addon_config.prefix }}LambdaIngress:
226
- Metadata:
227
- 'aws:copilot:description': 'Allow ingress from Lambda Functions in my application to the DB cluster'
228
- Type: AWS::EC2::SecurityGroupIngress
229
- DeletionPolicy: !FindInMap [{{ addon_config.prefix }}EnvironmentConfigMap, !Ref Env, DeletionPolicy]
230
- UpdateReplacePolicy: Retain
231
- Properties:
232
- Description: Ingress from Lambda Functions to DB
233
- GroupId: !Ref '{{ addon_config.prefix }}DBClusterSecurityGroup'
234
- IpProtocol: tcp
235
- FromPort: 5432
236
- ToPort: 5432
237
- SourceSecurityGroupId: !Ref '{{ addon_config.prefix }}DBClusterSecurityGroup'
238
-
239
- {{ addon_config.prefix }}SecretsManagerIngress:
240
- Metadata:
241
- 'aws:copilot:description': 'Allow ingress from Lambda Functions in my application to the Secrets Manager'
242
- Type: AWS::EC2::SecurityGroupIngress
243
- DeletionPolicy: !FindInMap [{{ addon_config.prefix }}EnvironmentConfigMap, !Ref Env, DeletionPolicy]
244
- UpdateReplacePolicy: Retain
245
- Properties:
246
- Description: Ingress from Lambda Functions to Secrets Manager
247
- GroupId: !Ref '{{ addon_config.prefix }}DBClusterSecurityGroup'
248
- IpProtocol: tcp
249
- FromPort: 443
250
- ToPort: 443
251
- SourceSecurityGroupId: !Ref '{{ addon_config.prefix }}DBClusterSecurityGroup'
252
-
253
- {{ addon_config.prefix }}LambdaEgress:
254
- Metadata:
255
- 'aws:copilot:description': 'Allow egress from DB cluster in my application to the Lambda Function'
256
- Type: AWS::EC2::SecurityGroupEgress
257
- DeletionPolicy: !FindInMap [{{ addon_config.prefix }}EnvironmentConfigMap, !Ref Env, DeletionPolicy]
258
- UpdateReplacePolicy: Retain
259
- Properties:
260
- Description: Egress from DB to Lambda Functions
261
- GroupId: !Ref '{{ addon_config.prefix }}DBClusterSecurityGroup'
262
- IpProtocol: tcp
263
- FromPort: 5432
264
- ToPort: 5432
265
- DestinationSecurityGroupId: !Ref '{{ addon_config.prefix }}DBClusterSecurityGroup'
266
-
267
- {{ addon_config.prefix }}SecretsManagerEgress:
268
- Metadata:
269
- 'aws:copilot:description': 'Allow egress from Secrets Manager in my application to the Lambda Function'
270
- Type: AWS::EC2::SecurityGroupEgress
271
- DeletionPolicy: !FindInMap [{{ addon_config.prefix }}EnvironmentConfigMap, !Ref Env, DeletionPolicy]
272
- UpdateReplacePolicy: Retain
273
- Properties:
274
- Description: Egress from Secrets Manager to Lambda Functions
275
- GroupId: !Ref '{{ addon_config.prefix }}DBClusterSecurityGroup'
276
- IpProtocol: tcp
277
- FromPort: 443
278
- ToPort: 443
279
- DestinationSecurityGroupId: !Ref '{{ addon_config.prefix }}DBClusterSecurityGroup'
280
-
281
- {{ addon_config.prefix }}HTTPSEgress:
282
- Metadata:
283
- 'aws:copilot:description': 'Allow egress for HTTPS (so the Lambda Function can post a success response back to the Custom Resource)'
284
- Type: AWS::EC2::SecurityGroupEgress
285
- DeletionPolicy: !FindInMap [{{ addon_config.prefix }}EnvironmentConfigMap, !Ref Env, DeletionPolicy]
286
- UpdateReplacePolicy: Retain
287
- Properties:
288
- CidrIp: 0.0.0.0/0
289
- Description: Egress for HTTPS
290
- GroupId: !Ref '{{ addon_config.prefix }}DBClusterSecurityGroup'
291
- IpProtocol: tcp
292
- FromPort: 443
293
- ToPort: 443
294
-
295
- {{ addon_config.prefix }}LambdaFunction:
296
- Type: AWS::Lambda::Function
297
- Properties:
298
- FunctionName: !Sub "${App}-${Env}-{{ addon_config.prefix }}-aurora-create-user"
299
- Handler: index.handler
300
- Runtime: python3.11
301
- Layers:
302
- - arn:aws:lambda:eu-west-2:763451185160:layer:python-postgres:1
303
- MemorySize: 128
304
- Timeout: 10
305
- Role: !GetAtt {{ addon_config.prefix }}LambdaFunctionExecutionRole.Arn
306
- VpcConfig:
307
- SecurityGroupIds:
308
- - !Ref {{ addon_config.prefix }}DBClusterSecurityGroup
309
- SubnetIds: !Split [ ",", !Ref PrivateSubnets ]
310
- Code:
311
- ZipFile: |
312
- import json
313
- import boto3
314
- import cfnresponse
315
- import psycopg2
316
- from botocore.exceptions import ClientError
317
-
318
-
319
- def drop_user(cursor, username):
320
- cursor.execute(f"SELECT * FROM pg_catalog.pg_user WHERE usename = '{username}'")
321
-
322
- if cursor.fetchone() is not None:
323
- cursor.execute(f"GRANT {username} TO postgres")
324
- cursor.execute(f"DROP OWNED BY {username}")
325
- cursor.execute(f"DROP USER {username}")
326
-
327
-
328
- def create_db_user(conn, cursor, username, password, permissions):
329
- drop_user(cursor, username)
330
-
331
- cursor.execute(f"CREATE USER {username} WITH ENCRYPTED PASSWORD '%s'" % password)
332
- cursor.execute(f"GRANT {username} to postgres;")
333
- cursor.execute(f"GRANT {', '.join(permissions)} ON ALL TABLES IN SCHEMA public TO {username};")
334
- cursor.execute(f"ALTER DEFAULT PRIVILEGES FOR USER {username} IN SCHEMA public GRANT {', '.join(permissions)} ON TABLES TO {username};")
335
- conn.commit()
336
-
337
-
338
- def create_or_update_user_secret(ssm, user_secret_name, user_secret_string, event):
339
- user_secret_description = event['ResourceProperties']['SecretDescription']
340
- copilot_application = event['ResourceProperties']['CopilotApplication']
341
- copilot_environment = event['ResourceProperties']['CopilotEnvironment']
342
-
343
- user_secret = None
344
-
345
- try:
346
- user_secret = ssm.put_parameter(
347
- Name=user_secret_name,
348
- Description=user_secret_description,
349
- Value=json.dumps(user_secret_string),
350
- Tags=[
351
- {'Key': 'custom:cloudformation:stack-name', 'Value': event["StackId"].split('/')[1]},
352
- {'Key': 'custom:cloudformation:logical-id', 'Value': event["LogicalResourceId"]},
353
- {'Key': 'custom:cloudformation:stack-id', 'Value': event["StackId"]},
354
- {'Key': 'copilot-application', 'Value': copilot_application},
355
- {'Key': 'copilot-environment', 'Value': copilot_environment},
356
- ],
357
- Type="String",
358
- )
359
- except ClientError as error:
360
- if error.response["Error"]["Code"] == "ParameterAlreadyExists":
361
- user_secret = ssm.put_parameter(
362
- Name=user_secret_name,
363
- Description=user_secret_description,
364
- Value=json.dumps(user_secret_string),
365
- Overwrite=True,
366
- )
367
-
368
- return user_secret
369
-
370
-
371
- def handler(event, context):
372
- print("REQUEST RECEIVED:\n" + json.dumps(event))
373
-
374
- db_master_user_secret = event['ResourceProperties']['MasterUserSecret']
375
- user_secret_name = event['ResourceProperties']['SecretName']
376
- username = event['ResourceProperties']['Username']
377
- user_permissions = event['ResourceProperties']['Permissions']
378
-
379
- secrets_manager = boto3.client("secretsmanager")
380
- ssm = boto3.client("ssm")
381
-
382
- master_user = json.loads(secrets_manager.get_secret_value(SecretId=db_master_user_secret)["SecretString"])
383
-
384
- user_password = secrets_manager.get_random_password(
385
- PasswordLength=16,
386
- ExcludeCharacters='[]{}()"@/\;=?&`><:|#',
387
- ExcludePunctuation=True,
388
- IncludeSpace=False,
389
- )["RandomPassword"]
390
-
391
- user_secret_string = {
392
- "username": username,
393
- "password": user_password,
394
- "engine": master_user["engine"],
395
- "port": master_user["port"],
396
- "dbname": master_user["dbname"],
397
- "host": master_user["host"],
398
- "dbClusterIdentifier": master_user["dbClusterIdentifier"]
399
- }
400
-
401
- conn = psycopg2.connect(
402
- dbname=master_user["dbname"],
403
- user=master_user["username"],
404
- password=master_user["password"],
405
- host=master_user["host"],
406
- port=master_user["port"]
407
- )
408
-
409
- cursor = conn.cursor()
410
-
411
- response = {"Status": "SUCCESS"}
412
-
413
- try:
414
- match event["RequestType"]:
415
- case "Create":
416
- create_db_user(conn, cursor, username, user_password, user_permissions)
417
-
418
- response = {
419
- **response,
420
- "Data": create_or_update_user_secret(ssm, user_secret_name, user_secret_string, event)
421
- }
422
- case "Update":
423
- create_db_user(conn, cursor, username, user_password, user_permissions)
424
-
425
- response = {
426
- **response,
427
- "Data": create_or_update_user_secret(ssm, user_secret_name, user_secret_string, event)
428
- }
429
- case "Delete":
430
- drop_user(cursor, username)
431
-
432
- response = {
433
- **response,
434
- "Data": ssm.delete_parameter(Name=user_secret_name)
435
- }
436
- case _:
437
- response = {"Status": "FAILED",
438
- "Data": {"Error": f"""Invalid requestType of '${event["RequestType"]}'"""}}
439
- except Exception as e:
440
- response = {"Status": "FAILED", "Data": {"Error": str(e)}}
441
-
442
- cursor.close()
443
- conn.close()
444
-
445
- print(json.dumps(response, default=str))
446
- cfnresponse.send(event, context, response["Status"], response["Data"], event["LogicalResourceId"])
447
-
448
- {{ addon_config.prefix }}ApplicationUser:
449
- Type: 'Custom::{{ addon_config.prefix }}ApplicationUser'
450
- DeletionPolicy: !FindInMap [{{ addon_config.prefix }}EnvironmentConfigMap, !Ref Env, DeletionPolicy]
451
- UpdateReplacePolicy: Retain
452
- Properties:
453
- ServiceToken: !GetAtt '{{ addon_config.prefix }}LambdaFunction.Arn'
454
- CopilotApplication: !Sub "${App}"
455
- CopilotEnvironment: !Sub "${Env}"
456
- MasterUserSecret: !Ref {{ addon_config.prefix }}AuroraSecret
457
- SecretDescription: !Sub Aurora application user secret for ${AWS::StackName}
458
- SecretName: !Sub '/copilot/${App}/${Env}/secrets/{{ addon_config.name|upper|replace("-", "_") }}_APPLICATION_USER'
459
- DefaultPublicRoute: !Ref DefaultPublicRoute
460
- InternetGateway: !Ref InternetGateway
461
- InternetGatewayAttachment: !Ref InternetGatewayAttachment
462
- PublicRouteTable: !Ref PublicRouteTable
463
- PublicSubnet1RouteTableAssociation: !Ref PublicSubnet1RouteTableAssociation
464
- PublicSubnet2RouteTableAssociation: !Ref PublicSubnet2RouteTableAssociation
465
- Snapshot: !If [{{ addon_config.prefix }}UseSnapshot, !FindInMap [{{ addon_config.prefix }}EnvironmentConfigMap, !Ref Env, SnapshotIdentifier], ""]
466
- Username: 'application_user'
467
- Permissions:
468
- - 'SELECT'
469
- - 'INSERT'
470
- - 'UPDATE'
471
- - 'DELETE'
472
- - 'TRIGGER'
473
- # Resource based metadata block to ignore reference to resources in other addon templates. Do not remove.
474
- Metadata:
475
- cfn-lint:
476
- config:
477
- ignore_checks:
478
- # https://github.com/aws-cloudformation/cfn-lint/blob/main/docs/rules.md
479
- - E3005
480
- DependsOn:
481
- - VpcEndpoint
482
- - {{ addon_config.prefix }}DBWriterInstance
483
- - AdditionalNatGateway1
484
- - AdditionalNatGateway2
485
- - AdditionalPrivateRoute1
486
- - AdditionalPrivateRouteTable1
487
- - AdditionalPrivateRouteTable1Association
488
- - AdditionalPrivateRoute2
489
- - AdditionalPrivateRouteTable2
490
- - AdditionalPrivateRouteTable2Association
491
- - {{ addon_config.prefix }}SecretAuroraClusterAttachment
492
- - {{ addon_config.prefix }}EnvironmentIngress
493
- - {{ addon_config.prefix }}SecretsManagerIngress
494
- - {{ addon_config.prefix }}LambdaIngress
495
- - {{ addon_config.prefix }}SecretsManagerEgress
496
- - {{ addon_config.prefix }}LambdaEgress
497
- - {{ addon_config.prefix }}HTTPSEgress
498
- - {{ addon_config.prefix }}KeyAlias
499
-
500
- {{ addon_config.prefix }}ReadOnlyUser:
501
- Type: 'Custom::{{ addon_config.prefix }}ReadOnlyUser'
502
- DeletionPolicy: !FindInMap [{{ addon_config.prefix }}EnvironmentConfigMap, !Ref Env, DeletionPolicy]
503
- UpdateReplacePolicy: Retain
504
- Properties:
505
- ServiceToken: !GetAtt '{{ addon_config.prefix }}LambdaFunction.Arn'
506
- CopilotApplication: !Sub "${App}"
507
- CopilotEnvironment: !Sub "${Env}"
508
- MasterUserSecret: !Ref {{ addon_config.prefix }}AuroraSecret
509
- SecretDescription: !Sub Aurora read only user secret for ${AWS::StackName}
510
- SecretName: !Sub '/copilot/${App}/${Env}/secrets/{{ addon_config.name|upper|replace("-", "_") }}_READ_ONLY_USER'
511
- DefaultPublicRoute: !Ref DefaultPublicRoute
512
- InternetGateway: !Ref InternetGateway
513
- InternetGatewayAttachment: !Ref InternetGatewayAttachment
514
- PublicRouteTable: !Ref PublicRouteTable
515
- PublicSubnet1RouteTableAssociation: !Ref PublicSubnet1RouteTableAssociation
516
- PublicSubnet2RouteTableAssociation: !Ref PublicSubnet2RouteTableAssociation
517
- Snapshot: !If [{{ addon_config.prefix }}UseSnapshot, !FindInMap [{{ addon_config.prefix }}EnvironmentConfigMap, !Ref Env, SnapshotIdentifier], ""]
518
- Username: 'read_only_user'
519
- Permissions:
520
- - 'SELECT'
521
- # Resource based metadata block to ignore reference to resources in other addon templates. Do not remove.
522
- Metadata:
523
- cfn-lint:
524
- config:
525
- ignore_checks:
526
- # https://github.com/aws-cloudformation/cfn-lint/blob/main/docs/rules.md
527
- - E3005
528
- DependsOn:
529
- - VpcEndpoint
530
- - {{ addon_config.prefix }}DBWriterInstance
531
- - AdditionalNatGateway1
532
- - AdditionalNatGateway2
533
- - AdditionalPrivateRoute1
534
- - AdditionalPrivateRouteTable1
535
- - AdditionalPrivateRouteTable1Association
536
- - AdditionalPrivateRoute2
537
- - AdditionalPrivateRouteTable2
538
- - AdditionalPrivateRouteTable2Association
539
- - {{ addon_config.prefix }}SecretAuroraClusterAttachment
540
- - {{ addon_config.prefix }}EnvironmentIngress
541
- - {{ addon_config.prefix }}SecretsManagerIngress
542
- - {{ addon_config.prefix }}LambdaIngress
543
- - {{ addon_config.prefix }}SecretsManagerEgress
544
- - {{ addon_config.prefix }}LambdaEgress
545
- - {{ addon_config.prefix }}HTTPSEgress
546
- - {{ addon_config.prefix }}KeyAlias
547
-
548
- {{ addon_config.prefix }}LambdaFunctionExecutionRole:
549
- Type: AWS::IAM::Role
550
- Properties:
551
- RoleName: !Sub "${App}-${Env}-{{ addon_config.prefix }}-aurora-user"
552
- AssumeRolePolicyDocument:
553
- Version: 2012-10-17
554
- Statement:
555
- - Effect: Allow
556
- Action:
557
- - 'sts:AssumeRole'
558
- Principal:
559
- Service:
560
- - lambda.amazonaws.com
561
- Policies:
562
- - PolicyName: !Sub "${App}-${Env}-aurora-user"
563
- PolicyDocument:
564
- Version: '2012-10-17'
565
- Statement:
566
- - Effect: Allow
567
- Action:
568
- - 'ec2:CreateNetworkInterface'
569
- - 'ec2:DescribeNetworkInterfaces'
570
- - 'ec2:DeleteNetworkInterface'
571
- Resource:
572
- - '*'
573
- - Effect: Allow
574
- Action:
575
- - 'ssm:DeleteParameter'
576
- - 'ssm:PutParameter'
577
- - 'ssm:AddTagsToResource'
578
- - 'kms:Decrypt'
579
- Resource:
580
- - '*'
581
- - Effect: Allow
582
- Action:
583
- - 'secretsmanager:DescribeSecret'
584
- - 'secretsmanager:GetRandomPassword'
585
- - 'secretsmanager:GetSecretValue'
586
- Resource:
587
- - '*'
588
- - Effect: Allow
589
- Action:
590
- - 'logs:CreateLogGroup'
591
- - 'logs:CreateLogStream'
592
- - 'logs:PutLogEvents'
593
- Resource: 'arn:aws:logs:*:*:*'
594
-
595
- {{ addon_config.prefix }}SubscriptionFilter:
596
- Type: AWS::Logs::SubscriptionFilter
597
- DependsOn:
598
- - {{ addon_config.prefix }}DBWriterInstance
599
- Properties:
600
- RoleArn: !Sub 'arn:aws:iam::${AWS::AccountId}:role/CWLtoSubscriptionFilterRole'
601
- LogGroupName: !Sub '/aws/rds/cluster/${{ '{' }}{{ addon_config.prefix }}DBCluster}/postgresql'
602
- FilterName: !Sub '/aws/rds/cluster/${App}/${Env}/${{ '{' }}{{ addon_config.prefix }}DBCluster}/postgresql'
603
- FilterPattern: ''
604
- DestinationArn: !If [{{ addon_config.prefix }}CreateProdSubFilter, '{{ log_destination.prod }}', '{{ log_destination.dev }}']