create-aws-project 1.2.1 → 1.3.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.
- package/README.md +129 -27
- package/dist/__tests__/generator/replace-tokens.spec.js +9 -0
- package/dist/__tests__/wizard.spec.js +2 -3
- package/dist/aws/iam.d.ts +8 -1
- package/dist/aws/iam.js +22 -3
- package/dist/cli.js +79 -102
- package/dist/commands/initialize-github.d.ts +13 -0
- package/dist/commands/initialize-github.js +329 -0
- package/dist/commands/setup-aws-envs.d.ts +14 -0
- package/dist/commands/setup-aws-envs.js +233 -0
- package/dist/commands/setup-github.d.ts +11 -0
- package/dist/commands/setup-github.js +22 -0
- package/dist/templates/manifest.js +5 -0
- package/dist/templates/types.d.ts +4 -0
- package/dist/utils/project-context.d.ts +44 -0
- package/dist/utils/project-context.js +63 -0
- package/dist/wizard.js +2 -37
- package/package.json +4 -1
- package/templates/manifest.json +1 -0
- package/templates/root/README.md +156 -0
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@ Create a new AWS project from scratch including CloudFront, API Gateway, Lambdas
|
|
|
7
7
|
## Quick Start
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
npx create-aws-
|
|
10
|
+
npx create-aws-project my-project
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
**Requirements:** Node.js 22.16.0+ (npm included)
|
|
@@ -33,35 +33,24 @@ The generated project is a full-stack Nx monorepo with:
|
|
|
33
33
|
## CLI Options
|
|
34
34
|
|
|
35
35
|
```
|
|
36
|
-
create-aws-starter-kit [
|
|
36
|
+
create-aws-starter-kit [command] [options]
|
|
37
|
+
|
|
38
|
+
Commands:
|
|
39
|
+
(default) Create a new project (interactive wizard)
|
|
40
|
+
setup-aws-envs Set up AWS Organizations and environment accounts
|
|
41
|
+
initialize-github Configure GitHub Environment for deployment
|
|
37
42
|
|
|
38
43
|
Options:
|
|
39
|
-
--help, -h
|
|
40
|
-
--version, -v
|
|
44
|
+
--help, -h Show help message
|
|
45
|
+
--version, -v Show version number
|
|
41
46
|
|
|
42
47
|
Examples:
|
|
43
48
|
npx create-aws-starter-kit my-app
|
|
49
|
+
npx create-aws-starter-kit setup-aws-envs
|
|
50
|
+
npx create-aws-starter-kit initialize-github dev
|
|
44
51
|
npx create-aws-starter-kit --help
|
|
45
|
-
npx create-aws-starter-kit --version
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
### Setup GitHub Command
|
|
49
|
-
|
|
50
|
-
After generating a project with AWS Organizations enabled, configure GitHub Actions deployment:
|
|
51
|
-
|
|
52
|
-
```bash
|
|
53
|
-
npx create-aws-starter-kit setup-github
|
|
54
52
|
```
|
|
55
53
|
|
|
56
|
-
This command:
|
|
57
|
-
- Creates IAM deployment users per environment (dev, stage, prod)
|
|
58
|
-
- Configures GitHub Environments with AWS credentials
|
|
59
|
-
- Sets up least-privilege CDK deployment permissions
|
|
60
|
-
|
|
61
|
-
**Requirements:**
|
|
62
|
-
- GitHub Personal Access Token with `repo` and `admin:org` scopes
|
|
63
|
-
- AWS credentials with IAM permissions
|
|
64
|
-
|
|
65
54
|
## Wizard Prompts
|
|
66
55
|
|
|
67
56
|
The interactive wizard will ask you about:
|
|
@@ -72,11 +61,7 @@ The interactive wizard will ask you about:
|
|
|
72
61
|
- None (add later)
|
|
73
62
|
- AWS Cognito
|
|
74
63
|
- Auth0
|
|
75
|
-
|
|
76
|
-
4. **AWS Organizations** - Multi-account setup (optional):
|
|
77
|
-
- Creates separate AWS accounts for each environment
|
|
78
|
-
- Environments: dev, stage, prod (plus optional qa, sandbox)
|
|
79
|
-
- Requires root email per account
|
|
64
|
+
4. **Auth features** - Social login, MFA (conditional on auth provider)
|
|
80
65
|
5. **Features** - Optional extras:
|
|
81
66
|
- GitHub Actions workflows for CI/CD
|
|
82
67
|
- VS Code workspace configuration
|
|
@@ -113,6 +98,123 @@ npm run cdk:deploy
|
|
|
113
98
|
|
|
114
99
|
See the generated project's README for detailed documentation.
|
|
115
100
|
|
|
101
|
+
## Post-Install Setup
|
|
102
|
+
|
|
103
|
+
After creating your project, you'll set up AWS environments and GitHub deployment. This is a one-time setup.
|
|
104
|
+
|
|
105
|
+
### Prerequisites
|
|
106
|
+
|
|
107
|
+
Before you begin:
|
|
108
|
+
- AWS CLI configured with credentials from your AWS management account
|
|
109
|
+
- GitHub repository created for your project
|
|
110
|
+
- GitHub Personal Access Token with "repo" scope ([create one here](https://github.com/settings/tokens/new))
|
|
111
|
+
|
|
112
|
+
### Step 1: Set Up AWS Environments
|
|
113
|
+
|
|
114
|
+
From your project directory, run:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
npx create-aws-project setup-aws-envs
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
This command:
|
|
121
|
+
- Creates an AWS Organization (if you don't have one)
|
|
122
|
+
- Creates three environment accounts: dev, stage, prod
|
|
123
|
+
- Prompts for a unique root email for each account (tip: use aliases like you+dev@email.com)
|
|
124
|
+
|
|
125
|
+
**What's happening:** AWS Organizations lets you isolate each environment in its own AWS account. This is a security best practice - your production data is completely separate from development.
|
|
126
|
+
|
|
127
|
+
Expected output:
|
|
128
|
+
```
|
|
129
|
+
✔ Created AWS Organization: o-xxxxxxxxxx
|
|
130
|
+
✔ Created dev account: 123456789012
|
|
131
|
+
✔ Created stage account: 234567890123
|
|
132
|
+
✔ Created prod account: 345678901234
|
|
133
|
+
|
|
134
|
+
AWS environment setup complete!
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Account IDs are saved to `.aws-starter-config.json` for the next step.
|
|
138
|
+
|
|
139
|
+
### Step 2: Configure GitHub Environments
|
|
140
|
+
|
|
141
|
+
For each environment, run:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
npx create-aws-project initialize-github dev
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
This command:
|
|
148
|
+
- Creates an IAM deployment user in the target AWS account
|
|
149
|
+
- Configures GitHub Environment secrets with AWS credentials
|
|
150
|
+
- Sets up least-privilege permissions for CDK deployments
|
|
151
|
+
|
|
152
|
+
**What's happening:** Each GitHub Environment (Development, Staging, Production) gets its own AWS credentials. When GitHub Actions runs, it uses the right credentials for the target environment.
|
|
153
|
+
|
|
154
|
+
Repeat for each environment:
|
|
155
|
+
```bash
|
|
156
|
+
npx create-aws-project initialize-github stage
|
|
157
|
+
npx create-aws-project initialize-github prod
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
You'll be prompted for your GitHub PAT each time (it's not stored).
|
|
161
|
+
|
|
162
|
+
### You're Done!
|
|
163
|
+
|
|
164
|
+
Push to main to trigger your first deployment:
|
|
165
|
+
```bash
|
|
166
|
+
git push origin main
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
GitHub Actions will deploy to your dev environment automatically.
|
|
170
|
+
|
|
171
|
+
## Troubleshooting
|
|
172
|
+
|
|
173
|
+
### setup-aws-envs errors
|
|
174
|
+
|
|
175
|
+
**"Insufficient AWS permissions"**
|
|
176
|
+
|
|
177
|
+
Your AWS credentials need Organizations permissions. Ensure you're using credentials from the management account (not a member account).
|
|
178
|
+
|
|
179
|
+
Required permissions:
|
|
180
|
+
- organizations:DescribeOrganization
|
|
181
|
+
- organizations:CreateOrganization
|
|
182
|
+
- organizations:CreateAccount
|
|
183
|
+
- organizations:DescribeCreateAccountStatus
|
|
184
|
+
|
|
185
|
+
**"AWS Organizations limit reached"**
|
|
186
|
+
|
|
187
|
+
AWS limits how many accounts you can create. Contact AWS Support to request a limit increase.
|
|
188
|
+
|
|
189
|
+
**"AWS Organization is still initializing"**
|
|
190
|
+
|
|
191
|
+
New organizations take up to an hour to fully initialize. Wait and try again.
|
|
192
|
+
|
|
193
|
+
### initialize-github errors
|
|
194
|
+
|
|
195
|
+
**"Cannot assume role in target account"**
|
|
196
|
+
|
|
197
|
+
The command needs to access the target AWS account via `OrganizationAccountAccessRole`. This role is created automatically when you create accounts via `setup-aws-envs`. Ensure:
|
|
198
|
+
1. You ran `setup-aws-envs` first
|
|
199
|
+
2. Your credentials are from the management account
|
|
200
|
+
3. The account ID in `.aws-starter-config.json` is correct
|
|
201
|
+
|
|
202
|
+
**"IAM user already exists"**
|
|
203
|
+
|
|
204
|
+
The deployment user already exists in the target account. To retry:
|
|
205
|
+
1. Go to AWS Console > IAM > Users
|
|
206
|
+
2. Delete the existing `<project>-<env>-deploy` user
|
|
207
|
+
3. Run the command again
|
|
208
|
+
|
|
209
|
+
**"GitHub authentication failed"**
|
|
210
|
+
|
|
211
|
+
Your Personal Access Token may be invalid or missing permissions. Ensure:
|
|
212
|
+
1. Token has "repo" scope enabled
|
|
213
|
+
2. Token belongs to the repository owner (or has collaborator access)
|
|
214
|
+
3. Token is not expired
|
|
215
|
+
|
|
216
|
+
Create a new token at: https://github.com/settings/tokens/new
|
|
217
|
+
|
|
116
218
|
## License
|
|
117
219
|
|
|
118
220
|
ISC
|
|
@@ -12,6 +12,9 @@ describe('replaceTokens', () => {
|
|
|
12
12
|
AUTH_AUTH0: 'false',
|
|
13
13
|
AUTH_SOCIAL_LOGIN: 'false',
|
|
14
14
|
AUTH_MFA: 'false',
|
|
15
|
+
WEB: 'false',
|
|
16
|
+
MOBILE: 'false',
|
|
17
|
+
API: 'false',
|
|
15
18
|
};
|
|
16
19
|
describe('single token replacement', () => {
|
|
17
20
|
it('should replace PROJECT_NAME token', () => {
|
|
@@ -107,6 +110,9 @@ describe('processConditionalBlocks', () => {
|
|
|
107
110
|
AUTH_AUTH0: 'false',
|
|
108
111
|
AUTH_SOCIAL_LOGIN: 'false',
|
|
109
112
|
AUTH_MFA: 'false',
|
|
113
|
+
WEB: 'false',
|
|
114
|
+
MOBILE: 'false',
|
|
115
|
+
API: 'false',
|
|
110
116
|
};
|
|
111
117
|
describe('comment-wrapped conditionals', () => {
|
|
112
118
|
it('should keep content when token is true (removes markers)', () => {
|
|
@@ -228,6 +234,9 @@ describe('replaceTokens integration with conditionals', () => {
|
|
|
228
234
|
AUTH_AUTH0: 'false',
|
|
229
235
|
AUTH_SOCIAL_LOGIN: 'false',
|
|
230
236
|
AUTH_MFA: 'false',
|
|
237
|
+
WEB: 'false',
|
|
238
|
+
MOBILE: 'false',
|
|
239
|
+
API: 'false',
|
|
231
240
|
};
|
|
232
241
|
it('should process conditionals before token replacement', () => {
|
|
233
242
|
const tokens = { ...baseTokens, AUTH_COGNITO: 'true' };
|
|
@@ -173,10 +173,9 @@ describe('runWizard', () => {
|
|
|
173
173
|
await runWizard();
|
|
174
174
|
expect(mockPrompts).toHaveBeenCalledTimes(1);
|
|
175
175
|
const [promptsArg] = mockPrompts.mock.calls[0];
|
|
176
|
-
// Verify
|
|
177
|
-
// enableOrg, orgName, orgEnvironments, devEmail, stageEmail, prodEmail, qaEmail, sandboxEmail, brandColor)
|
|
176
|
+
// Verify 7 prompts are passed (projectName, platforms, authProvider, authFeatures, features, awsRegion, brandColor)
|
|
178
177
|
expect(Array.isArray(promptsArg)).toBe(true);
|
|
179
|
-
expect(promptsArg.length).toBe(
|
|
178
|
+
expect(promptsArg.length).toBe(7);
|
|
180
179
|
});
|
|
181
180
|
});
|
|
182
181
|
describe('auth configuration', () => {
|
package/dist/aws/iam.d.ts
CHANGED
|
@@ -11,11 +11,18 @@ import { IAMClient } from '@aws-sdk/client-iam';
|
|
|
11
11
|
* @returns Configured IAMClient instance
|
|
12
12
|
*/
|
|
13
13
|
export declare function createIAMClient(region?: string): IAMClient;
|
|
14
|
+
/**
|
|
15
|
+
* Creates an IAMClient configured to access a target account via cross-account role assumption
|
|
16
|
+
* @param region - AWS region
|
|
17
|
+
* @param targetAccountId - Target AWS account ID to access
|
|
18
|
+
* @returns IAMClient configured with cross-account credentials
|
|
19
|
+
*/
|
|
20
|
+
export declare function createCrossAccountIAMClient(region: string, targetAccountId: string): IAMClient;
|
|
14
21
|
/**
|
|
15
22
|
* Creates an IAM deployment user with path /deployment/
|
|
16
23
|
* @param client - IAMClient instance
|
|
17
24
|
* @param userName - User name (format: {project}-{environment}-deploy)
|
|
18
|
-
* @throws Error if user
|
|
25
|
+
* @throws Error if user already exists or creation fails
|
|
19
26
|
*/
|
|
20
27
|
export declare function createDeploymentUser(client: IAMClient, userName: string): Promise<void>;
|
|
21
28
|
/**
|
package/dist/aws/iam.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { IAMClient, CreateUserCommand, GetUserCommand, CreatePolicyCommand, GetPolicyCommand, AttachUserPolicyCommand, CreateAccessKeyCommand, NoSuchEntityException, } from '@aws-sdk/client-iam';
|
|
2
|
+
import { fromTemporaryCredentials } from '@aws-sdk/credential-providers';
|
|
2
3
|
import pc from 'picocolors';
|
|
3
4
|
/**
|
|
4
5
|
* AWS IAM service module
|
|
@@ -14,6 +15,25 @@ import pc from 'picocolors';
|
|
|
14
15
|
export function createIAMClient(region = 'us-east-1') {
|
|
15
16
|
return new IAMClient({ region });
|
|
16
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* Creates an IAMClient configured to access a target account via cross-account role assumption
|
|
20
|
+
* @param region - AWS region
|
|
21
|
+
* @param targetAccountId - Target AWS account ID to access
|
|
22
|
+
* @returns IAMClient configured with cross-account credentials
|
|
23
|
+
*/
|
|
24
|
+
export function createCrossAccountIAMClient(region, targetAccountId) {
|
|
25
|
+
const roleArn = `arn:aws:iam::${targetAccountId}:role/OrganizationAccountAccessRole`;
|
|
26
|
+
return new IAMClient({
|
|
27
|
+
region,
|
|
28
|
+
credentials: fromTemporaryCredentials({
|
|
29
|
+
params: {
|
|
30
|
+
RoleArn: roleArn,
|
|
31
|
+
RoleSessionName: `create-aws-project-${Date.now()}`,
|
|
32
|
+
DurationSeconds: 900,
|
|
33
|
+
},
|
|
34
|
+
}),
|
|
35
|
+
});
|
|
36
|
+
}
|
|
17
37
|
/**
|
|
18
38
|
* Checks if an IAM user exists
|
|
19
39
|
* @param client - IAMClient instance
|
|
@@ -56,13 +76,12 @@ async function policyExists(client, policyArn) {
|
|
|
56
76
|
* Creates an IAM deployment user with path /deployment/
|
|
57
77
|
* @param client - IAMClient instance
|
|
58
78
|
* @param userName - User name (format: {project}-{environment}-deploy)
|
|
59
|
-
* @throws Error if user
|
|
79
|
+
* @throws Error if user already exists or creation fails
|
|
60
80
|
*/
|
|
61
81
|
export async function createDeploymentUser(client, userName) {
|
|
62
82
|
// Check if user already exists
|
|
63
83
|
if (await userExists(client, userName)) {
|
|
64
|
-
|
|
65
|
-
return;
|
|
84
|
+
throw new Error(`IAM user "${userName}" already exists. Delete manually before retrying.`);
|
|
66
85
|
}
|
|
67
86
|
const command = new CreateUserCommand({
|
|
68
87
|
UserName: userName,
|
package/dist/cli.js
CHANGED
|
@@ -1,11 +1,30 @@
|
|
|
1
|
-
import { readFileSync, existsSync, mkdirSync } from 'node:fs';
|
|
1
|
+
import { readFileSync, existsSync, mkdirSync, writeFileSync } from 'node:fs';
|
|
2
2
|
import { fileURLToPath } from 'node:url';
|
|
3
3
|
import { dirname, join, resolve } from 'node:path';
|
|
4
4
|
import pc from 'picocolors';
|
|
5
5
|
import { runWizard } from './wizard.js';
|
|
6
6
|
import { generateProject } from './generator/index.js';
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
7
|
+
import { showDeprecationNotice } from './commands/setup-github.js';
|
|
8
|
+
import { runSetupAwsEnvs } from './commands/setup-aws-envs.js';
|
|
9
|
+
import { runInitializeGitHub } from './commands/initialize-github.js';
|
|
10
|
+
/**
|
|
11
|
+
* Write project configuration file for downstream commands
|
|
12
|
+
*/
|
|
13
|
+
function writeConfigFile(outputDir, config) {
|
|
14
|
+
const configContent = {
|
|
15
|
+
configVersion: '1.0',
|
|
16
|
+
projectName: config.projectName,
|
|
17
|
+
platforms: config.platforms,
|
|
18
|
+
authProvider: config.auth.provider,
|
|
19
|
+
features: config.features,
|
|
20
|
+
awsRegion: config.awsRegion,
|
|
21
|
+
theme: config.brandColor,
|
|
22
|
+
createdAt: new Date().toISOString(),
|
|
23
|
+
accounts: {},
|
|
24
|
+
};
|
|
25
|
+
const configPath = join(outputDir, '.aws-starter-config.json');
|
|
26
|
+
writeFileSync(configPath, JSON.stringify(configContent, null, 2), 'utf-8');
|
|
27
|
+
}
|
|
9
28
|
/**
|
|
10
29
|
* Get the version from package.json
|
|
11
30
|
*/
|
|
@@ -26,20 +45,24 @@ create-aws-starter-kit [command] [options]
|
|
|
26
45
|
Scaffold a new AWS Starter Kit project with React, Lambda, and CDK infrastructure.
|
|
27
46
|
|
|
28
47
|
Commands:
|
|
29
|
-
(default)
|
|
30
|
-
setup-
|
|
48
|
+
(default) Create a new project (interactive wizard)
|
|
49
|
+
setup-aws-envs Set up AWS Organizations and environment accounts
|
|
50
|
+
initialize-github Configure GitHub Environment for deployment
|
|
51
|
+
setup-github ${pc.dim('[DEPRECATED]')} Use initialize-github instead
|
|
31
52
|
|
|
32
53
|
Options:
|
|
33
|
-
--help, -h
|
|
34
|
-
--version, -v
|
|
54
|
+
--help, -h Show this help message
|
|
55
|
+
--version, -v Show version number
|
|
35
56
|
|
|
36
57
|
Usage:
|
|
37
|
-
create-aws-starter-kit
|
|
38
|
-
create-aws-starter-kit setup-
|
|
58
|
+
create-aws-starter-kit Run interactive wizard
|
|
59
|
+
create-aws-starter-kit setup-aws-envs Create AWS accounts
|
|
60
|
+
create-aws-starter-kit initialize-github dev Configure dev environment
|
|
39
61
|
|
|
40
62
|
Examples:
|
|
41
63
|
create-aws-starter-kit my-app
|
|
42
|
-
create-aws-starter-kit setup-
|
|
64
|
+
create-aws-starter-kit setup-aws-envs
|
|
65
|
+
create-aws-starter-kit initialize-github dev
|
|
43
66
|
create-aws-starter-kit --help
|
|
44
67
|
`.trim());
|
|
45
68
|
}
|
|
@@ -81,31 +104,16 @@ function printNextSteps(projectName, platforms) {
|
|
|
81
104
|
console.log(` ${pc.cyan('npm run cdk:deploy')}`);
|
|
82
105
|
console.log('');
|
|
83
106
|
}
|
|
107
|
+
console.log(` ${pc.gray('# Configure AWS environments')}`);
|
|
108
|
+
console.log(` ${pc.cyan('npx create-aws-project setup-aws-envs')}`);
|
|
109
|
+
console.log('');
|
|
84
110
|
console.log(pc.gray('Happy coding!'));
|
|
85
111
|
}
|
|
86
112
|
/**
|
|
87
|
-
*
|
|
113
|
+
* Run the create project wizard flow
|
|
114
|
+
* This is the default command when no subcommand is specified
|
|
88
115
|
*/
|
|
89
|
-
|
|
90
|
-
const args = process.argv.slice(2);
|
|
91
|
-
// Check for --help or -h
|
|
92
|
-
if (args.includes('--help') || args.includes('-h')) {
|
|
93
|
-
printHelp();
|
|
94
|
-
process.exit(0);
|
|
95
|
-
}
|
|
96
|
-
// Check for --version or -v
|
|
97
|
-
if (args.includes('--version') || args.includes('-v')) {
|
|
98
|
-
console.log(getVersion());
|
|
99
|
-
process.exit(0);
|
|
100
|
-
}
|
|
101
|
-
// Check for subcommands (first non-flag argument)
|
|
102
|
-
const command = args.find((arg) => !arg.startsWith('-'));
|
|
103
|
-
// Handle setup-github command
|
|
104
|
-
if (command === 'setup-github') {
|
|
105
|
-
await runSetupGitHub();
|
|
106
|
-
process.exit(0);
|
|
107
|
-
}
|
|
108
|
-
// Default: run interactive wizard
|
|
116
|
+
async function runCreate(_args) {
|
|
109
117
|
printWelcome();
|
|
110
118
|
console.log(''); // blank line after banner
|
|
111
119
|
const config = await runWizard();
|
|
@@ -113,77 +121,6 @@ export async function run() {
|
|
|
113
121
|
console.log('\nProject creation cancelled.');
|
|
114
122
|
process.exit(1);
|
|
115
123
|
}
|
|
116
|
-
// Set up AWS Organizations if enabled
|
|
117
|
-
if (config.org?.enabled) {
|
|
118
|
-
console.log('');
|
|
119
|
-
console.log(pc.cyan('Setting up AWS Organizations...'));
|
|
120
|
-
try {
|
|
121
|
-
const orgClient = createOrganizationsClient(config.awsRegion);
|
|
122
|
-
// Check if already in an organization
|
|
123
|
-
const existingOrgId = await checkExistingOrganization(orgClient);
|
|
124
|
-
if (existingOrgId) {
|
|
125
|
-
console.log(pc.yellow(`Already in organization: ${existingOrgId}`));
|
|
126
|
-
console.log(pc.dim('Proceeding with existing organization...'));
|
|
127
|
-
}
|
|
128
|
-
else {
|
|
129
|
-
// Create new organization
|
|
130
|
-
console.log(pc.dim('Creating new AWS Organization...'));
|
|
131
|
-
const orgId = await createOrganization(orgClient);
|
|
132
|
-
console.log(pc.green('✔') + ` Organization created: ${orgId}`);
|
|
133
|
-
}
|
|
134
|
-
// Create environment accounts
|
|
135
|
-
const accountResults = await createEnvironmentAccounts(orgClient, config.org.organizationName, config.org.accounts);
|
|
136
|
-
// Update config.org.accounts with returned accountIds
|
|
137
|
-
for (const result of accountResults) {
|
|
138
|
-
const account = config.org.accounts.find((a) => a.environment === result.environment);
|
|
139
|
-
if (account) {
|
|
140
|
-
account.accountId = result.accountId;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
console.log('');
|
|
144
|
-
console.log(pc.green('✔') + ' AWS Organizations setup complete');
|
|
145
|
-
console.log(pc.dim('Account IDs:'));
|
|
146
|
-
for (const account of config.org.accounts) {
|
|
147
|
-
console.log(pc.dim(` ${account.environment}: ${account.accountId}`));
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
catch (error) {
|
|
151
|
-
console.log('');
|
|
152
|
-
// Handle specific AWS errors
|
|
153
|
-
if (error instanceof Error) {
|
|
154
|
-
if (error.name === 'CredentialsProviderError' ||
|
|
155
|
-
error.message.includes('Could not load credentials')) {
|
|
156
|
-
console.log(pc.red('Error:') + ' AWS credentials not configured.');
|
|
157
|
-
console.log('');
|
|
158
|
-
console.log('Please configure AWS credentials using one of these methods:');
|
|
159
|
-
console.log(' 1. Run: ' + pc.cyan('aws configure'));
|
|
160
|
-
console.log(' 2. Set environment variables: ' + pc.cyan('AWS_ACCESS_KEY_ID') + ' and ' + pc.cyan('AWS_SECRET_ACCESS_KEY'));
|
|
161
|
-
console.log(' 3. Use an AWS profile: ' + pc.cyan('export AWS_PROFILE=your-profile'));
|
|
162
|
-
process.exit(1);
|
|
163
|
-
}
|
|
164
|
-
if (error.name === 'AccessDeniedException' ||
|
|
165
|
-
error.message.includes('not authorized')) {
|
|
166
|
-
console.log(pc.red('Error:') + ' Insufficient AWS permissions.');
|
|
167
|
-
console.log('');
|
|
168
|
-
console.log('Required IAM permissions for AWS Organizations:');
|
|
169
|
-
console.log(' - ' + pc.cyan('organizations:CreateOrganization'));
|
|
170
|
-
console.log(' - ' + pc.cyan('organizations:DescribeOrganization'));
|
|
171
|
-
console.log(' - ' + pc.cyan('organizations:CreateAccount'));
|
|
172
|
-
console.log(' - ' + pc.cyan('organizations:DescribeCreateAccountStatus'));
|
|
173
|
-
process.exit(1);
|
|
174
|
-
}
|
|
175
|
-
// Log which account failed if it's an account creation error
|
|
176
|
-
if (error.message.includes('Failed to create')) {
|
|
177
|
-
console.log(pc.red('Error:') + ` ${error.message}`);
|
|
178
|
-
process.exit(1);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
// Generic error
|
|
182
|
-
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
183
|
-
console.log(pc.red('Error:') + ` AWS Organizations setup failed: ${message}`);
|
|
184
|
-
process.exit(1);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
124
|
// Determine output directory
|
|
188
125
|
const outputDir = resolve(process.cwd(), config.projectName);
|
|
189
126
|
// Check if directory already exists
|
|
@@ -198,9 +135,49 @@ export async function run() {
|
|
|
198
135
|
// Generate project
|
|
199
136
|
console.log('');
|
|
200
137
|
await generateProject(config, outputDir);
|
|
138
|
+
// Write config file for downstream commands
|
|
139
|
+
writeConfigFile(outputDir, config);
|
|
201
140
|
// Success message and next steps
|
|
202
141
|
console.log('');
|
|
203
142
|
console.log(pc.green('✔') + ` Created ${pc.bold(config.projectName)} successfully!`);
|
|
204
143
|
printNextSteps(config.projectName, config.platforms);
|
|
205
144
|
process.exit(0);
|
|
206
145
|
}
|
|
146
|
+
/**
|
|
147
|
+
* Parse command line arguments and run the CLI
|
|
148
|
+
*/
|
|
149
|
+
export async function run() {
|
|
150
|
+
const args = process.argv.slice(2);
|
|
151
|
+
// Check for --help or -h
|
|
152
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
153
|
+
printHelp();
|
|
154
|
+
process.exit(0);
|
|
155
|
+
}
|
|
156
|
+
// Check for --version or -v
|
|
157
|
+
if (args.includes('--version') || args.includes('-v')) {
|
|
158
|
+
console.log(getVersion());
|
|
159
|
+
process.exit(0);
|
|
160
|
+
}
|
|
161
|
+
// Find the command (first non-flag argument)
|
|
162
|
+
const commandIndex = args.findIndex((arg) => !arg.startsWith('-'));
|
|
163
|
+
const command = commandIndex !== -1 ? args[commandIndex] : undefined;
|
|
164
|
+
const commandArgs = commandIndex !== -1 ? args.slice(commandIndex + 1) : [];
|
|
165
|
+
// Route to appropriate command handler
|
|
166
|
+
switch (command) {
|
|
167
|
+
case 'setup-aws-envs':
|
|
168
|
+
await runSetupAwsEnvs(commandArgs);
|
|
169
|
+
break;
|
|
170
|
+
case 'initialize-github':
|
|
171
|
+
await runInitializeGitHub(commandArgs);
|
|
172
|
+
break;
|
|
173
|
+
case 'setup-github':
|
|
174
|
+
// Deprecated command - show notice and exit
|
|
175
|
+
showDeprecationNotice();
|
|
176
|
+
break;
|
|
177
|
+
default:
|
|
178
|
+
// Default: run interactive create wizard
|
|
179
|
+
// This handles both no command and unknown commands
|
|
180
|
+
await runCreate(args);
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* initialize-github command
|
|
3
|
+
*
|
|
4
|
+
* Configures GitHub Environment with AWS credentials for a single environment
|
|
5
|
+
* Must be run from inside a project directory
|
|
6
|
+
* Requires environment name as argument (dev, stage, prod)
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Runs the initialize-github command
|
|
10
|
+
*
|
|
11
|
+
* @param args Command arguments - expects environment name as first arg (optional)
|
|
12
|
+
*/
|
|
13
|
+
export declare function runInitializeGitHub(args: string[]): Promise<void>;
|