@frontpoint/aws-infra-mcp 0.1.0

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 (63) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +141 -0
  3. package/dist/core/aws-analyzer.d.ts +73 -0
  4. package/dist/core/aws-analyzer.d.ts.map +1 -0
  5. package/dist/core/aws-analyzer.js +429 -0
  6. package/dist/core/aws-analyzer.js.map +1 -0
  7. package/dist/core/cdk-generator.d.ts +26 -0
  8. package/dist/core/cdk-generator.d.ts.map +1 -0
  9. package/dist/core/cdk-generator.js +790 -0
  10. package/dist/core/cdk-generator.js.map +1 -0
  11. package/dist/core/template-engine.d.ts +32 -0
  12. package/dist/core/template-engine.d.ts.map +1 -0
  13. package/dist/core/template-engine.js +131 -0
  14. package/dist/core/template-engine.js.map +1 -0
  15. package/dist/index.d.ts +9 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +62 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/server.d.ts +21 -0
  20. package/dist/server.d.ts.map +1 -0
  21. package/dist/server.js +158 -0
  22. package/dist/server.js.map +1 -0
  23. package/dist/tools/aws-add-compute.d.ts +8 -0
  24. package/dist/tools/aws-add-compute.d.ts.map +1 -0
  25. package/dist/tools/aws-add-compute.js +269 -0
  26. package/dist/tools/aws-add-compute.js.map +1 -0
  27. package/dist/tools/aws-add-database.d.ts +8 -0
  28. package/dist/tools/aws-add-database.d.ts.map +1 -0
  29. package/dist/tools/aws-add-database.js +230 -0
  30. package/dist/tools/aws-add-database.js.map +1 -0
  31. package/dist/tools/aws-add-network.d.ts +8 -0
  32. package/dist/tools/aws-add-network.d.ts.map +1 -0
  33. package/dist/tools/aws-add-network.js +240 -0
  34. package/dist/tools/aws-add-network.js.map +1 -0
  35. package/dist/tools/aws-add-storage.d.ts +8 -0
  36. package/dist/tools/aws-add-storage.d.ts.map +1 -0
  37. package/dist/tools/aws-add-storage.js +207 -0
  38. package/dist/tools/aws-add-storage.js.map +1 -0
  39. package/dist/tools/aws-analyze.d.ts +8 -0
  40. package/dist/tools/aws-analyze.d.ts.map +1 -0
  41. package/dist/tools/aws-analyze.js +123 -0
  42. package/dist/tools/aws-analyze.js.map +1 -0
  43. package/dist/tools/aws-generate-all.d.ts +8 -0
  44. package/dist/tools/aws-generate-all.d.ts.map +1 -0
  45. package/dist/tools/aws-generate-all.js +197 -0
  46. package/dist/tools/aws-generate-all.js.map +1 -0
  47. package/dist/tools/aws-init.d.ts +8 -0
  48. package/dist/tools/aws-init.d.ts.map +1 -0
  49. package/dist/tools/aws-init.js +114 -0
  50. package/dist/tools/aws-init.js.map +1 -0
  51. package/dist/tools/aws-status.d.ts +8 -0
  52. package/dist/tools/aws-status.d.ts.map +1 -0
  53. package/dist/tools/aws-status.js +110 -0
  54. package/dist/tools/aws-status.js.map +1 -0
  55. package/dist/tools/index.d.ts +51 -0
  56. package/dist/tools/index.d.ts.map +1 -0
  57. package/dist/tools/index.js +35 -0
  58. package/dist/tools/index.js.map +1 -0
  59. package/dist/types.d.ts +644 -0
  60. package/dist/types.d.ts.map +1 -0
  61. package/dist/types.js +12 -0
  62. package/dist/types.js.map +1 -0
  63. package/package.json +95 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 frontpoint
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,141 @@
1
+ # AWS Infra MCP
2
+
3
+ MCP (Model Context Protocol) server for generating AWS CDK TypeScript infrastructure code with resource analysis.
4
+
5
+ ## Features
6
+
7
+ - **AWS Resource Analysis**: Scan existing AWS resources (EC2, RDS, Lambda, S3, DynamoDB, ECS, EKS, ECR, VPC, API Gateway)
8
+ - **CDK Code Generation**: Generate type-safe AWS CDK TypeScript projects
9
+ - **Full Service Coverage**: Support for compute, database, storage, and network resources
10
+ - **Interactive Configuration**: Add resources incrementally with MCP tools
11
+ - **Cost Estimation**: Preview estimated monthly costs (coming soon)
12
+ - **Security Validation**: IAM and security group validation (coming soon)
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npm install -g @frontpoint/aws-infra-mcp
18
+ ```
19
+
20
+ ## Usage
21
+
22
+ ### As MCP Server
23
+
24
+ Add to your Claude Code MCP configuration:
25
+
26
+ ```json
27
+ {
28
+ "mcpServers": {
29
+ "aws-infra": {
30
+ "command": "aws-infra-mcp",
31
+ "args": ["/path/to/your/project"]
32
+ }
33
+ }
34
+ }
35
+ ```
36
+
37
+ ### CLI
38
+
39
+ ```bash
40
+ # Start MCP server in current directory
41
+ aws-infra-mcp
42
+
43
+ # Start with specific project path
44
+ aws-infra-mcp /path/to/project
45
+ ```
46
+
47
+ ## Available Tools
48
+
49
+ | Tool | Description |
50
+ |------|-------------|
51
+ | `aws-init` | Initialize project with AWS credentials verification |
52
+ | `aws-analyze` | Scan existing AWS resources in your account |
53
+ | `aws-status` | Show current configuration status |
54
+ | `aws-add-compute` | Add EC2, Lambda, ECS, EKS resources |
55
+ | `aws-add-database` | Add RDS, Aurora, DynamoDB resources |
56
+ | `aws-add-storage` | Add S3, ECR resources |
57
+ | `aws-add-network` | Add VPC, API Gateway resources |
58
+ | `aws-generate-all` | Generate complete CDK project |
59
+
60
+ ## Supported AWS Services
61
+
62
+ ### Compute
63
+ - EC2 Instances & Auto Scaling Groups
64
+ - Lambda Functions with event sources
65
+ - ECS Clusters, Services, Task Definitions
66
+ - EKS Clusters with Node Groups
67
+
68
+ ### Database
69
+ - RDS (MySQL, PostgreSQL, MariaDB)
70
+ - Aurora (MySQL, PostgreSQL, Serverless v2)
71
+ - DynamoDB Tables with GSI/LSI
72
+
73
+ ### Storage
74
+ - S3 Buckets with lifecycle policies
75
+ - ECR Repositories
76
+
77
+ ### Network
78
+ - VPC with public/private subnets
79
+ - NAT Gateways
80
+ - API Gateway (REST, HTTP, WebSocket)
81
+
82
+ ## Example Workflow
83
+
84
+ ```bash
85
+ # 1. Initialize project
86
+ aws-init projectName: my-app region: ap-northeast-2
87
+
88
+ # 2. Analyze existing resources (optional)
89
+ aws-analyze
90
+
91
+ # 3. Add infrastructure resources
92
+ aws-add-network type: vpc name: main-vpc cidrBlock: 10.0.0.0/16
93
+ aws-add-database type: dynamodb name: users-table partitionKey: userId:S
94
+ aws-add-storage type: s3 name: my-app-assets versioning: true
95
+ aws-add-compute type: lambda name: api-handler runtime: nodejs20.x
96
+
97
+ # 4. Generate CDK project
98
+ aws-generate-all
99
+
100
+ # 5. Deploy
101
+ cd cdk-infra && npm install && npx cdk deploy --all
102
+ ```
103
+
104
+ ## Generated CDK Structure
105
+
106
+ ```
107
+ cdk-infra/
108
+ ├── bin/
109
+ │ └── app.ts # CDK app entry point
110
+ ├── lib/
111
+ │ └── stacks/
112
+ │ ├── network-stack.ts
113
+ │ ├── compute-stack.ts
114
+ │ ├── database-stack.ts
115
+ │ └── storage-stack.ts
116
+ ├── cdk.json
117
+ ├── package.json
118
+ └── tsconfig.json
119
+ ```
120
+
121
+ ## Requirements
122
+
123
+ - Node.js >= 18.0.0
124
+ - AWS CLI configured with credentials
125
+ - AWS CDK CLI (`npm install -g aws-cdk`)
126
+
127
+ ## Configuration
128
+
129
+ Configuration is stored in `.aws-infra-mcp/` directory:
130
+
131
+ - `config.json` - Infrastructure configuration
132
+ - `state.json` - Generation state and history
133
+ - `analysis-cache.json` - Cached AWS resource analysis
134
+
135
+ ## License
136
+
137
+ MIT
138
+
139
+ ## Author
140
+
141
+ frontpoint
@@ -0,0 +1,73 @@
1
+ /**
2
+ * AWS Resource Analyzer
3
+ *
4
+ * Analyzes existing AWS resources using AWS SDK v3
5
+ */
6
+ import type { AWSRegion, AWSResourceAnalysis, AnalyzedEC2Instance, AnalyzedRDSInstance, AnalyzedLambdaFunction, AnalyzedS3Bucket, AnalyzedDynamoDBTable, AnalyzedECSCluster, AnalyzedEKSCluster, AnalyzedECRRepository, AnalyzedVPC, AnalyzedAPIGateway } from '../types.js';
7
+ export interface AWSAnalyzerOptions {
8
+ region: AWSRegion;
9
+ profile?: string;
10
+ }
11
+ export interface AWSCredentialsInfo {
12
+ account: string;
13
+ userId: string;
14
+ arn: string;
15
+ }
16
+ export declare class AWSAnalyzer {
17
+ private region;
18
+ private clientConfig;
19
+ constructor(options: AWSAnalyzerOptions);
20
+ /**
21
+ * Verify AWS credentials and get account info
22
+ */
23
+ verifyCredentials(): Promise<AWSCredentialsInfo>;
24
+ /**
25
+ * Analyze all AWS resources
26
+ */
27
+ analyzeAll(): Promise<AWSResourceAnalysis>;
28
+ /**
29
+ * Analyze EC2 instances
30
+ */
31
+ analyzeEC2(): Promise<AnalyzedEC2Instance[]>;
32
+ /**
33
+ * Analyze RDS instances
34
+ */
35
+ analyzeRDS(): Promise<AnalyzedRDSInstance[]>;
36
+ /**
37
+ * Analyze Lambda functions
38
+ */
39
+ analyzeLambda(): Promise<AnalyzedLambdaFunction[]>;
40
+ /**
41
+ * Analyze S3 buckets
42
+ */
43
+ analyzeS3(): Promise<AnalyzedS3Bucket[]>;
44
+ /**
45
+ * Analyze DynamoDB tables
46
+ */
47
+ analyzeDynamoDB(): Promise<AnalyzedDynamoDBTable[]>;
48
+ /**
49
+ * Analyze ECS clusters
50
+ */
51
+ analyzeECS(): Promise<AnalyzedECSCluster[]>;
52
+ /**
53
+ * Analyze EKS clusters
54
+ */
55
+ analyzeEKS(): Promise<AnalyzedEKSCluster[]>;
56
+ /**
57
+ * Analyze ECR repositories
58
+ */
59
+ analyzeECR(): Promise<AnalyzedECRRepository[]>;
60
+ /**
61
+ * Analyze VPCs
62
+ */
63
+ analyzeVPC(): Promise<AnalyzedVPC[]>;
64
+ /**
65
+ * Analyze API Gateways
66
+ */
67
+ analyzeAPIGateway(): Promise<AnalyzedAPIGateway[]>;
68
+ /**
69
+ * Build importable resources list
70
+ */
71
+ private buildImportableResources;
72
+ }
73
+ //# sourceMappingURL=aws-analyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aws-analyzer.d.ts","sourceRoot":"","sources":["../../src/core/aws-analyzer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAYH,OAAO,KAAK,EACV,SAAS,EACT,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,sBAAsB,EACtB,gBAAgB,EAChB,qBAAqB,EACrB,kBAAkB,EAClB,kBAAkB,EAClB,qBAAqB,EACrB,WAAW,EACX,kBAAkB,EAEnB,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,SAAS,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;CACb;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,YAAY,CAAqB;gBAE7B,OAAO,EAAE,kBAAkB;IAWvC;;OAEG;IACG,iBAAiB,IAAI,OAAO,CAAC,kBAAkB,CAAC;IAWtD;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAwChD;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC;IA8BlD;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAoBlD;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,sBAAsB,EAAE,CAAC;IAmBxD;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAwC9C;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC,qBAAqB,EAAE,CAAC;IAgCzD;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC;IA0BjD;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC;IA+BjD;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,qBAAqB,EAAE,CAAC;IAgBpD;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAmB1C;;OAEG;IACG,iBAAiB,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAgBxD;;OAEG;IACH,OAAO,CAAC,wBAAwB;CA2HjC"}
@@ -0,0 +1,429 @@
1
+ /**
2
+ * AWS Resource Analyzer
3
+ *
4
+ * Analyzes existing AWS resources using AWS SDK v3
5
+ */
6
+ import { EC2Client, DescribeInstancesCommand, DescribeVpcsCommand } from '@aws-sdk/client-ec2';
7
+ import { RDSClient, DescribeDBInstancesCommand } from '@aws-sdk/client-rds';
8
+ import { S3Client, ListBucketsCommand, GetBucketVersioningCommand, GetBucketEncryptionCommand } from '@aws-sdk/client-s3';
9
+ import { LambdaClient, ListFunctionsCommand } from '@aws-sdk/client-lambda';
10
+ import { DynamoDBClient, ListTablesCommand, DescribeTableCommand } from '@aws-sdk/client-dynamodb';
11
+ import { ECSClient, ListClustersCommand, DescribeClustersCommand } from '@aws-sdk/client-ecs';
12
+ import { EKSClient, ListClustersCommand as EKSListClustersCommand, DescribeClusterCommand } from '@aws-sdk/client-eks';
13
+ import { ECRClient, DescribeRepositoriesCommand } from '@aws-sdk/client-ecr';
14
+ import { ApiGatewayV2Client, GetApisCommand } from '@aws-sdk/client-apigatewayv2';
15
+ import { STSClient, GetCallerIdentityCommand } from '@aws-sdk/client-sts';
16
+ export class AWSAnalyzer {
17
+ region;
18
+ clientConfig;
19
+ constructor(options) {
20
+ this.region = options.region;
21
+ this.clientConfig = { region: options.region };
22
+ // If profile is specified, set environment variable
23
+ // AWS SDK v3 will automatically use AWS_PROFILE
24
+ if (options.profile) {
25
+ process.env.AWS_PROFILE = options.profile;
26
+ }
27
+ }
28
+ /**
29
+ * Verify AWS credentials and get account info
30
+ */
31
+ async verifyCredentials() {
32
+ const client = new STSClient(this.clientConfig);
33
+ const response = await client.send(new GetCallerIdentityCommand({}));
34
+ return {
35
+ account: response.Account || '',
36
+ userId: response.UserId || '',
37
+ arn: response.Arn || '',
38
+ };
39
+ }
40
+ /**
41
+ * Analyze all AWS resources
42
+ */
43
+ async analyzeAll() {
44
+ const credentials = await this.verifyCredentials();
45
+ const [ec2, rds, lambda, s3, dynamodb, ecs, eks, ecr, vpc, apiGateway,] = await Promise.all([
46
+ this.analyzeEC2(),
47
+ this.analyzeRDS(),
48
+ this.analyzeLambda(),
49
+ this.analyzeS3(),
50
+ this.analyzeDynamoDB(),
51
+ this.analyzeECS(),
52
+ this.analyzeEKS(),
53
+ this.analyzeECR(),
54
+ this.analyzeVPC(),
55
+ this.analyzeAPIGateway(),
56
+ ]);
57
+ const importableResources = this.buildImportableResources({
58
+ ec2, rds, lambda, s3, dynamodb, ecs, eks, ecr, vpc, apiGateway,
59
+ });
60
+ return {
61
+ region: this.region,
62
+ account: credentials.account,
63
+ analyzedAt: new Date().toISOString(),
64
+ resources: { ec2, rds, lambda, s3, dynamodb, ecs, eks, ecr, vpc, apiGateway },
65
+ importableResources,
66
+ };
67
+ }
68
+ /**
69
+ * Analyze EC2 instances
70
+ */
71
+ async analyzeEC2() {
72
+ try {
73
+ const client = new EC2Client(this.clientConfig);
74
+ const response = await client.send(new DescribeInstancesCommand({}));
75
+ const instances = [];
76
+ for (const reservation of response.Reservations || []) {
77
+ for (const instance of reservation.Instances || []) {
78
+ const nameTag = instance.Tags?.find((t) => t.Key === 'Name');
79
+ instances.push({
80
+ instanceId: instance.InstanceId || '',
81
+ name: nameTag?.Value,
82
+ instanceType: instance.InstanceType || '',
83
+ state: instance.State?.Name || '',
84
+ vpcId: instance.VpcId,
85
+ subnetId: instance.SubnetId,
86
+ publicIpAddress: instance.PublicIpAddress,
87
+ privateIpAddress: instance.PrivateIpAddress,
88
+ tags: Object.fromEntries((instance.Tags || []).map((t) => [t.Key || '', t.Value || ''])),
89
+ });
90
+ }
91
+ }
92
+ return instances;
93
+ }
94
+ catch {
95
+ return [];
96
+ }
97
+ }
98
+ /**
99
+ * Analyze RDS instances
100
+ */
101
+ async analyzeRDS() {
102
+ try {
103
+ const client = new RDSClient(this.clientConfig);
104
+ const response = await client.send(new DescribeDBInstancesCommand({}));
105
+ return (response.DBInstances || []).map((db) => ({
106
+ dbInstanceIdentifier: db.DBInstanceIdentifier || '',
107
+ engine: db.Engine || '',
108
+ engineVersion: db.EngineVersion || '',
109
+ dbInstanceClass: db.DBInstanceClass || '',
110
+ allocatedStorage: db.AllocatedStorage || 0,
111
+ status: db.DBInstanceStatus || '',
112
+ multiAZ: db.MultiAZ || false,
113
+ publiclyAccessible: db.PubliclyAccessible || false,
114
+ }));
115
+ }
116
+ catch {
117
+ return [];
118
+ }
119
+ }
120
+ /**
121
+ * Analyze Lambda functions
122
+ */
123
+ async analyzeLambda() {
124
+ try {
125
+ const client = new LambdaClient(this.clientConfig);
126
+ const response = await client.send(new ListFunctionsCommand({}));
127
+ return (response.Functions || []).map((fn) => ({
128
+ functionName: fn.FunctionName || '',
129
+ functionArn: fn.FunctionArn || '',
130
+ runtime: fn.Runtime || '',
131
+ handler: fn.Handler || '',
132
+ memorySize: fn.MemorySize || 0,
133
+ timeout: fn.Timeout || 0,
134
+ lastModified: fn.LastModified || '',
135
+ }));
136
+ }
137
+ catch {
138
+ return [];
139
+ }
140
+ }
141
+ /**
142
+ * Analyze S3 buckets
143
+ */
144
+ async analyzeS3() {
145
+ try {
146
+ const client = new S3Client(this.clientConfig);
147
+ const response = await client.send(new ListBucketsCommand({}));
148
+ const buckets = [];
149
+ for (const bucket of response.Buckets || []) {
150
+ let versioning = false;
151
+ let encryption = false;
152
+ try {
153
+ const versioningResponse = await client.send(new GetBucketVersioningCommand({ Bucket: bucket.Name }));
154
+ versioning = versioningResponse.Status === 'Enabled';
155
+ }
156
+ catch {
157
+ // Bucket might be in different region
158
+ }
159
+ try {
160
+ await client.send(new GetBucketEncryptionCommand({ Bucket: bucket.Name }));
161
+ encryption = true;
162
+ }
163
+ catch {
164
+ // No encryption or different region
165
+ }
166
+ buckets.push({
167
+ name: bucket.Name || '',
168
+ creationDate: bucket.CreationDate?.toISOString() || '',
169
+ region: this.region,
170
+ versioning,
171
+ encryption,
172
+ });
173
+ }
174
+ return buckets;
175
+ }
176
+ catch {
177
+ return [];
178
+ }
179
+ }
180
+ /**
181
+ * Analyze DynamoDB tables
182
+ */
183
+ async analyzeDynamoDB() {
184
+ try {
185
+ const client = new DynamoDBClient(this.clientConfig);
186
+ const listResponse = await client.send(new ListTablesCommand({}));
187
+ const tables = [];
188
+ for (const tableName of listResponse.TableNames || []) {
189
+ try {
190
+ const describeResponse = await client.send(new DescribeTableCommand({ TableName: tableName }));
191
+ const table = describeResponse.Table;
192
+ if (table) {
193
+ tables.push({
194
+ tableName: table.TableName || '',
195
+ tableArn: table.TableArn || '',
196
+ status: table.TableStatus || '',
197
+ itemCount: Number(table.ItemCount) || 0,
198
+ tableSizeBytes: Number(table.TableSizeBytes) || 0,
199
+ billingMode: table.BillingModeSummary?.BillingMode || 'PROVISIONED',
200
+ });
201
+ }
202
+ }
203
+ catch {
204
+ // Skip tables we can't describe
205
+ }
206
+ }
207
+ return tables;
208
+ }
209
+ catch {
210
+ return [];
211
+ }
212
+ }
213
+ /**
214
+ * Analyze ECS clusters
215
+ */
216
+ async analyzeECS() {
217
+ try {
218
+ const client = new ECSClient(this.clientConfig);
219
+ const listResponse = await client.send(new ListClustersCommand({}));
220
+ if (!listResponse.clusterArns?.length) {
221
+ return [];
222
+ }
223
+ const describeResponse = await client.send(new DescribeClustersCommand({ clusters: listResponse.clusterArns }));
224
+ return (describeResponse.clusters || []).map((cluster) => ({
225
+ clusterName: cluster.clusterName || '',
226
+ clusterArn: cluster.clusterArn || '',
227
+ status: cluster.status || '',
228
+ runningTasksCount: cluster.runningTasksCount || 0,
229
+ pendingTasksCount: cluster.pendingTasksCount || 0,
230
+ activeServicesCount: cluster.activeServicesCount || 0,
231
+ }));
232
+ }
233
+ catch {
234
+ return [];
235
+ }
236
+ }
237
+ /**
238
+ * Analyze EKS clusters
239
+ */
240
+ async analyzeEKS() {
241
+ try {
242
+ const client = new EKSClient(this.clientConfig);
243
+ const listResponse = await client.send(new EKSListClustersCommand({}));
244
+ const clusters = [];
245
+ for (const clusterName of listResponse.clusters || []) {
246
+ try {
247
+ const describeResponse = await client.send(new DescribeClusterCommand({ name: clusterName }));
248
+ const cluster = describeResponse.cluster;
249
+ if (cluster) {
250
+ clusters.push({
251
+ name: cluster.name || '',
252
+ arn: cluster.arn || '',
253
+ version: cluster.version || '',
254
+ status: cluster.status || '',
255
+ endpoint: cluster.endpoint || '',
256
+ });
257
+ }
258
+ }
259
+ catch {
260
+ // Skip clusters we can't describe
261
+ }
262
+ }
263
+ return clusters;
264
+ }
265
+ catch {
266
+ return [];
267
+ }
268
+ }
269
+ /**
270
+ * Analyze ECR repositories
271
+ */
272
+ async analyzeECR() {
273
+ try {
274
+ const client = new ECRClient(this.clientConfig);
275
+ const response = await client.send(new DescribeRepositoriesCommand({}));
276
+ return (response.repositories || []).map((repo) => ({
277
+ repositoryName: repo.repositoryName || '',
278
+ repositoryArn: repo.repositoryArn || '',
279
+ repositoryUri: repo.repositoryUri || '',
280
+ imageCount: 0, // Would need additional API call
281
+ }));
282
+ }
283
+ catch {
284
+ return [];
285
+ }
286
+ }
287
+ /**
288
+ * Analyze VPCs
289
+ */
290
+ async analyzeVPC() {
291
+ try {
292
+ const client = new EC2Client(this.clientConfig);
293
+ const response = await client.send(new DescribeVpcsCommand({}));
294
+ return (response.Vpcs || []).map((vpc) => ({
295
+ vpcId: vpc.VpcId || '',
296
+ cidrBlock: vpc.CidrBlock || '',
297
+ state: vpc.State || '',
298
+ isDefault: vpc.IsDefault || false,
299
+ tags: Object.fromEntries((vpc.Tags || []).map((t) => [t.Key || '', t.Value || ''])),
300
+ }));
301
+ }
302
+ catch {
303
+ return [];
304
+ }
305
+ }
306
+ /**
307
+ * Analyze API Gateways
308
+ */
309
+ async analyzeAPIGateway() {
310
+ try {
311
+ const client = new ApiGatewayV2Client(this.clientConfig);
312
+ const response = await client.send(new GetApisCommand({}));
313
+ return (response.Items || []).map((api) => ({
314
+ apiId: api.ApiId || '',
315
+ name: api.Name || '',
316
+ protocolType: api.ProtocolType || '',
317
+ apiEndpoint: api.ApiEndpoint || '',
318
+ }));
319
+ }
320
+ catch {
321
+ return [];
322
+ }
323
+ }
324
+ /**
325
+ * Build importable resources list
326
+ */
327
+ buildImportableResources(resources) {
328
+ const importable = [];
329
+ // EC2 instances
330
+ for (const instance of resources.ec2) {
331
+ importable.push({
332
+ type: 'AWS::EC2::Instance',
333
+ id: instance.instanceId,
334
+ name: instance.name || instance.instanceId,
335
+ importCommand: `cdk import ${instance.instanceId}`,
336
+ });
337
+ }
338
+ // RDS instances
339
+ for (const db of resources.rds) {
340
+ importable.push({
341
+ type: 'AWS::RDS::DBInstance',
342
+ id: db.dbInstanceIdentifier,
343
+ name: db.dbInstanceIdentifier,
344
+ importCommand: `cdk import ${db.dbInstanceIdentifier}`,
345
+ });
346
+ }
347
+ // Lambda functions
348
+ for (const fn of resources.lambda) {
349
+ importable.push({
350
+ type: 'AWS::Lambda::Function',
351
+ id: fn.functionName,
352
+ name: fn.functionName,
353
+ arn: fn.functionArn,
354
+ importCommand: `cdk import ${fn.functionName}`,
355
+ });
356
+ }
357
+ // S3 buckets
358
+ for (const bucket of resources.s3) {
359
+ importable.push({
360
+ type: 'AWS::S3::Bucket',
361
+ id: bucket.name,
362
+ name: bucket.name,
363
+ importCommand: `cdk import ${bucket.name}`,
364
+ });
365
+ }
366
+ // DynamoDB tables
367
+ for (const table of resources.dynamodb) {
368
+ importable.push({
369
+ type: 'AWS::DynamoDB::Table',
370
+ id: table.tableName,
371
+ name: table.tableName,
372
+ arn: table.tableArn,
373
+ importCommand: `cdk import ${table.tableName}`,
374
+ });
375
+ }
376
+ // ECS clusters
377
+ for (const cluster of resources.ecs) {
378
+ importable.push({
379
+ type: 'AWS::ECS::Cluster',
380
+ id: cluster.clusterName,
381
+ name: cluster.clusterName,
382
+ arn: cluster.clusterArn,
383
+ importCommand: `cdk import ${cluster.clusterName}`,
384
+ });
385
+ }
386
+ // EKS clusters
387
+ for (const cluster of resources.eks) {
388
+ importable.push({
389
+ type: 'AWS::EKS::Cluster',
390
+ id: cluster.name,
391
+ name: cluster.name,
392
+ arn: cluster.arn,
393
+ importCommand: `cdk import ${cluster.name}`,
394
+ });
395
+ }
396
+ // ECR repositories
397
+ for (const repo of resources.ecr) {
398
+ importable.push({
399
+ type: 'AWS::ECR::Repository',
400
+ id: repo.repositoryName,
401
+ name: repo.repositoryName,
402
+ arn: repo.repositoryArn,
403
+ importCommand: `cdk import ${repo.repositoryName}`,
404
+ });
405
+ }
406
+ // VPCs
407
+ for (const vpc of resources.vpc) {
408
+ if (!vpc.isDefault) {
409
+ importable.push({
410
+ type: 'AWS::EC2::VPC',
411
+ id: vpc.vpcId,
412
+ name: vpc.tags['Name'] || vpc.vpcId,
413
+ importCommand: `cdk import ${vpc.vpcId}`,
414
+ });
415
+ }
416
+ }
417
+ // API Gateways
418
+ for (const api of resources.apiGateway) {
419
+ importable.push({
420
+ type: 'AWS::ApiGatewayV2::Api',
421
+ id: api.apiId,
422
+ name: api.name,
423
+ importCommand: `cdk import ${api.apiId}`,
424
+ });
425
+ }
426
+ return importable;
427
+ }
428
+ }
429
+ //# sourceMappingURL=aws-analyzer.js.map