@stacksjs/ts-cloud-core 0.1.8 → 0.1.9
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.
- package/package.json +7 -6
- package/src/advanced-features.test.ts +465 -0
- package/src/aws/cloudformation.ts +421 -0
- package/src/aws/cloudfront.ts +158 -0
- package/src/aws/credentials.test.ts +132 -0
- package/src/aws/credentials.ts +545 -0
- package/src/aws/index.ts +87 -0
- package/src/aws/s3.test.ts +188 -0
- package/src/aws/s3.ts +1088 -0
- package/src/aws/signature.test.ts +670 -0
- package/src/aws/signature.ts +1155 -0
- package/src/backup/disaster-recovery.test.ts +726 -0
- package/src/backup/disaster-recovery.ts +500 -0
- package/src/backup/index.ts +34 -0
- package/src/backup/manager.test.ts +498 -0
- package/src/backup/manager.ts +432 -0
- package/src/cicd/circleci.ts +430 -0
- package/src/cicd/github-actions.ts +424 -0
- package/src/cicd/gitlab-ci.ts +255 -0
- package/src/cicd/index.ts +8 -0
- package/src/cli/history.ts +396 -0
- package/src/cli/index.ts +10 -0
- package/src/cli/progress.ts +458 -0
- package/src/cli/repl.ts +454 -0
- package/src/cli/suggestions.ts +327 -0
- package/src/cli/table.test.ts +319 -0
- package/src/cli/table.ts +332 -0
- package/src/cloudformation/builder.test.ts +327 -0
- package/src/cloudformation/builder.ts +378 -0
- package/src/cloudformation/builders/api-gateway.ts +449 -0
- package/src/cloudformation/builders/cache.ts +334 -0
- package/src/cloudformation/builders/cdn.ts +278 -0
- package/src/cloudformation/builders/compute.ts +485 -0
- package/src/cloudformation/builders/database.ts +392 -0
- package/src/cloudformation/builders/functions.ts +343 -0
- package/src/cloudformation/builders/messaging.ts +140 -0
- package/src/cloudformation/builders/monitoring.ts +300 -0
- package/src/cloudformation/builders/network.ts +264 -0
- package/src/cloudformation/builders/queue.ts +147 -0
- package/src/cloudformation/builders/security.ts +399 -0
- package/src/cloudformation/builders/storage.ts +285 -0
- package/src/cloudformation/index.ts +30 -0
- package/src/cloudformation/types.ts +173 -0
- package/src/compliance/aws-config.ts +543 -0
- package/src/compliance/cloudtrail.ts +376 -0
- package/src/compliance/compliance.test.ts +423 -0
- package/src/compliance/guardduty.ts +446 -0
- package/src/compliance/index.ts +66 -0
- package/src/compliance/security-hub.ts +456 -0
- package/src/containers/build-optimization.ts +416 -0
- package/src/containers/containers.test.ts +508 -0
- package/src/containers/image-scanning.ts +360 -0
- package/src/containers/index.ts +9 -0
- package/src/containers/registry.ts +293 -0
- package/src/containers/service-mesh.ts +520 -0
- package/src/database/database.test.ts +762 -0
- package/src/database/index.ts +9 -0
- package/src/database/migrations.ts +444 -0
- package/src/database/performance.ts +528 -0
- package/src/database/replicas.ts +534 -0
- package/src/database/users.ts +494 -0
- package/src/dependency-graph.ts +143 -0
- package/src/deployment/ab-testing.ts +582 -0
- package/src/deployment/blue-green.ts +452 -0
- package/src/deployment/canary.ts +500 -0
- package/src/deployment/deployment.test.ts +526 -0
- package/src/deployment/index.ts +61 -0
- package/src/deployment/progressive.ts +62 -0
- package/src/dns/dns.test.ts +641 -0
- package/src/dns/dnssec.ts +315 -0
- package/src/dns/index.ts +8 -0
- package/src/dns/resolver.ts +496 -0
- package/src/dns/routing.ts +593 -0
- package/src/email/advanced/analytics.ts +445 -0
- package/src/email/advanced/index.ts +11 -0
- package/src/email/advanced/rules.ts +465 -0
- package/src/email/advanced/scheduling.ts +352 -0
- package/src/email/advanced/search.ts +412 -0
- package/src/email/advanced/shared-mailboxes.ts +404 -0
- package/src/email/advanced/templates.ts +455 -0
- package/src/email/advanced/threading.ts +281 -0
- package/src/email/analytics.ts +467 -0
- package/src/email/bounce-handling.ts +425 -0
- package/src/email/email.test.ts +431 -0
- package/src/email/handlers/__tests__/inbound.test.ts +38 -0
- package/src/email/handlers/__tests__/outbound.test.ts +37 -0
- package/src/email/handlers/converter.ts +227 -0
- package/src/email/handlers/feedback.ts +228 -0
- package/src/email/handlers/inbound.ts +169 -0
- package/src/email/handlers/outbound.ts +178 -0
- package/src/email/index.ts +15 -0
- package/src/email/reputation.ts +303 -0
- package/src/email/templates.ts +352 -0
- package/src/errors/index.test.ts +434 -0
- package/src/errors/index.ts +416 -0
- package/src/health-checks/index.ts +40 -0
- package/src/index.ts +360 -0
- package/src/intrinsic-functions.ts +118 -0
- package/src/lambda/concurrency.ts +330 -0
- package/src/lambda/destinations.ts +345 -0
- package/src/lambda/dlq.ts +425 -0
- package/src/lambda/index.ts +11 -0
- package/src/lambda/lambda.test.ts +840 -0
- package/src/lambda/layers.ts +263 -0
- package/src/lambda/versions.ts +376 -0
- package/src/lambda/vpc.ts +399 -0
- package/src/local/config.ts +114 -0
- package/src/local/index.ts +6 -0
- package/src/local/mock-aws.ts +351 -0
- package/src/modules/ai.ts +340 -0
- package/src/modules/api.ts +478 -0
- package/src/modules/auth.ts +805 -0
- package/src/modules/cache.ts +417 -0
- package/src/modules/cdn.ts +1062 -0
- package/src/modules/communication.ts +1094 -0
- package/src/modules/compute.ts +3348 -0
- package/src/modules/database.ts +554 -0
- package/src/modules/deployment.ts +1079 -0
- package/src/modules/dns.ts +337 -0
- package/src/modules/email.ts +1538 -0
- package/src/modules/filesystem.ts +515 -0
- package/src/modules/index.ts +32 -0
- package/src/modules/messaging.ts +486 -0
- package/src/modules/monitoring.ts +2086 -0
- package/src/modules/network.ts +664 -0
- package/src/modules/parameter-store.ts +325 -0
- package/src/modules/permissions.ts +1081 -0
- package/src/modules/phone.ts +494 -0
- package/src/modules/queue.ts +1260 -0
- package/src/modules/redirects.ts +464 -0
- package/src/modules/registry.ts +699 -0
- package/src/modules/search.ts +401 -0
- package/src/modules/secrets.ts +416 -0
- package/src/modules/security.ts +731 -0
- package/src/modules/sms.ts +389 -0
- package/src/modules/storage.ts +1120 -0
- package/src/modules/workflow.ts +680 -0
- package/src/multi-account/config.ts +521 -0
- package/src/multi-account/index.ts +7 -0
- package/src/multi-account/manager.ts +427 -0
- package/src/multi-region/cross-region.ts +410 -0
- package/src/multi-region/index.ts +8 -0
- package/src/multi-region/manager.ts +483 -0
- package/src/multi-region/regions.ts +435 -0
- package/src/network-security/index.ts +48 -0
- package/src/observability/index.ts +9 -0
- package/src/observability/logs.ts +522 -0
- package/src/observability/metrics.ts +460 -0
- package/src/observability/observability.test.ts +782 -0
- package/src/observability/synthetics.ts +568 -0
- package/src/observability/xray.ts +358 -0
- package/src/phone/advanced/analytics.ts +349 -0
- package/src/phone/advanced/callbacks.ts +428 -0
- package/src/phone/advanced/index.ts +8 -0
- package/src/phone/advanced/ivr-builder.ts +504 -0
- package/src/phone/advanced/recording.ts +310 -0
- package/src/phone/handlers/__tests__/incoming-call.test.ts +40 -0
- package/src/phone/handlers/incoming-call.ts +117 -0
- package/src/phone/handlers/missed-call.ts +116 -0
- package/src/phone/handlers/voicemail.ts +179 -0
- package/src/phone/index.ts +9 -0
- package/src/presets/api-backend.ts +134 -0
- package/src/presets/data-pipeline.ts +204 -0
- package/src/presets/extend.test.ts +295 -0
- package/src/presets/extend.ts +297 -0
- package/src/presets/fullstack-app.ts +144 -0
- package/src/presets/index.ts +27 -0
- package/src/presets/jamstack.ts +135 -0
- package/src/presets/microservices.ts +167 -0
- package/src/presets/ml-api.ts +208 -0
- package/src/presets/nodejs-server.ts +104 -0
- package/src/presets/nodejs-serverless.ts +114 -0
- package/src/presets/realtime-app.ts +184 -0
- package/src/presets/static-site.ts +64 -0
- package/src/presets/traditional-web-app.ts +339 -0
- package/src/presets/wordpress.ts +138 -0
- package/src/preview/github.test.ts +249 -0
- package/src/preview/github.ts +297 -0
- package/src/preview/index.ts +37 -0
- package/src/preview/manager.test.ts +440 -0
- package/src/preview/manager.ts +326 -0
- package/src/preview/notifications.test.ts +582 -0
- package/src/preview/notifications.ts +341 -0
- package/src/queue/batch-processing.ts +402 -0
- package/src/queue/dlq-monitoring.ts +402 -0
- package/src/queue/fifo.ts +342 -0
- package/src/queue/index.ts +9 -0
- package/src/queue/management.ts +428 -0
- package/src/queue/queue.test.ts +429 -0
- package/src/resource-mgmt/index.ts +39 -0
- package/src/resource-naming.ts +62 -0
- package/src/s3/index.ts +523 -0
- package/src/schema/cloud-config.schema.json +554 -0
- package/src/schema/index.ts +68 -0
- package/src/security/certificate-manager.ts +492 -0
- package/src/security/index.ts +9 -0
- package/src/security/scanning.ts +545 -0
- package/src/security/secrets-manager.ts +476 -0
- package/src/security/secrets-rotation.ts +456 -0
- package/src/security/security.test.ts +738 -0
- package/src/sms/advanced/ab-testing.ts +389 -0
- package/src/sms/advanced/analytics.ts +336 -0
- package/src/sms/advanced/campaigns.ts +523 -0
- package/src/sms/advanced/chatbot.ts +224 -0
- package/src/sms/advanced/index.ts +10 -0
- package/src/sms/advanced/link-tracking.ts +248 -0
- package/src/sms/advanced/mms.ts +308 -0
- package/src/sms/handlers/__tests__/send.test.ts +40 -0
- package/src/sms/handlers/delivery-status.ts +133 -0
- package/src/sms/handlers/receive.ts +162 -0
- package/src/sms/handlers/send.ts +174 -0
- package/src/sms/index.ts +9 -0
- package/src/stack-diff.ts +389 -0
- package/src/static-site/index.ts +85 -0
- package/src/template-builder.ts +110 -0
- package/src/template-validator.ts +574 -0
- package/src/utils/cache.ts +291 -0
- package/src/utils/diff.ts +269 -0
- package/src/utils/hash.ts +227 -0
- package/src/utils/index.ts +8 -0
- package/src/utils/parallel.ts +294 -0
- package/src/validators/credentials.test.ts +274 -0
- package/src/validators/credentials.ts +233 -0
- package/src/validators/quotas.test.ts +434 -0
- package/src/validators/quotas.ts +217 -0
|
@@ -0,0 +1,521 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-Account Configuration
|
|
3
|
+
* Best practices and configuration for multi-account setups
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { AWSAccount, CrossAccountRole } from './manager'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Account structure presets
|
|
10
|
+
*/
|
|
11
|
+
export interface AccountStructure {
|
|
12
|
+
name: string
|
|
13
|
+
description: string
|
|
14
|
+
accounts: AccountStructureDefinition[]
|
|
15
|
+
organizationalUnits?: OUDefinition[]
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface AccountStructureDefinition {
|
|
19
|
+
alias: string
|
|
20
|
+
email: string
|
|
21
|
+
role: AWSAccount['role']
|
|
22
|
+
ou?: string
|
|
23
|
+
description: string
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface OUDefinition {
|
|
27
|
+
name: string
|
|
28
|
+
parent?: string
|
|
29
|
+
policies?: string[]
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* AWS best practices: Multi-account structure
|
|
34
|
+
* Based on AWS Well-Architected Framework
|
|
35
|
+
*/
|
|
36
|
+
export const RECOMMENDED_ACCOUNT_STRUCTURES: Record<string, AccountStructure> = {
|
|
37
|
+
basic: {
|
|
38
|
+
name: 'Basic (3 Accounts)',
|
|
39
|
+
description: 'Simple structure for small teams',
|
|
40
|
+
accounts: [
|
|
41
|
+
{
|
|
42
|
+
alias: 'management',
|
|
43
|
+
email: 'aws+management@example.com',
|
|
44
|
+
role: 'management',
|
|
45
|
+
ou: 'root',
|
|
46
|
+
description: 'Management account for AWS Organizations',
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
alias: 'production',
|
|
50
|
+
email: 'aws+production@example.com',
|
|
51
|
+
role: 'production',
|
|
52
|
+
ou: 'workloads',
|
|
53
|
+
description: 'Production workloads',
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
alias: 'development',
|
|
57
|
+
email: 'aws+development@example.com',
|
|
58
|
+
role: 'development',
|
|
59
|
+
ou: 'workloads',
|
|
60
|
+
description: 'Development and testing',
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
organizationalUnits: [
|
|
64
|
+
{ name: 'root' },
|
|
65
|
+
{ name: 'workloads', parent: 'root' },
|
|
66
|
+
],
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
standard: {
|
|
70
|
+
name: 'Standard (5 Accounts)',
|
|
71
|
+
description: 'Recommended for most organizations',
|
|
72
|
+
accounts: [
|
|
73
|
+
{
|
|
74
|
+
alias: 'management',
|
|
75
|
+
email: 'aws+management@example.com',
|
|
76
|
+
role: 'management',
|
|
77
|
+
ou: 'root',
|
|
78
|
+
description: 'Management account',
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
alias: 'security',
|
|
82
|
+
email: 'aws+security@example.com',
|
|
83
|
+
role: 'security',
|
|
84
|
+
ou: 'security',
|
|
85
|
+
description: 'Security tooling and audit logs',
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
alias: 'shared-services',
|
|
89
|
+
email: 'aws+shared@example.com',
|
|
90
|
+
role: 'shared-services',
|
|
91
|
+
ou: 'infrastructure',
|
|
92
|
+
description: 'Shared services (CI/CD, monitoring)',
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
alias: 'production',
|
|
96
|
+
email: 'aws+production@example.com',
|
|
97
|
+
role: 'production',
|
|
98
|
+
ou: 'workloads',
|
|
99
|
+
description: 'Production environment',
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
alias: 'staging',
|
|
103
|
+
email: 'aws+staging@example.com',
|
|
104
|
+
role: 'staging',
|
|
105
|
+
ou: 'workloads',
|
|
106
|
+
description: 'Staging environment',
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
alias: 'development',
|
|
110
|
+
email: 'aws+development@example.com',
|
|
111
|
+
role: 'development',
|
|
112
|
+
ou: 'workloads',
|
|
113
|
+
description: 'Development environment',
|
|
114
|
+
},
|
|
115
|
+
],
|
|
116
|
+
organizationalUnits: [
|
|
117
|
+
{ name: 'root' },
|
|
118
|
+
{ name: 'security', parent: 'root' },
|
|
119
|
+
{ name: 'infrastructure', parent: 'root' },
|
|
120
|
+
{ name: 'workloads', parent: 'root' },
|
|
121
|
+
],
|
|
122
|
+
},
|
|
123
|
+
|
|
124
|
+
enterprise: {
|
|
125
|
+
name: 'Enterprise (7+ Accounts)',
|
|
126
|
+
description: 'For large organizations with strict compliance requirements',
|
|
127
|
+
accounts: [
|
|
128
|
+
{
|
|
129
|
+
alias: 'management',
|
|
130
|
+
email: 'aws+management@example.com',
|
|
131
|
+
role: 'management',
|
|
132
|
+
ou: 'root',
|
|
133
|
+
description: 'Management account',
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
alias: 'audit',
|
|
137
|
+
email: 'aws+audit@example.com',
|
|
138
|
+
role: 'security',
|
|
139
|
+
ou: 'security',
|
|
140
|
+
description: 'Audit and compliance',
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
alias: 'log-archive',
|
|
144
|
+
email: 'aws+logs@example.com',
|
|
145
|
+
role: 'security',
|
|
146
|
+
ou: 'security',
|
|
147
|
+
description: 'Centralized log storage',
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
alias: 'shared-services',
|
|
151
|
+
email: 'aws+shared@example.com',
|
|
152
|
+
role: 'shared-services',
|
|
153
|
+
ou: 'infrastructure',
|
|
154
|
+
description: 'Shared infrastructure',
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
alias: 'network',
|
|
158
|
+
email: 'aws+network@example.com',
|
|
159
|
+
role: 'shared-services',
|
|
160
|
+
ou: 'infrastructure',
|
|
161
|
+
description: 'Network infrastructure (Transit Gateway)',
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
alias: 'production',
|
|
165
|
+
email: 'aws+production@example.com',
|
|
166
|
+
role: 'production',
|
|
167
|
+
ou: 'production-ou',
|
|
168
|
+
description: 'Production workloads',
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
alias: 'staging',
|
|
172
|
+
email: 'aws+staging@example.com',
|
|
173
|
+
role: 'staging',
|
|
174
|
+
ou: 'non-production-ou',
|
|
175
|
+
description: 'Staging environment',
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
alias: 'development',
|
|
179
|
+
email: 'aws+development@example.com',
|
|
180
|
+
role: 'development',
|
|
181
|
+
ou: 'non-production-ou',
|
|
182
|
+
description: 'Development environment',
|
|
183
|
+
},
|
|
184
|
+
],
|
|
185
|
+
organizationalUnits: [
|
|
186
|
+
{ name: 'root' },
|
|
187
|
+
{ name: 'security', parent: 'root', policies: ['deny-root-access'] },
|
|
188
|
+
{ name: 'infrastructure', parent: 'root' },
|
|
189
|
+
{ name: 'production-ou', parent: 'root', policies: ['require-mfa'] },
|
|
190
|
+
{ name: 'non-production-ou', parent: 'root' },
|
|
191
|
+
],
|
|
192
|
+
},
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Service Control Policies (SCPs) - AWS best practices
|
|
197
|
+
*/
|
|
198
|
+
export const RECOMMENDED_SCPS = {
|
|
199
|
+
denyRootAccess: {
|
|
200
|
+
name: 'Deny Root User Access',
|
|
201
|
+
description: 'Prevent root user from performing any actions',
|
|
202
|
+
policyDocument: {
|
|
203
|
+
Version: '2012-10-17',
|
|
204
|
+
Statement: [
|
|
205
|
+
{
|
|
206
|
+
Sid: 'DenyRootUser',
|
|
207
|
+
Effect: 'Deny',
|
|
208
|
+
Action: '*',
|
|
209
|
+
Resource: '*',
|
|
210
|
+
Condition: {
|
|
211
|
+
StringLike: {
|
|
212
|
+
'aws:PrincipalArn': 'arn:aws:iam::*:root',
|
|
213
|
+
},
|
|
214
|
+
},
|
|
215
|
+
},
|
|
216
|
+
] as const,
|
|
217
|
+
},
|
|
218
|
+
},
|
|
219
|
+
|
|
220
|
+
requireMFA: {
|
|
221
|
+
name: 'Require MFA for All Actions',
|
|
222
|
+
description: 'Require MFA for console and API access',
|
|
223
|
+
policyDocument: {
|
|
224
|
+
Version: '2012-10-17',
|
|
225
|
+
Statement: [
|
|
226
|
+
{
|
|
227
|
+
Sid: 'RequireMFA',
|
|
228
|
+
Effect: 'Deny',
|
|
229
|
+
Action: '*',
|
|
230
|
+
Resource: '*',
|
|
231
|
+
Condition: {
|
|
232
|
+
BoolIfExists: {
|
|
233
|
+
'aws:MultiFactorAuthPresent': 'false',
|
|
234
|
+
},
|
|
235
|
+
},
|
|
236
|
+
},
|
|
237
|
+
] as const,
|
|
238
|
+
},
|
|
239
|
+
},
|
|
240
|
+
|
|
241
|
+
denyRegions: {
|
|
242
|
+
name: 'Deny Access to Non-Approved Regions',
|
|
243
|
+
description: 'Restrict operations to specific regions',
|
|
244
|
+
policyDocument: {
|
|
245
|
+
Version: '2012-10-17',
|
|
246
|
+
Statement: [
|
|
247
|
+
{
|
|
248
|
+
Sid: 'DenyNonApprovedRegions',
|
|
249
|
+
Effect: 'Deny',
|
|
250
|
+
NotAction: [
|
|
251
|
+
'iam:*',
|
|
252
|
+
'organizations:*',
|
|
253
|
+
'route53:*',
|
|
254
|
+
'cloudfront:*',
|
|
255
|
+
'support:*',
|
|
256
|
+
's3:*',
|
|
257
|
+
],
|
|
258
|
+
Resource: '*',
|
|
259
|
+
Condition: {
|
|
260
|
+
StringNotEquals: {
|
|
261
|
+
'aws:RequestedRegion': [
|
|
262
|
+
'us-east-1',
|
|
263
|
+
'us-west-2',
|
|
264
|
+
],
|
|
265
|
+
},
|
|
266
|
+
},
|
|
267
|
+
},
|
|
268
|
+
] as const,
|
|
269
|
+
},
|
|
270
|
+
},
|
|
271
|
+
|
|
272
|
+
preventLeaving: {
|
|
273
|
+
name: 'Prevent Leaving Organization',
|
|
274
|
+
description: 'Prevent accounts from leaving the organization',
|
|
275
|
+
policyDocument: {
|
|
276
|
+
Version: '2012-10-17',
|
|
277
|
+
Statement: [
|
|
278
|
+
{
|
|
279
|
+
Sid: 'PreventLeaving',
|
|
280
|
+
Effect: 'Deny',
|
|
281
|
+
Action: 'organizations:LeaveOrganization',
|
|
282
|
+
Resource: '*',
|
|
283
|
+
},
|
|
284
|
+
] as const,
|
|
285
|
+
},
|
|
286
|
+
},
|
|
287
|
+
|
|
288
|
+
denyS3Unencrypted: {
|
|
289
|
+
name: 'Deny Unencrypted S3 Uploads',
|
|
290
|
+
description: 'Require encryption for all S3 uploads',
|
|
291
|
+
policyDocument: {
|
|
292
|
+
Version: '2012-10-17',
|
|
293
|
+
Statement: [
|
|
294
|
+
{
|
|
295
|
+
Sid: 'DenyUnencryptedS3Uploads',
|
|
296
|
+
Effect: 'Deny',
|
|
297
|
+
Action: 's3:PutObject',
|
|
298
|
+
Resource: '*',
|
|
299
|
+
Condition: {
|
|
300
|
+
StringNotEquals: {
|
|
301
|
+
's3:x-amz-server-side-encryption': [
|
|
302
|
+
'AES256',
|
|
303
|
+
'aws:kms',
|
|
304
|
+
],
|
|
305
|
+
},
|
|
306
|
+
},
|
|
307
|
+
},
|
|
308
|
+
] as const,
|
|
309
|
+
},
|
|
310
|
+
},
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Common cross-account role configurations
|
|
315
|
+
*/
|
|
316
|
+
export const COMMON_CROSS_ACCOUNT_ROLES = {
|
|
317
|
+
deploymentRole: {
|
|
318
|
+
name: 'CrossAccountDeploymentRole',
|
|
319
|
+
description: 'Role for deploying infrastructure from CI/CD',
|
|
320
|
+
permissions: [
|
|
321
|
+
'cloudformation:*',
|
|
322
|
+
's3:*',
|
|
323
|
+
'ec2:*',
|
|
324
|
+
'ecs:*',
|
|
325
|
+
'lambda:*',
|
|
326
|
+
'iam:GetRole',
|
|
327
|
+
'iam:PassRole',
|
|
328
|
+
'logs:*',
|
|
329
|
+
'events:*',
|
|
330
|
+
] as const,
|
|
331
|
+
},
|
|
332
|
+
|
|
333
|
+
readOnlyRole: {
|
|
334
|
+
name: 'CrossAccountReadOnlyRole',
|
|
335
|
+
description: 'Read-only access for monitoring and auditing',
|
|
336
|
+
permissions: [
|
|
337
|
+
'cloudformation:Describe*',
|
|
338
|
+
'cloudformation:List*',
|
|
339
|
+
'ec2:Describe*',
|
|
340
|
+
'ecs:Describe*',
|
|
341
|
+
'lambda:Get*',
|
|
342
|
+
'lambda:List*',
|
|
343
|
+
's3:Get*',
|
|
344
|
+
's3:List*',
|
|
345
|
+
'logs:Get*',
|
|
346
|
+
'logs:Describe*',
|
|
347
|
+
] as const,
|
|
348
|
+
},
|
|
349
|
+
|
|
350
|
+
securityAuditRole: {
|
|
351
|
+
name: 'CrossAccountSecurityAuditRole',
|
|
352
|
+
description: 'Security audit and compliance checks',
|
|
353
|
+
permissions: [
|
|
354
|
+
'iam:Get*',
|
|
355
|
+
'iam:List*',
|
|
356
|
+
'iam:Generate*',
|
|
357
|
+
'access-analyzer:*',
|
|
358
|
+
'guardduty:Get*',
|
|
359
|
+
'guardduty:List*',
|
|
360
|
+
'securityhub:Get*',
|
|
361
|
+
'securityhub:List*',
|
|
362
|
+
'config:Describe*',
|
|
363
|
+
'config:Get*',
|
|
364
|
+
'config:List*',
|
|
365
|
+
] as const,
|
|
366
|
+
},
|
|
367
|
+
|
|
368
|
+
breakGlassRole: {
|
|
369
|
+
name: 'CrossAccountBreakGlassRole',
|
|
370
|
+
description: 'Emergency access role (use with caution)',
|
|
371
|
+
permissions: ['*'] as const,
|
|
372
|
+
},
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Get recommended account structure
|
|
377
|
+
*/
|
|
378
|
+
export function getRecommendedStructure(size: 'basic' | 'standard' | 'enterprise'): AccountStructure {
|
|
379
|
+
return RECOMMENDED_ACCOUNT_STRUCTURES[size]
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Generate cross-account role CloudFormation
|
|
384
|
+
*/
|
|
385
|
+
export function generateCrossAccountRoleCF(
|
|
386
|
+
role: CrossAccountRole,
|
|
387
|
+
managedPolicies?: string[],
|
|
388
|
+
): any {
|
|
389
|
+
return {
|
|
390
|
+
Type: 'AWS::IAM::Role',
|
|
391
|
+
Properties: {
|
|
392
|
+
RoleName: role.roleName,
|
|
393
|
+
AssumeRolePolicyDocument: {
|
|
394
|
+
Version: '2012-10-17',
|
|
395
|
+
Statement: [
|
|
396
|
+
{
|
|
397
|
+
Effect: 'Allow',
|
|
398
|
+
Principal: {
|
|
399
|
+
AWS: `arn:aws:iam::${role.sourceAccountId}:root`,
|
|
400
|
+
},
|
|
401
|
+
Action: 'sts:AssumeRole',
|
|
402
|
+
...(role.externalId && {
|
|
403
|
+
Condition: {
|
|
404
|
+
StringEquals: {
|
|
405
|
+
'sts:ExternalId': role.externalId,
|
|
406
|
+
},
|
|
407
|
+
},
|
|
408
|
+
}),
|
|
409
|
+
},
|
|
410
|
+
],
|
|
411
|
+
},
|
|
412
|
+
Policies: [
|
|
413
|
+
{
|
|
414
|
+
PolicyName: `${role.roleName}Policy`,
|
|
415
|
+
PolicyDocument: {
|
|
416
|
+
Version: '2012-10-17',
|
|
417
|
+
Statement: [
|
|
418
|
+
{
|
|
419
|
+
Effect: 'Allow',
|
|
420
|
+
Action: role.permissions,
|
|
421
|
+
Resource: '*',
|
|
422
|
+
},
|
|
423
|
+
],
|
|
424
|
+
},
|
|
425
|
+
},
|
|
426
|
+
],
|
|
427
|
+
...(managedPolicies && {
|
|
428
|
+
ManagedPolicyArns: managedPolicies,
|
|
429
|
+
}),
|
|
430
|
+
MaxSessionDuration: role.sessionDuration || 3600,
|
|
431
|
+
Tags: [
|
|
432
|
+
{ Key: 'ManagedBy', Value: 'TS-Cloud' },
|
|
433
|
+
{ Key: 'SourceAccount', Value: role.sourceAccountId },
|
|
434
|
+
],
|
|
435
|
+
},
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
/**
|
|
440
|
+
* Validate account structure
|
|
441
|
+
*/
|
|
442
|
+
export function validateAccountStructure(structure: AccountStructure): {
|
|
443
|
+
valid: boolean
|
|
444
|
+
errors: string[]
|
|
445
|
+
warnings: string[]
|
|
446
|
+
} {
|
|
447
|
+
const errors: string[] = []
|
|
448
|
+
const warnings: string[] = []
|
|
449
|
+
|
|
450
|
+
// Check for management account
|
|
451
|
+
const managementAccounts = structure.accounts.filter(a => a.role === 'management')
|
|
452
|
+
if (managementAccounts.length === 0) {
|
|
453
|
+
errors.push('No management account defined')
|
|
454
|
+
}
|
|
455
|
+
if (managementAccounts.length > 1) {
|
|
456
|
+
errors.push('Multiple management accounts defined')
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
// Check for duplicate emails
|
|
460
|
+
const emails = structure.accounts.map(a => a.email)
|
|
461
|
+
const duplicates = emails.filter((email, index) => emails.indexOf(email) !== index)
|
|
462
|
+
if (duplicates.length > 0) {
|
|
463
|
+
errors.push(`Duplicate email addresses: ${duplicates.join(', ')}`)
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
// Check for duplicate aliases
|
|
467
|
+
const aliases = structure.accounts.map(a => a.alias)
|
|
468
|
+
const duplicateAliases = aliases.filter((alias, index) => aliases.indexOf(alias) !== index)
|
|
469
|
+
if (duplicateAliases.length > 0) {
|
|
470
|
+
errors.push(`Duplicate aliases: ${duplicateAliases.join(', ')}`)
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
// Warnings for best practices
|
|
474
|
+
if (!structure.accounts.some(a => a.role === 'security')) {
|
|
475
|
+
warnings.push('No dedicated security account - consider adding one for audit logs')
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
if (structure.accounts.length < 3) {
|
|
479
|
+
warnings.push('Less than 3 accounts - consider separating environments')
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
if (!structure.accounts.some(a => a.role === 'production')) {
|
|
483
|
+
warnings.push('No production account defined')
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
return {
|
|
487
|
+
valid: errors.length === 0,
|
|
488
|
+
errors,
|
|
489
|
+
warnings,
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
/**
|
|
494
|
+
* Format account structure for display
|
|
495
|
+
*/
|
|
496
|
+
export function formatAccountStructure(structure: AccountStructure): string {
|
|
497
|
+
const lines: string[] = []
|
|
498
|
+
|
|
499
|
+
lines.push(`${structure.name}`)
|
|
500
|
+
lines.push('─'.repeat(structure.name.length))
|
|
501
|
+
lines.push(structure.description)
|
|
502
|
+
lines.push('')
|
|
503
|
+
|
|
504
|
+
if (structure.organizationalUnits) {
|
|
505
|
+
lines.push('Organizational Units:')
|
|
506
|
+
for (const ou of structure.organizationalUnits) {
|
|
507
|
+
const prefix = ou.parent ? ' └─ ' : ' '
|
|
508
|
+
lines.push(`${prefix}${ou.name}`)
|
|
509
|
+
}
|
|
510
|
+
lines.push('')
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
lines.push('Accounts:')
|
|
514
|
+
for (const account of structure.accounts) {
|
|
515
|
+
lines.push(` ${account.alias.padEnd(20)} ${account.role.padEnd(15)} ${account.email}`)
|
|
516
|
+
lines.push(` ${''.padEnd(20)} ${account.description}`)
|
|
517
|
+
lines.push('')
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
return lines.join('\n')
|
|
521
|
+
}
|