Skip to content

Commit 0b70bdf

Browse files
committed
Add auto connect for aws
1 parent 656e6f3 commit 0b70bdf

File tree

1 file changed

+143
-0
lines changed

1 file changed

+143
-0
lines changed

cirun/cloud.py

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,149 @@ def create_azure(
242242
_connect_cloud(name="azure", credentials=credentials)
243243

244244

245+
@cloud_create.command(name="aws")
246+
def create_aws(
247+
name: str = typer.Option(
248+
None,
249+
"--name",
250+
help="Name for the IAM user (optional, auto-generated if not provided)"
251+
),
252+
policy_arn: str = typer.Option(
253+
"arn:aws:iam::aws:policy/AmazonEC2FullAccess",
254+
"--policy-arn",
255+
help="IAM policy ARN to attach to the user"
256+
),
257+
auto_connect: bool = typer.Option(
258+
False,
259+
"--auto-connect",
260+
help="Automatically connect the created credentials to Cirun"
261+
),
262+
):
263+
"""Create AWS IAM User credentials for Cirun"""
264+
import os
265+
266+
console = Console()
267+
error_console = Console(stderr=True, style="bold red")
268+
269+
if auto_connect and not os.environ.get("CIRUN_API_KEY"):
270+
error_console.print("Error: CIRUN_API_KEY environment variable is required for --auto-connect")
271+
raise typer.Exit(code=1)
272+
273+
# Check if AWS CLI is installed
274+
try:
275+
subprocess.run(
276+
["aws", "--version"],
277+
capture_output=True,
278+
check=True
279+
)
280+
except (subprocess.CalledProcessError, FileNotFoundError):
281+
error_console.print("Error: AWS CLI is not installed or not found in PATH")
282+
error_console.print("Install it from: https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html")
283+
raise typer.Exit(code=1)
284+
285+
# Check caller identity
286+
console.print("[bold blue]Checking AWS CLI configuration...[/bold blue]")
287+
try:
288+
result = subprocess.run(
289+
["aws", "sts", "get-caller-identity", "--output", "json"],
290+
capture_output=True,
291+
check=True,
292+
text=True
293+
)
294+
caller_identity = json.loads(result.stdout)
295+
except subprocess.CalledProcessError:
296+
error_console.print("Error: Not authenticated with AWS CLI")
297+
error_console.print("Please run: aws configure")
298+
raise typer.Exit(code=1)
299+
300+
# Display account details
301+
console.print("\n[bold green]AWS Account Details:[/bold green]")
302+
console.print(f" Account ID: [bold]{caller_identity.get('Account', 'N/A')}[/bold]")
303+
console.print(f" ARN: [bold]{caller_identity.get('Arn', 'N/A')}[/bold]")
304+
console.print(f" User ID: [bold]{caller_identity.get('UserId', 'N/A')}[/bold]")
305+
console.print("")
306+
307+
# Generate IAM user name if not provided
308+
if not name:
309+
from datetime import datetime, timezone
310+
name = f"cirun-{datetime.now(timezone.utc).strftime('%Y%m%d-%H%M%S')}"
311+
312+
# Confirm before creating
313+
typer.confirm(
314+
f"Create IAM user '{name}' with policy '{policy_arn}'?",
315+
abort=True,
316+
)
317+
318+
# Create IAM user
319+
console.print(f"[bold blue]Creating IAM user '[bold green]{name}[/bold green]'...[/bold blue]")
320+
try:
321+
subprocess.run(
322+
["aws", "iam", "create-user", "--user-name", name],
323+
capture_output=True,
324+
check=True,
325+
text=True
326+
)
327+
except subprocess.CalledProcessError as e:
328+
error_console.print(f"Error creating IAM user: {e.stderr}")
329+
raise typer.Exit(code=1)
330+
331+
# Attach policy
332+
console.print(f"[bold blue]Attaching policy [bold green]{policy_arn}[/bold green]...[/bold blue]")
333+
try:
334+
subprocess.run(
335+
[
336+
"aws", "iam", "attach-user-policy",
337+
"--user-name", name,
338+
"--policy-arn", policy_arn,
339+
],
340+
capture_output=True,
341+
check=True,
342+
text=True
343+
)
344+
except subprocess.CalledProcessError as e:
345+
error_console.print(f"Error attaching policy: {e.stderr}")
346+
raise typer.Exit(code=1)
347+
348+
# Create access key
349+
console.print("[bold blue]Creating access key...[/bold blue]")
350+
try:
351+
result = subprocess.run(
352+
["aws", "iam", "create-access-key", "--user-name", name, "--output", "json"],
353+
capture_output=True,
354+
check=True,
355+
text=True
356+
)
357+
key_data = json.loads(result.stdout).get("AccessKey", {})
358+
except subprocess.CalledProcessError as e:
359+
error_console.print(f"Error creating access key: {e.stderr}")
360+
raise typer.Exit(code=1)
361+
362+
access_key = key_data.get("AccessKeyId")
363+
secret_key = key_data.get("SecretAccessKey")
364+
365+
# Display credentials
366+
success_console = Console(style="bold green")
367+
success_console.rule("[bold green]")
368+
success_console.print("[bold green]✓[/bold green] IAM user created successfully!")
369+
success_console.print("")
370+
success_console.print("[bold yellow]AWS Credentials for Cirun:[/bold yellow]")
371+
success_console.print("")
372+
success_console.print(f" AWS_ACCESS_KEY_ID: [bold]{access_key}[/bold]")
373+
success_console.print(f" AWS_SECRET_ACCESS_KEY: [bold]{secret_key}[/bold]")
374+
success_console.print("")
375+
success_console.print("[bold red]⚠️ Save the SECRET_ACCESS_KEY - it won't be shown again![/bold red]")
376+
success_console.rule("[bold green]")
377+
378+
# Auto-connect if requested
379+
if auto_connect:
380+
console.print("\n[bold blue]Connecting credentials to Cirun...[/bold blue]")
381+
credentials = {
382+
"access_key": access_key,
383+
"secret_key": secret_key,
384+
}
385+
_connect_cloud(name="aws", credentials=credentials)
386+
387+
245388
@cloud_create.command(name="gcp")
246389
def create_gcp(
247390
name: str = typer.Option(

0 commit comments

Comments
 (0)