diff --git a/cli/commands/configure.py b/cli/commands/configure.py index 7f4c5cb..0ab7ef6 100644 --- a/cli/commands/configure.py +++ b/cli/commands/configure.py @@ -20,9 +20,6 @@ PLUGINS = ["CKAN", "Socrata", "ArcGIS"] -# Bucket name must match the `backend "s3"` block in terraform/aws/main.tf. -TERRAFORM_STATE_BUCKET = "opencontext-terraform-state" - def _ensure_state_bucket(bucket_name: str, region: str) -> None: """Check that the Terraform S3 state bucket exists; create it if not. @@ -198,19 +195,8 @@ def _write_tfvars( @friendly_exit -def configure( - state_bucket: str = typer.Option( - TERRAFORM_STATE_BUCKET, - "--state-bucket", - help="S3 bucket name for Terraform state (default: opencontext-terraform-state)", - ), -) -> None: +def configure() -> None: """Interactive wizard to configure your OpenContext MCP server.""" - # When called programmatically (e.g. in tests), Typer does not resolve - # Option defaults — guard against receiving the raw OptionInfo sentinel. - if not isinstance(state_bucket, str): - state_bucket = TERRAFORM_STATE_BUCKET - project_root = get_project_root() terraform_dir = get_terraform_dir() @@ -274,6 +260,19 @@ def configure( raise typer.Exit(0) city_slug = city_name.lower().replace(" ", "-") + + # Prompt for a unique S3 bucket name for Terraform state. + # S3 bucket names are globally unique across all AWS accounts, so the + # default includes the org city slug to avoid collisions with other + # deployments of this project. + suggested_bucket = f"opencontext-terraform-state-{city_slug}" + state_bucket = questionary.text( + "S3 bucket name for Terraform state:", + default=suggested_bucket, + ).ask() + if state_bucket is None: + raise typer.Exit(0) + suggested_lambda = f"{city_slug}-opencontext-mcp-{env}" lambda_name = questionary.text( @@ -398,6 +397,7 @@ def configure( summary.add_row("City", city_name) summary.add_row("Environment", env) summary.add_row("Plugin", plugin) + summary.add_row("Terraform state bucket", state_bucket) summary.add_row("Lambda name", lambda_name) summary.add_row("AWS region", region) summary.add_row("Lambda memory", f"{lambda_memory} MB") diff --git a/cli/commands/validate.py b/cli/commands/validate.py index c46075a..98b8552 100644 --- a/cli/commands/validate.py +++ b/cli/commands/validate.py @@ -130,36 +130,13 @@ def run_checks(env: str) -> bool: ".terraform directory found" if tf_initialized else "Run: opencontext configure", )) - # 7. terraform validate - if tf_installed and tf_initialized: - try: - result = subprocess.run( - ["terraform", "validate", "-json"], - cwd=terraform_dir, - capture_output=True, text=True, timeout=30, - ) - if result.returncode == 0: - checks.append(("terraform validate", True, "Configuration valid")) - else: - error_msg = "" - try: - data = json.loads(result.stdout) - error_msg = data.get("error_message", "") - except Exception: - pass - if not error_msg: - error_msg = (result.stderr or result.stdout or "Validation failed").strip() - checks.append(("terraform validate", False, error_msg[:100])) - except (FileNotFoundError, subprocess.TimeoutExpired) as e: - checks.append(("terraform validate", False, str(e)[:80])) - else: - checks.append(( - "terraform validate", - False, - "Skipped — terraform not installed or not initialized", - )) + # Note: terraform validate is intentionally skipped here because it + # references lambda-deployment.zip, which does not exist until the + # packaging step inside `opencontext deploy`. Running validate before + # packaging would always fail. Terraform plan (run inside deploy) catches + # the same configuration errors after the zip has been created. - # 8. AWS credentials valid + # 7. AWS credentials valid try: result = subprocess.run( ["aws", "sts", "get-caller-identity", "--output", "json"], @@ -179,7 +156,7 @@ def run_checks(env: str) -> bool: except (subprocess.TimeoutExpired, json.JSONDecodeError): checks.append(("AWS credentials valid", False, "Run: aws configure")) - # 9. ACM cert exists for custom domain (only if custom_domain is set) + # 8. ACM cert exists for custom domain (only if custom_domain is set) if custom_domain: try: result = subprocess.run( diff --git a/terraform/bootstrap/variables.tf b/terraform/bootstrap/variables.tf index 625c8c2..3a87afe 100644 --- a/terraform/bootstrap/variables.tf +++ b/terraform/bootstrap/variables.tf @@ -7,5 +7,4 @@ variable "aws_region" { variable "state_bucket_name" { description = "Name of the S3 bucket for Terraform state" type = string - default = "opencontext-terraform-state" }