code-abyss 1.6.16 → 1.7.1

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 (97) hide show
  1. package/README.md +8 -6
  2. package/bin/install.js +59 -163
  3. package/bin/lib/ccline.js +82 -0
  4. package/bin/lib/utils.js +61 -0
  5. package/package.json +5 -2
  6. package/skills/SKILL.md +24 -16
  7. package/skills/domains/ai/SKILL.md +2 -2
  8. package/skills/domains/ai/prompt-and-eval.md +279 -0
  9. package/skills/domains/architecture/SKILL.md +2 -3
  10. package/skills/domains/architecture/security-arch.md +87 -0
  11. package/skills/domains/data-engineering/SKILL.md +188 -26
  12. package/skills/domains/development/SKILL.md +1 -4
  13. package/skills/domains/devops/SKILL.md +3 -5
  14. package/skills/domains/devops/performance.md +63 -0
  15. package/skills/domains/devops/testing.md +97 -0
  16. package/skills/domains/frontend-design/SKILL.md +12 -3
  17. package/skills/domains/frontend-design/claymorphism/SKILL.md +117 -0
  18. package/skills/domains/frontend-design/claymorphism/references/tokens.css +52 -0
  19. package/skills/domains/frontend-design/engineering.md +287 -0
  20. package/skills/domains/frontend-design/glassmorphism/SKILL.md +138 -0
  21. package/skills/domains/frontend-design/glassmorphism/references/tokens.css +32 -0
  22. package/skills/domains/frontend-design/liquid-glass/SKILL.md +135 -0
  23. package/skills/domains/frontend-design/liquid-glass/references/tokens.css +81 -0
  24. package/skills/domains/frontend-design/neubrutalism/SKILL.md +141 -0
  25. package/skills/domains/frontend-design/neubrutalism/references/tokens.css +44 -0
  26. package/skills/domains/infrastructure/SKILL.md +174 -34
  27. package/skills/domains/mobile/SKILL.md +211 -21
  28. package/skills/domains/orchestration/SKILL.md +1 -0
  29. package/skills/domains/security/SKILL.md +4 -6
  30. package/skills/domains/security/blue-team.md +57 -0
  31. package/skills/domains/security/red-team.md +54 -0
  32. package/skills/domains/security/threat-intel.md +50 -0
  33. package/skills/orchestration/multi-agent/SKILL.md +195 -46
  34. package/skills/run_skill.js +139 -0
  35. package/skills/tools/gen-docs/SKILL.md +6 -4
  36. package/skills/tools/gen-docs/scripts/doc_generator.js +363 -0
  37. package/skills/tools/lib/shared.js +98 -0
  38. package/skills/tools/verify-change/SKILL.md +8 -6
  39. package/skills/tools/verify-change/scripts/change_analyzer.js +289 -0
  40. package/skills/tools/verify-module/SKILL.md +6 -4
  41. package/skills/tools/verify-module/scripts/module_scanner.js +171 -0
  42. package/skills/tools/verify-quality/SKILL.md +5 -3
  43. package/skills/tools/verify-quality/scripts/quality_checker.js +337 -0
  44. package/skills/tools/verify-security/SKILL.md +7 -5
  45. package/skills/tools/verify-security/scripts/security_scanner.js +283 -0
  46. package/skills/__pycache__/run_skill.cpython-312.pyc +0 -0
  47. package/skills/domains/COVERAGE_PLAN.md +0 -232
  48. package/skills/domains/ai/model-evaluation.md +0 -790
  49. package/skills/domains/ai/prompt-engineering.md +0 -703
  50. package/skills/domains/architecture/compliance.md +0 -299
  51. package/skills/domains/architecture/data-security.md +0 -184
  52. package/skills/domains/data-engineering/data-pipeline.md +0 -762
  53. package/skills/domains/data-engineering/data-quality.md +0 -894
  54. package/skills/domains/data-engineering/stream-processing.md +0 -791
  55. package/skills/domains/development/dart.md +0 -963
  56. package/skills/domains/development/kotlin.md +0 -834
  57. package/skills/domains/development/php.md +0 -659
  58. package/skills/domains/development/swift.md +0 -755
  59. package/skills/domains/devops/e2e-testing.md +0 -914
  60. package/skills/domains/devops/performance-testing.md +0 -734
  61. package/skills/domains/devops/testing-strategy.md +0 -667
  62. package/skills/domains/frontend-design/build-tools.md +0 -743
  63. package/skills/domains/frontend-design/performance.md +0 -734
  64. package/skills/domains/frontend-design/testing.md +0 -699
  65. package/skills/domains/infrastructure/gitops.md +0 -735
  66. package/skills/domains/infrastructure/iac.md +0 -855
  67. package/skills/domains/infrastructure/kubernetes.md +0 -1018
  68. package/skills/domains/mobile/android-dev.md +0 -979
  69. package/skills/domains/mobile/cross-platform.md +0 -795
  70. package/skills/domains/mobile/ios-dev.md +0 -931
  71. package/skills/domains/security/secrets-management.md +0 -834
  72. package/skills/domains/security/supply-chain.md +0 -931
  73. package/skills/domains/security/threat-modeling.md +0 -828
  74. package/skills/run_skill.py +0 -153
  75. package/skills/tests/README.md +0 -225
  76. package/skills/tests/SUMMARY.md +0 -362
  77. package/skills/tests/__init__.py +0 -3
  78. package/skills/tests/__pycache__/test_change_analyzer.cpython-312.pyc +0 -0
  79. package/skills/tests/__pycache__/test_doc_generator.cpython-312.pyc +0 -0
  80. package/skills/tests/__pycache__/test_module_scanner.cpython-312.pyc +0 -0
  81. package/skills/tests/__pycache__/test_quality_checker.cpython-312.pyc +0 -0
  82. package/skills/tests/__pycache__/test_security_scanner.cpython-312.pyc +0 -0
  83. package/skills/tests/test_change_analyzer.py +0 -558
  84. package/skills/tests/test_doc_generator.py +0 -538
  85. package/skills/tests/test_module_scanner.py +0 -376
  86. package/skills/tests/test_quality_checker.py +0 -516
  87. package/skills/tests/test_security_scanner.py +0 -426
  88. package/skills/tools/gen-docs/scripts/__pycache__/doc_generator.cpython-312.pyc +0 -0
  89. package/skills/tools/gen-docs/scripts/doc_generator.py +0 -520
  90. package/skills/tools/verify-change/scripts/__pycache__/change_analyzer.cpython-312.pyc +0 -0
  91. package/skills/tools/verify-change/scripts/change_analyzer.py +0 -529
  92. package/skills/tools/verify-module/scripts/__pycache__/module_scanner.cpython-312.pyc +0 -0
  93. package/skills/tools/verify-module/scripts/module_scanner.py +0 -321
  94. package/skills/tools/verify-quality/scripts/__pycache__/quality_checker.cpython-312.pyc +0 -0
  95. package/skills/tools/verify-quality/scripts/quality_checker.py +0 -481
  96. package/skills/tools/verify-security/scripts/__pycache__/security_scanner.cpython-312.pyc +0 -0
  97. package/skills/tools/verify-security/scripts/security_scanner.py +0 -374
@@ -1,855 +0,0 @@
1
- ---
2
- name: iac
3
- description: 基础设施即代码。Terraform、Pulumi、AWS CDK、状态管理、模块开发、远程后端。当用户提到 IaC、Terraform、Pulumi、CDK、基础设施即代码、状态管理时使用。
4
- ---
5
-
6
- # 🏗️ 基础设施即代码 · IaC
7
-
8
- ## Terraform
9
-
10
- ### 项目结构
11
- ```
12
- terraform/
13
- ├── modules/
14
- │ ├── vpc/
15
- │ │ ├── main.tf
16
- │ │ ├── variables.tf
17
- │ │ └── outputs.tf
18
- │ ├── eks/
19
- │ └── rds/
20
- ├── environments/
21
- │ ├── dev/
22
- │ │ ├── main.tf
23
- │ │ ├── variables.tf
24
- │ │ ├── terraform.tfvars
25
- │ │ └── backend.tf
26
- │ ├── staging/
27
- │ └── production/
28
- └── .terraform.lock.hcl
29
- ```
30
-
31
- ### Provider 配置
32
- ```hcl
33
- # versions.tf
34
- terraform {
35
- required_version = ">= 1.5.0"
36
-
37
- required_providers {
38
- aws = {
39
- source = "hashicorp/aws"
40
- version = "~> 5.0"
41
- }
42
- kubernetes = {
43
- source = "hashicorp/kubernetes"
44
- version = "~> 2.23"
45
- }
46
- helm = {
47
- source = "hashicorp/helm"
48
- version = "~> 2.11"
49
- }
50
- }
51
-
52
- backend "s3" {
53
- bucket = "mycompany-terraform-state"
54
- key = "production/terraform.tfstate"
55
- region = "us-west-2"
56
- encrypt = true
57
- dynamodb_table = "terraform-state-lock"
58
- kms_key_id = "arn:aws:kms:us-west-2:123456789012:key/..."
59
- }
60
- }
61
-
62
- provider "aws" {
63
- region = var.aws_region
64
-
65
- default_tags {
66
- tags = {
67
- Environment = var.environment
68
- ManagedBy = "Terraform"
69
- Project = var.project_name
70
- }
71
- }
72
- }
73
- ```
74
-
75
- ### VPC 模块
76
- ```hcl
77
- # modules/vpc/main.tf
78
- resource "aws_vpc" "main" {
79
- cidr_block = var.vpc_cidr
80
- enable_dns_hostnames = true
81
- enable_dns_support = true
82
-
83
- tags = {
84
- Name = "${var.name_prefix}-vpc"
85
- }
86
- }
87
-
88
- resource "aws_subnet" "public" {
89
- count = length(var.public_subnet_cidrs)
90
- vpc_id = aws_vpc.main.id
91
- cidr_block = var.public_subnet_cidrs[count.index]
92
- availability_zone = var.availability_zones[count.index]
93
- map_public_ip_on_launch = true
94
-
95
- tags = {
96
- Name = "${var.name_prefix}-public-${count.index + 1}"
97
- "kubernetes.io/role/elb" = "1"
98
- "kubernetes.io/cluster/${var.cluster_name}" = "shared"
99
- }
100
- }
101
-
102
- resource "aws_subnet" "private" {
103
- count = length(var.private_subnet_cidrs)
104
- vpc_id = aws_vpc.main.id
105
- cidr_block = var.private_subnet_cidrs[count.index]
106
- availability_zone = var.availability_zones[count.index]
107
-
108
- tags = {
109
- Name = "${var.name_prefix}-private-${count.index + 1}"
110
- "kubernetes.io/role/internal-elb" = "1"
111
- "kubernetes.io/cluster/${var.cluster_name}" = "shared"
112
- }
113
- }
114
-
115
- resource "aws_internet_gateway" "main" {
116
- vpc_id = aws_vpc.main.id
117
-
118
- tags = {
119
- Name = "${var.name_prefix}-igw"
120
- }
121
- }
122
-
123
- resource "aws_eip" "nat" {
124
- count = var.enable_nat_gateway ? length(var.public_subnet_cidrs) : 0
125
- domain = "vpc"
126
-
127
- tags = {
128
- Name = "${var.name_prefix}-nat-eip-${count.index + 1}"
129
- }
130
- }
131
-
132
- resource "aws_nat_gateway" "main" {
133
- count = var.enable_nat_gateway ? length(var.public_subnet_cidrs) : 0
134
- allocation_id = aws_eip.nat[count.index].id
135
- subnet_id = aws_subnet.public[count.index].id
136
-
137
- tags = {
138
- Name = "${var.name_prefix}-nat-${count.index + 1}"
139
- }
140
-
141
- depends_on = [aws_internet_gateway.main]
142
- }
143
-
144
- # modules/vpc/variables.tf
145
- variable "name_prefix" {
146
- description = "Prefix for resource names"
147
- type = string
148
- }
149
-
150
- variable "vpc_cidr" {
151
- description = "CIDR block for VPC"
152
- type = string
153
- default = "10.0.0.0/16"
154
- }
155
-
156
- variable "public_subnet_cidrs" {
157
- description = "CIDR blocks for public subnets"
158
- type = list(string)
159
- }
160
-
161
- variable "private_subnet_cidrs" {
162
- description = "CIDR blocks for private subnets"
163
- type = list(string)
164
- }
165
-
166
- variable "availability_zones" {
167
- description = "Availability zones"
168
- type = list(string)
169
- }
170
-
171
- variable "enable_nat_gateway" {
172
- description = "Enable NAT Gateway"
173
- type = bool
174
- default = true
175
- }
176
-
177
- variable "cluster_name" {
178
- description = "EKS cluster name for tagging"
179
- type = string
180
- }
181
-
182
- # modules/vpc/outputs.tf
183
- output "vpc_id" {
184
- description = "VPC ID"
185
- value = aws_vpc.main.id
186
- }
187
-
188
- output "public_subnet_ids" {
189
- description = "Public subnet IDs"
190
- value = aws_subnet.public[*].id
191
- }
192
-
193
- output "private_subnet_ids" {
194
- description = "Private subnet IDs"
195
- value = aws_subnet.private[*].id
196
- }
197
- ```
198
-
199
- ### EKS 模块
200
- ```hcl
201
- # modules/eks/main.tf
202
- resource "aws_eks_cluster" "main" {
203
- name = var.cluster_name
204
- role_arn = aws_iam_role.cluster.arn
205
- version = var.kubernetes_version
206
-
207
- vpc_config {
208
- subnet_ids = concat(var.public_subnet_ids, var.private_subnet_ids)
209
- endpoint_private_access = true
210
- endpoint_public_access = var.endpoint_public_access
211
- public_access_cidrs = var.public_access_cidrs
212
- }
213
-
214
- enabled_cluster_log_types = ["api", "audit", "authenticator", "controllerManager", "scheduler"]
215
-
216
- encryption_config {
217
- provider {
218
- key_arn = var.kms_key_arn
219
- }
220
- resources = ["secrets"]
221
- }
222
-
223
- depends_on = [
224
- aws_iam_role_policy_attachment.cluster_policy,
225
- aws_cloudwatch_log_group.cluster,
226
- ]
227
- }
228
-
229
- resource "aws_eks_node_group" "main" {
230
- cluster_name = aws_eks_cluster.main.name
231
- node_group_name = "${var.cluster_name}-node-group"
232
- node_role_arn = aws_iam_role.node.arn
233
- subnet_ids = var.private_subnet_ids
234
-
235
- scaling_config {
236
- desired_size = var.desired_size
237
- max_size = var.max_size
238
- min_size = var.min_size
239
- }
240
-
241
- instance_types = var.instance_types
242
- capacity_type = var.capacity_type
243
- disk_size = var.disk_size
244
-
245
- update_config {
246
- max_unavailable_percentage = 33
247
- }
248
-
249
- labels = var.node_labels
250
-
251
- tags = {
252
- Name = "${var.cluster_name}-node-group"
253
- }
254
-
255
- depends_on = [
256
- aws_iam_role_policy_attachment.node_policy,
257
- ]
258
- }
259
-
260
- resource "aws_iam_role" "cluster" {
261
- name = "${var.cluster_name}-cluster-role"
262
-
263
- assume_role_policy = jsonencode({
264
- Version = "2012-10-17"
265
- Statement = [{
266
- Action = "sts:AssumeRole"
267
- Effect = "Allow"
268
- Principal = {
269
- Service = "eks.amazonaws.com"
270
- }
271
- }]
272
- })
273
- }
274
-
275
- resource "aws_iam_role_policy_attachment" "cluster_policy" {
276
- policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"
277
- role = aws_iam_role.cluster.name
278
- }
279
-
280
- resource "aws_cloudwatch_log_group" "cluster" {
281
- name = "/aws/eks/${var.cluster_name}/cluster"
282
- retention_in_days = var.log_retention_days
283
- kms_key_id = var.kms_key_arn
284
- }
285
- ```
286
-
287
- ### 环境配置
288
- ```hcl
289
- # environments/production/main.tf
290
- module "vpc" {
291
- source = "../../modules/vpc"
292
-
293
- name_prefix = "myapp-prod"
294
- vpc_cidr = "10.0.0.0/16"
295
- public_subnet_cidrs = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
296
- private_subnet_cidrs = ["10.0.11.0/24", "10.0.12.0/24", "10.0.13.0/24"]
297
- availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"]
298
- enable_nat_gateway = true
299
- cluster_name = "myapp-prod"
300
- }
301
-
302
- module "eks" {
303
- source = "../../modules/eks"
304
-
305
- cluster_name = "myapp-prod"
306
- kubernetes_version = "1.28"
307
- vpc_id = module.vpc.vpc_id
308
- public_subnet_ids = module.vpc.public_subnet_ids
309
- private_subnet_ids = module.vpc.private_subnet_ids
310
- endpoint_public_access = false
311
-
312
- desired_size = 3
313
- min_size = 3
314
- max_size = 10
315
- instance_types = ["t3.large"]
316
- capacity_type = "ON_DEMAND"
317
-
318
- kms_key_arn = aws_kms_key.eks.arn
319
- }
320
-
321
- # environments/production/terraform.tfvars
322
- aws_region = "us-west-2"
323
- environment = "production"
324
- project_name = "myapp"
325
- ```
326
-
327
- ### Terraform 命令
328
- ```bash
329
- # 初始化
330
- terraform init
331
-
332
- # 验证配置
333
- terraform validate
334
-
335
- # 格式化代码
336
- terraform fmt -recursive
337
-
338
- # 查看计划
339
- terraform plan -out=tfplan
340
-
341
- # 应用变更
342
- terraform apply tfplan
343
-
344
- # 查看状态
345
- terraform show
346
-
347
- # 查看输出
348
- terraform output
349
-
350
- # 导入现有资源
351
- terraform import aws_vpc.main vpc-12345678
352
-
353
- # 销毁资源
354
- terraform destroy
355
-
356
- # 状态管理
357
- terraform state list
358
- terraform state show aws_vpc.main
359
- terraform state mv aws_vpc.old aws_vpc.new
360
- terraform state rm aws_vpc.unused
361
-
362
- # Workspace 管理
363
- terraform workspace list
364
- terraform workspace new production
365
- terraform workspace select production
366
- ```
367
-
368
- ### 远程状态数据源
369
- ```hcl
370
- data "terraform_remote_state" "vpc" {
371
- backend = "s3"
372
- config = {
373
- bucket = "mycompany-terraform-state"
374
- key = "vpc/terraform.tfstate"
375
- region = "us-west-2"
376
- }
377
- }
378
-
379
- resource "aws_instance" "app" {
380
- subnet_id = data.terraform_remote_state.vpc.outputs.private_subnet_ids[0]
381
- }
382
- ```
383
-
384
- ## Pulumi
385
-
386
- ### 项目结构
387
- ```
388
- pulumi/
389
- ├── __main__.py
390
- ├── Pulumi.yaml
391
- ├── Pulumi.dev.yaml
392
- ├── Pulumi.prod.yaml
393
- ├── requirements.txt
394
- └── modules/
395
- ├── vpc.py
396
- ├── eks.py
397
- └── rds.py
398
- ```
399
-
400
- ### Pulumi.yaml
401
- ```yaml
402
- name: myapp-infrastructure
403
- runtime: python
404
- description: Infrastructure for MyApp
405
- ```
406
-
407
- ### VPC 模块 (Python)
408
- ```python
409
- # modules/vpc.py
410
- import pulumi
411
- import pulumi_aws as aws
412
-
413
- class VpcArgs:
414
- def __init__(self,
415
- name_prefix: str,
416
- cidr_block: str = "10.0.0.0/16",
417
- availability_zones: list = None,
418
- public_subnet_cidrs: list = None,
419
- private_subnet_cidrs: list = None):
420
- self.name_prefix = name_prefix
421
- self.cidr_block = cidr_block
422
- self.availability_zones = availability_zones or ["us-west-2a", "us-west-2b"]
423
- self.public_subnet_cidrs = public_subnet_cidrs or ["10.0.1.0/24", "10.0.2.0/24"]
424
- self.private_subnet_cidrs = private_subnet_cidrs or ["10.0.11.0/24", "10.0.12.0/24"]
425
-
426
- class Vpc(pulumi.ComponentResource):
427
- def __init__(self, name: str, args: VpcArgs, opts=None):
428
- super().__init__("custom:network:Vpc", name, {}, opts)
429
-
430
- # VPC
431
- self.vpc = aws.ec2.Vpc(
432
- f"{name}-vpc",
433
- cidr_block=args.cidr_block,
434
- enable_dns_hostnames=True,
435
- enable_dns_support=True,
436
- tags={"Name": f"{args.name_prefix}-vpc"},
437
- opts=pulumi.ResourceOptions(parent=self)
438
- )
439
-
440
- # Internet Gateway
441
- self.igw = aws.ec2.InternetGateway(
442
- f"{name}-igw",
443
- vpc_id=self.vpc.id,
444
- tags={"Name": f"{args.name_prefix}-igw"},
445
- opts=pulumi.ResourceOptions(parent=self)
446
- )
447
-
448
- # Public Subnets
449
- self.public_subnets = []
450
- for i, (az, cidr) in enumerate(zip(args.availability_zones, args.public_subnet_cidrs)):
451
- subnet = aws.ec2.Subnet(
452
- f"{name}-public-{i}",
453
- vpc_id=self.vpc.id,
454
- cidr_block=cidr,
455
- availability_zone=az,
456
- map_public_ip_on_launch=True,
457
- tags={"Name": f"{args.name_prefix}-public-{i}"},
458
- opts=pulumi.ResourceOptions(parent=self)
459
- )
460
- self.public_subnets.append(subnet)
461
-
462
- # Private Subnets
463
- self.private_subnets = []
464
- for i, (az, cidr) in enumerate(zip(args.availability_zones, args.private_subnet_cidrs)):
465
- subnet = aws.ec2.Subnet(
466
- f"{name}-private-{i}",
467
- vpc_id=self.vpc.id,
468
- cidr_block=cidr,
469
- availability_zone=az,
470
- tags={"Name": f"{args.name_prefix}-private-{i}"},
471
- opts=pulumi.ResourceOptions(parent=self)
472
- )
473
- self.private_subnets.append(subnet)
474
-
475
- # NAT Gateways
476
- self.nat_gateways = []
477
- for i, subnet in enumerate(self.public_subnets):
478
- eip = aws.ec2.Eip(
479
- f"{name}-nat-eip-{i}",
480
- domain="vpc",
481
- tags={"Name": f"{args.name_prefix}-nat-eip-{i}"},
482
- opts=pulumi.ResourceOptions(parent=self)
483
- )
484
-
485
- nat = aws.ec2.NatGateway(
486
- f"{name}-nat-{i}",
487
- allocation_id=eip.id,
488
- subnet_id=subnet.id,
489
- tags={"Name": f"{args.name_prefix}-nat-{i}"},
490
- opts=pulumi.ResourceOptions(parent=self, depends_on=[self.igw])
491
- )
492
- self.nat_gateways.append(nat)
493
-
494
- self.register_outputs({
495
- "vpc_id": self.vpc.id,
496
- "public_subnet_ids": [s.id for s in self.public_subnets],
497
- "private_subnet_ids": [s.id for s in self.private_subnets],
498
- })
499
- ```
500
-
501
- ### EKS 模块 (Python)
502
- ```python
503
- # modules/eks.py
504
- import pulumi
505
- import pulumi_aws as aws
506
- import pulumi_eks as eks
507
-
508
- class EksArgs:
509
- def __init__(self,
510
- cluster_name: str,
511
- vpc_id: pulumi.Output,
512
- public_subnet_ids: list,
513
- private_subnet_ids: list,
514
- desired_capacity: int = 3,
515
- min_size: int = 2,
516
- max_size: int = 10,
517
- instance_type: str = "t3.medium"):
518
- self.cluster_name = cluster_name
519
- self.vpc_id = vpc_id
520
- self.public_subnet_ids = public_subnet_ids
521
- self.private_subnet_ids = private_subnet_ids
522
- self.desired_capacity = desired_capacity
523
- self.min_size = min_size
524
- self.max_size = max_size
525
- self.instance_type = instance_type
526
-
527
- class EksCluster(pulumi.ComponentResource):
528
- def __init__(self, name: str, args: EksArgs, opts=None):
529
- super().__init__("custom:kubernetes:EksCluster", name, {}, opts)
530
-
531
- # EKS Cluster
532
- self.cluster = eks.Cluster(
533
- name,
534
- vpc_id=args.vpc_id,
535
- public_subnet_ids=args.public_subnet_ids,
536
- private_subnet_ids=args.private_subnet_ids,
537
- instance_type=args.instance_type,
538
- desired_capacity=args.desired_capacity,
539
- min_size=args.min_size,
540
- max_size=args.max_size,
541
- enabled_cluster_log_types=["api", "audit", "authenticator"],
542
- opts=pulumi.ResourceOptions(parent=self)
543
- )
544
-
545
- self.register_outputs({
546
- "cluster_name": self.cluster.core.cluster.name,
547
- "kubeconfig": self.cluster.kubeconfig,
548
- })
549
- ```
550
-
551
- ### 主程序
552
- ```python
553
- # __main__.py
554
- import pulumi
555
- import pulumi_aws as aws
556
- from modules.vpc import Vpc, VpcArgs
557
- from modules.eks import EksCluster, EksArgs
558
-
559
- # 配置
560
- config = pulumi.Config()
561
- environment = pulumi.get_stack()
562
- project_name = pulumi.get_project()
563
-
564
- # VPC
565
- vpc = Vpc(
566
- "myapp-vpc",
567
- VpcArgs(
568
- name_prefix=f"{project_name}-{environment}",
569
- cidr_block="10.0.0.0/16",
570
- availability_zones=["us-west-2a", "us-west-2b", "us-west-2c"],
571
- public_subnet_cidrs=["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"],
572
- private_subnet_cidrs=["10.0.11.0/24", "10.0.12.0/24", "10.0.13.0/24"],
573
- )
574
- )
575
-
576
- # EKS
577
- eks_cluster = EksCluster(
578
- "myapp-eks",
579
- EksArgs(
580
- cluster_name=f"{project_name}-{environment}",
581
- vpc_id=vpc.vpc.id,
582
- public_subnet_ids=[s.id for s in vpc.public_subnets],
583
- private_subnet_ids=[s.id for s in vpc.private_subnets],
584
- desired_capacity=config.get_int("desired_capacity") or 3,
585
- min_size=config.get_int("min_size") or 2,
586
- max_size=config.get_int("max_size") or 10,
587
- instance_type=config.get("instance_type") or "t3.medium",
588
- )
589
- )
590
-
591
- # Outputs
592
- pulumi.export("vpc_id", vpc.vpc.id)
593
- pulumi.export("cluster_name", eks_cluster.cluster.core.cluster.name)
594
- pulumi.export("kubeconfig", eks_cluster.cluster.kubeconfig)
595
- ```
596
-
597
- ### Pulumi 命令
598
- ```bash
599
- # 初始化项目
600
- pulumi new aws-python
601
-
602
- # 配置
603
- pulumi config set aws:region us-west-2
604
- pulumi config set desired_capacity 5 --stack production
605
-
606
- # 预览变更
607
- pulumi preview
608
-
609
- # 应用变更
610
- pulumi up
611
-
612
- # 查看输出
613
- pulumi stack output kubeconfig
614
-
615
- # 查看资源
616
- pulumi stack
617
-
618
- # 销毁资源
619
- pulumi destroy
620
-
621
- # Stack 管理
622
- pulumi stack ls
623
- pulumi stack select production
624
- pulumi stack init staging
625
-
626
- # 导出/导入状态
627
- pulumi stack export > state.json
628
- pulumi stack import < state.json
629
- ```
630
-
631
- ## AWS CDK
632
-
633
- ### 项目结构
634
- ```
635
- cdk/
636
- ├── app.py
637
- ├── cdk.json
638
- ├── requirements.txt
639
- └── stacks/
640
- ├── vpc_stack.py
641
- ├── eks_stack.py
642
- └── rds_stack.py
643
- ```
644
-
645
- ### VPC Stack (Python)
646
- ```python
647
- # stacks/vpc_stack.py
648
- from aws_cdk import (
649
- Stack,
650
- aws_ec2 as ec2,
651
- )
652
- from constructs import Construct
653
-
654
- class VpcStack(Stack):
655
- def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
656
- super().__init__(scope, construct_id, **kwargs)
657
-
658
- # VPC
659
- self.vpc = ec2.Vpc(
660
- self, "MyVpc",
661
- max_azs=3,
662
- cidr="10.0.0.0/16",
663
- subnet_configuration=[
664
- ec2.SubnetConfiguration(
665
- name="Public",
666
- subnet_type=ec2.SubnetType.PUBLIC,
667
- cidr_mask=24,
668
- ),
669
- ec2.SubnetConfiguration(
670
- name="Private",
671
- subnet_type=ec2.SubnetType.PRIVATE_WITH_EGRESS,
672
- cidr_mask=24,
673
- ),
674
- ],
675
- nat_gateways=3,
676
- )
677
- ```
678
-
679
- ### EKS Stack (Python)
680
- ```python
681
- # stacks/eks_stack.py
682
- from aws_cdk import (
683
- Stack,
684
- aws_eks as eks,
685
- aws_ec2 as ec2,
686
- aws_iam as iam,
687
- )
688
- from constructs import Construct
689
-
690
- class EksStack(Stack):
691
- def __init__(self, scope: Construct, construct_id: str, vpc: ec2.Vpc, **kwargs) -> None:
692
- super().__init__(scope, construct_id, **kwargs)
693
-
694
- # EKS Cluster
695
- self.cluster = eks.Cluster(
696
- self, "MyCluster",
697
- version=eks.KubernetesVersion.V1_28,
698
- vpc=vpc,
699
- default_capacity=0,
700
- cluster_logging=[
701
- eks.ClusterLoggingTypes.API,
702
- eks.ClusterLoggingTypes.AUDIT,
703
- eks.ClusterLoggingTypes.AUTHENTICATOR,
704
- ],
705
- )
706
-
707
- # Node Group
708
- self.cluster.add_nodegroup_capacity(
709
- "NodeGroup",
710
- instance_types=[ec2.InstanceType("t3.medium")],
711
- min_size=2,
712
- max_size=10,
713
- desired_size=3,
714
- disk_size=50,
715
- )
716
-
717
- # Helm Chart
718
- self.cluster.add_helm_chart(
719
- "NginxIngress",
720
- chart="ingress-nginx",
721
- repository="https://kubernetes.github.io/ingress-nginx",
722
- namespace="ingress-nginx",
723
- create_namespace=True,
724
- )
725
- ```
726
-
727
- ### App
728
- ```python
729
- # app.py
730
- import aws_cdk as cdk
731
- from stacks.vpc_stack import VpcStack
732
- from stacks.eks_stack import EksStack
733
-
734
- app = cdk.App()
735
-
736
- env = cdk.Environment(
737
- account="123456789012",
738
- region="us-west-2"
739
- )
740
-
741
- vpc_stack = VpcStack(app, "VpcStack", env=env)
742
- eks_stack = EksStack(app, "EksStack", vpc=vpc_stack.vpc, env=env)
743
-
744
- app.synth()
745
- ```
746
-
747
- ### CDK 命令
748
- ```bash
749
- # 初始化项目
750
- cdk init app --language python
751
-
752
- # 安装依赖
753
- pip install -r requirements.txt
754
-
755
- # 合成 CloudFormation
756
- cdk synth
757
-
758
- # 查看差异
759
- cdk diff
760
-
761
- # 部署
762
- cdk deploy --all
763
-
764
- # 销毁
765
- cdk destroy --all
766
-
767
- # Bootstrap (首次使用)
768
- cdk bootstrap aws://123456789012/us-west-2
769
- ```
770
-
771
- ## 状态管理
772
-
773
- ### Terraform 远程后端
774
- ```hcl
775
- # S3 + DynamoDB
776
- terraform {
777
- backend "s3" {
778
- bucket = "mycompany-terraform-state"
779
- key = "production/terraform.tfstate"
780
- region = "us-west-2"
781
- encrypt = true
782
- dynamodb_table = "terraform-state-lock"
783
- kms_key_id = "arn:aws:kms:us-west-2:123456789012:key/..."
784
- }
785
- }
786
-
787
- # Terraform Cloud
788
- terraform {
789
- backend "remote" {
790
- organization = "mycompany"
791
- workspaces {
792
- name = "production"
793
- }
794
- }
795
- }
796
- ```
797
-
798
- ### 状态锁定
799
- ```bash
800
- # 创建 DynamoDB 表
801
- aws dynamodb create-table \
802
- --table-name terraform-state-lock \
803
- --attribute-definitions AttributeName=LockID,AttributeType=S \
804
- --key-schema AttributeName=LockID,KeyType=HASH \
805
- --billing-mode PAY_PER_REQUEST
806
- ```
807
-
808
- ### 状态迁移
809
- ```bash
810
- # 从本地迁移到 S3
811
- terraform init -migrate-state
812
-
813
- # 手动拉取状态
814
- terraform state pull > terraform.tfstate
815
-
816
- # 手动推送状态
817
- terraform state push terraform.tfstate
818
- ```
819
-
820
- ## 最佳实践
821
-
822
- | 实践 | 说明 |
823
- |------|------|
824
- | 模块化 | 将可复用组件抽象为模块 |
825
- | 环境隔离 | 不同环境使用不同 State |
826
- | 远程状态 | 使用 S3/Terraform Cloud 存储状态 |
827
- | 状态锁定 | 使用 DynamoDB 防止并发修改 |
828
- | 版本控制 | Provider 版本锁定 |
829
- | 密钥管理 | 使用 AWS Secrets Manager/SSM |
830
- | 标签规范 | 统一资源标签 |
831
- | 变更审查 | Plan 后人工审查再 Apply |
832
- | 自动化 | CI/CD 集成 |
833
- | 文档化 | 模块添加 README 和示例 |
834
-
835
- ## 工具对比
836
-
837
- | 工具 | 语言 | 状态管理 | 云支持 | 学习曲线 |
838
- |------|------|----------|---------|----------|
839
- | Terraform | HCL | 显式 | 全平台 | 中等 |
840
- | Pulumi | 多语言 | 自动 | 全平台 | 较低 |
841
- | AWS CDK | 多语言 | CloudFormation | AWS | 中等 |
842
- | CloudFormation | YAML/JSON | AWS 托管 | AWS | 较高 |
843
-
844
- ## 工具清单
845
-
846
- | 工具 | 用途 |
847
- |------|------|
848
- | Terraform | 多云 IaC |
849
- | Pulumi | 编程语言 IaC |
850
- | AWS CDK | AWS 原生 IaC |
851
- | Terragrunt | Terraform 包装器 |
852
- | Atlantis | Terraform PR 自动化 |
853
- | Infracost | 成本估算 |
854
- | Checkov | 安全扫描 |
855
- | tfsec | Terraform 安全扫描 |