awslabs.terraform-mcp-server 0.0.1__tar.gz
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.
Potentially problematic release.
This version of awslabs.terraform-mcp-server might be problematic. Click here for more details.
- awslabs_terraform_mcp_server-0.0.1/.gitignore +59 -0
- awslabs_terraform_mcp_server-0.0.1/.pre-commit-config.yaml +14 -0
- awslabs_terraform_mcp_server-0.0.1/.python-version +1 -0
- awslabs_terraform_mcp_server-0.0.1/CHANGELOG.md +12 -0
- awslabs_terraform_mcp_server-0.0.1/PKG-INFO +97 -0
- awslabs_terraform_mcp_server-0.0.1/README.md +82 -0
- awslabs_terraform_mcp_server-0.0.1/awslabs/__init__.py +2 -0
- awslabs_terraform_mcp_server-0.0.1/awslabs/terraform_mcp_server/__init__.py +3 -0
- awslabs_terraform_mcp_server-0.0.1/awslabs/terraform_mcp_server/impl/resources/__init__.py +11 -0
- awslabs_terraform_mcp_server-0.0.1/awslabs/terraform_mcp_server/impl/resources/terraform_aws_provider_resources_listing.py +52 -0
- awslabs_terraform_mcp_server-0.0.1/awslabs/terraform_mcp_server/impl/resources/terraform_awscc_provider_resources_listing.py +55 -0
- awslabs_terraform_mcp_server-0.0.1/awslabs/terraform_mcp_server/impl/tools/__init__.py +15 -0
- awslabs_terraform_mcp_server-0.0.1/awslabs/terraform_mcp_server/impl/tools/execute_terraform_command.py +206 -0
- awslabs_terraform_mcp_server-0.0.1/awslabs/terraform_mcp_server/impl/tools/run_checkov_scan.py +359 -0
- awslabs_terraform_mcp_server-0.0.1/awslabs/terraform_mcp_server/impl/tools/search_aws_provider_docs.py +677 -0
- awslabs_terraform_mcp_server-0.0.1/awslabs/terraform_mcp_server/impl/tools/search_awscc_provider_docs.py +627 -0
- awslabs_terraform_mcp_server-0.0.1/awslabs/terraform_mcp_server/impl/tools/search_specific_aws_ia_modules.py +444 -0
- awslabs_terraform_mcp_server-0.0.1/awslabs/terraform_mcp_server/impl/tools/utils.py +558 -0
- awslabs_terraform_mcp_server-0.0.1/awslabs/terraform_mcp_server/models/__init__.py +27 -0
- awslabs_terraform_mcp_server-0.0.1/awslabs/terraform_mcp_server/models/models.py +260 -0
- awslabs_terraform_mcp_server-0.0.1/awslabs/terraform_mcp_server/scripts/generate_aws_provider_resources.py +1224 -0
- awslabs_terraform_mcp_server-0.0.1/awslabs/terraform_mcp_server/scripts/generate_awscc_provider_resources.py +1020 -0
- awslabs_terraform_mcp_server-0.0.1/awslabs/terraform_mcp_server/scripts/scrape_aws_terraform_best_practices.py +129 -0
- awslabs_terraform_mcp_server-0.0.1/awslabs/terraform_mcp_server/server.py +329 -0
- awslabs_terraform_mcp_server-0.0.1/awslabs/terraform_mcp_server/static/AWSCC_PROVIDER_RESOURCES.md +3125 -0
- awslabs_terraform_mcp_server-0.0.1/awslabs/terraform_mcp_server/static/AWS_PROVIDER_RESOURCES.md +3833 -0
- awslabs_terraform_mcp_server-0.0.1/awslabs/terraform_mcp_server/static/AWS_TERRAFORM_BEST_PRACTICES.md +2523 -0
- awslabs_terraform_mcp_server-0.0.1/awslabs/terraform_mcp_server/static/MCP_INSTRUCTIONS.md +126 -0
- awslabs_terraform_mcp_server-0.0.1/awslabs/terraform_mcp_server/static/TERRAFORM_WORKFLOW_GUIDE.md +198 -0
- awslabs_terraform_mcp_server-0.0.1/awslabs/terraform_mcp_server/static/__init__.py +22 -0
- awslabs_terraform_mcp_server-0.0.1/awslabs/terraform_mcp_server/tests/__init__.py +1 -0
- awslabs_terraform_mcp_server-0.0.1/awslabs/terraform_mcp_server/tests/run_tests.sh +35 -0
- awslabs_terraform_mcp_server-0.0.1/awslabs/terraform_mcp_server/tests/test_parameter_annotations.py +207 -0
- awslabs_terraform_mcp_server-0.0.1/awslabs/terraform_mcp_server/tests/test_tool_implementations.py +309 -0
- awslabs_terraform_mcp_server-0.0.1/pyproject.toml +85 -0
- awslabs_terraform_mcp_server-0.0.1/uv.lock +2634 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
build/
|
|
8
|
+
develop-eggs/
|
|
9
|
+
dist/
|
|
10
|
+
downloads/
|
|
11
|
+
eggs/
|
|
12
|
+
.eggs/
|
|
13
|
+
lib/
|
|
14
|
+
lib64/
|
|
15
|
+
parts/
|
|
16
|
+
sdist/
|
|
17
|
+
var/
|
|
18
|
+
wheels/
|
|
19
|
+
share/python-wheels/
|
|
20
|
+
*.egg-info/
|
|
21
|
+
.installed.cfg
|
|
22
|
+
*.egg
|
|
23
|
+
MANIFEST
|
|
24
|
+
|
|
25
|
+
# Virtual environments
|
|
26
|
+
.venv
|
|
27
|
+
env/
|
|
28
|
+
venv/
|
|
29
|
+
ENV/
|
|
30
|
+
|
|
31
|
+
# IDE
|
|
32
|
+
.idea/
|
|
33
|
+
.vscode/
|
|
34
|
+
*.swp
|
|
35
|
+
*.swo
|
|
36
|
+
|
|
37
|
+
# Testing
|
|
38
|
+
.tox/
|
|
39
|
+
.coverage
|
|
40
|
+
.coverage.*
|
|
41
|
+
htmlcov/
|
|
42
|
+
.pytest_cache/
|
|
43
|
+
|
|
44
|
+
# Ruff
|
|
45
|
+
.ruff_cache/
|
|
46
|
+
|
|
47
|
+
# Build
|
|
48
|
+
*.manifest
|
|
49
|
+
*.spec
|
|
50
|
+
.pybuilder/
|
|
51
|
+
target/
|
|
52
|
+
|
|
53
|
+
# Environments
|
|
54
|
+
.env
|
|
55
|
+
.env.local
|
|
56
|
+
.env.*.local
|
|
57
|
+
|
|
58
|
+
# PyPI
|
|
59
|
+
.pypirc
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
3
|
+
rev: v0.9.6
|
|
4
|
+
hooks:
|
|
5
|
+
- id: ruff
|
|
6
|
+
args: [--fix]
|
|
7
|
+
- id: ruff-format
|
|
8
|
+
|
|
9
|
+
- repo: https://github.com/commitizen-tools/commitizen
|
|
10
|
+
rev: v3.13.0
|
|
11
|
+
hooks:
|
|
12
|
+
- id: commitizen
|
|
13
|
+
- id: commitizen-branch
|
|
14
|
+
stages: [push]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.10
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## Unreleased
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Initial project setup
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: awslabs.terraform-mcp-server
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: An AWS Labs Model Context Protocol (MCP) server for terraform
|
|
5
|
+
Requires-Python: >=3.10
|
|
6
|
+
Requires-Dist: beautifulsoup4>=4.12.0
|
|
7
|
+
Requires-Dist: checkov>=3.2.402
|
|
8
|
+
Requires-Dist: loguru>=0.7.0
|
|
9
|
+
Requires-Dist: mcp[cli]>=1.6.0
|
|
10
|
+
Requires-Dist: playwright>=1.40.0
|
|
11
|
+
Requires-Dist: pydantic>=2.10.6
|
|
12
|
+
Requires-Dist: pypdf2>=3.0.0
|
|
13
|
+
Requires-Dist: requests>=2.31.0
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
|
|
16
|
+
# AWS Terraform MCP Server
|
|
17
|
+
|
|
18
|
+
MCP server for Terraform on AWS best practices, infrastructure as code patterns, and security compliance with Checkov.
|
|
19
|
+
|
|
20
|
+
## Features
|
|
21
|
+
|
|
22
|
+
- **Terraform Best Practices** - Get prescriptive Terraform advice for building applications on AWS
|
|
23
|
+
- AWS Well-Architected guidance for Terraform configurations
|
|
24
|
+
- Security and compliance recommendations
|
|
25
|
+
- AWSCC provider prioritization for consistent API behavior
|
|
26
|
+
|
|
27
|
+
- **Security-First Development Workflow** - Follow a structured process for creating secure code
|
|
28
|
+
- Step-by-step guidance for validation and security scanning
|
|
29
|
+
- Integration of Checkov at the right stages of development
|
|
30
|
+
- Clear handoff points between AI assistance and developer deployment
|
|
31
|
+
|
|
32
|
+
- **Checkov Integration** - Work with Checkov for security and compliance scanning
|
|
33
|
+
- Run security scans on Terraform code to identify vulnerabilities
|
|
34
|
+
- Automatically fix identified security issues when possible
|
|
35
|
+
- Get detailed remediation guidance for compliance issues
|
|
36
|
+
|
|
37
|
+
- **AWS Provider Documentation** - Search for AWS and AWSCC provider resources
|
|
38
|
+
- Find documentation for specific resources and attributes
|
|
39
|
+
- Get example snippets and implementation guidance
|
|
40
|
+
- Compare AWS and AWSCC provider capabilities
|
|
41
|
+
|
|
42
|
+
- **AWS-IA GenAI Modules** - Access specialized modules for AI/ML workloads
|
|
43
|
+
- Amazon Bedrock module for generative AI applications
|
|
44
|
+
- OpenSearch Serverless for vector search capabilities
|
|
45
|
+
- SageMaker endpoint deployment for ML model hosting
|
|
46
|
+
- Serverless Streamlit application deployment for AI interfaces
|
|
47
|
+
|
|
48
|
+
- **Terraform Workflow Execution** - Run Terraform commands directly
|
|
49
|
+
- Initialize, plan, validate, apply, and destroy operations
|
|
50
|
+
- Pass variables and specify AWS regions
|
|
51
|
+
- Get formatted command output for analysis
|
|
52
|
+
|
|
53
|
+
## Tools and Resources
|
|
54
|
+
|
|
55
|
+
- **Terraform Development Workflow**: Follow security-focused development process via `terraform://workflow_guide`
|
|
56
|
+
- **AWS Best Practices**: Access AWS-specific guidance via `terraform://aws_best_practices`
|
|
57
|
+
- **AWS Provider Resources**: Access resource listings via `terraform://aws_provider_resources_listing`
|
|
58
|
+
- **AWSCC Provider Resources**: Access resource listings via `terraform://awscc_provider_resources_listing`
|
|
59
|
+
|
|
60
|
+
## Prerequisites
|
|
61
|
+
|
|
62
|
+
1. Install `uv` from [Astral](https://docs.astral.sh/uv/getting-started/installation/) or the [GitHub README](https://github.com/astral-sh/uv#installation)
|
|
63
|
+
2. Install Python using `uv python install 3.10`
|
|
64
|
+
3. Install Terraform CLI for workflow execution
|
|
65
|
+
4. Install Checkov for security scanning
|
|
66
|
+
|
|
67
|
+
## Installation
|
|
68
|
+
|
|
69
|
+
Here are some ways you can work with MCP across AWS, and we'll be adding support to more products including Amazon Q Developer CLI soon: (e.g. for Amazon Q Developer CLI MCP, `~/.aws/amazonq/mcp.json`):
|
|
70
|
+
|
|
71
|
+
```json
|
|
72
|
+
{
|
|
73
|
+
"mcpServers": {
|
|
74
|
+
"awslabs.terraform-mcp-server": {
|
|
75
|
+
"command": "uvx",
|
|
76
|
+
"args": ["awslabs.terraform-mcp-server@latest"],
|
|
77
|
+
"env": {
|
|
78
|
+
"FASTMCP_LOG_LEVEL": "ERROR"
|
|
79
|
+
},
|
|
80
|
+
"disabled": false,
|
|
81
|
+
"autoApprove": []
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Security Considerations
|
|
88
|
+
|
|
89
|
+
When using this MCP server, you should consider:
|
|
90
|
+
- **Following the structured development workflow** that integrates validation and security scanning
|
|
91
|
+
- Reviewing all Checkov warnings and errors manually
|
|
92
|
+
- Fixing security issues rather than ignoring them whenever possible
|
|
93
|
+
- Documenting clear justifications for any necessary exceptions
|
|
94
|
+
- Using the RunCheckovScan tool regularly to verify security compliance
|
|
95
|
+
- Preferring the AWSCC provider for its consistent API behavior and better security defaults
|
|
96
|
+
|
|
97
|
+
Before applying Terraform changes to production environments, you should conduct your own independent assessment to ensure that your infrastructure would comply with your own specific security and quality control practices and standards, as well as the local laws, rules, and regulations that govern you and your content.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# AWS Terraform MCP Server
|
|
2
|
+
|
|
3
|
+
MCP server for Terraform on AWS best practices, infrastructure as code patterns, and security compliance with Checkov.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Terraform Best Practices** - Get prescriptive Terraform advice for building applications on AWS
|
|
8
|
+
- AWS Well-Architected guidance for Terraform configurations
|
|
9
|
+
- Security and compliance recommendations
|
|
10
|
+
- AWSCC provider prioritization for consistent API behavior
|
|
11
|
+
|
|
12
|
+
- **Security-First Development Workflow** - Follow a structured process for creating secure code
|
|
13
|
+
- Step-by-step guidance for validation and security scanning
|
|
14
|
+
- Integration of Checkov at the right stages of development
|
|
15
|
+
- Clear handoff points between AI assistance and developer deployment
|
|
16
|
+
|
|
17
|
+
- **Checkov Integration** - Work with Checkov for security and compliance scanning
|
|
18
|
+
- Run security scans on Terraform code to identify vulnerabilities
|
|
19
|
+
- Automatically fix identified security issues when possible
|
|
20
|
+
- Get detailed remediation guidance for compliance issues
|
|
21
|
+
|
|
22
|
+
- **AWS Provider Documentation** - Search for AWS and AWSCC provider resources
|
|
23
|
+
- Find documentation for specific resources and attributes
|
|
24
|
+
- Get example snippets and implementation guidance
|
|
25
|
+
- Compare AWS and AWSCC provider capabilities
|
|
26
|
+
|
|
27
|
+
- **AWS-IA GenAI Modules** - Access specialized modules for AI/ML workloads
|
|
28
|
+
- Amazon Bedrock module for generative AI applications
|
|
29
|
+
- OpenSearch Serverless for vector search capabilities
|
|
30
|
+
- SageMaker endpoint deployment for ML model hosting
|
|
31
|
+
- Serverless Streamlit application deployment for AI interfaces
|
|
32
|
+
|
|
33
|
+
- **Terraform Workflow Execution** - Run Terraform commands directly
|
|
34
|
+
- Initialize, plan, validate, apply, and destroy operations
|
|
35
|
+
- Pass variables and specify AWS regions
|
|
36
|
+
- Get formatted command output for analysis
|
|
37
|
+
|
|
38
|
+
## Tools and Resources
|
|
39
|
+
|
|
40
|
+
- **Terraform Development Workflow**: Follow security-focused development process via `terraform://workflow_guide`
|
|
41
|
+
- **AWS Best Practices**: Access AWS-specific guidance via `terraform://aws_best_practices`
|
|
42
|
+
- **AWS Provider Resources**: Access resource listings via `terraform://aws_provider_resources_listing`
|
|
43
|
+
- **AWSCC Provider Resources**: Access resource listings via `terraform://awscc_provider_resources_listing`
|
|
44
|
+
|
|
45
|
+
## Prerequisites
|
|
46
|
+
|
|
47
|
+
1. Install `uv` from [Astral](https://docs.astral.sh/uv/getting-started/installation/) or the [GitHub README](https://github.com/astral-sh/uv#installation)
|
|
48
|
+
2. Install Python using `uv python install 3.10`
|
|
49
|
+
3. Install Terraform CLI for workflow execution
|
|
50
|
+
4. Install Checkov for security scanning
|
|
51
|
+
|
|
52
|
+
## Installation
|
|
53
|
+
|
|
54
|
+
Here are some ways you can work with MCP across AWS, and we'll be adding support to more products including Amazon Q Developer CLI soon: (e.g. for Amazon Q Developer CLI MCP, `~/.aws/amazonq/mcp.json`):
|
|
55
|
+
|
|
56
|
+
```json
|
|
57
|
+
{
|
|
58
|
+
"mcpServers": {
|
|
59
|
+
"awslabs.terraform-mcp-server": {
|
|
60
|
+
"command": "uvx",
|
|
61
|
+
"args": ["awslabs.terraform-mcp-server@latest"],
|
|
62
|
+
"env": {
|
|
63
|
+
"FASTMCP_LOG_LEVEL": "ERROR"
|
|
64
|
+
},
|
|
65
|
+
"disabled": false,
|
|
66
|
+
"autoApprove": []
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Security Considerations
|
|
73
|
+
|
|
74
|
+
When using this MCP server, you should consider:
|
|
75
|
+
- **Following the structured development workflow** that integrates validation and security scanning
|
|
76
|
+
- Reviewing all Checkov warnings and errors manually
|
|
77
|
+
- Fixing security issues rather than ignoring them whenever possible
|
|
78
|
+
- Documenting clear justifications for any necessary exceptions
|
|
79
|
+
- Using the RunCheckovScan tool regularly to verify security compliance
|
|
80
|
+
- Preferring the AWSCC provider for its consistent API behavior and better security defaults
|
|
81
|
+
|
|
82
|
+
Before applying Terraform changes to production environments, you should conduct your own independent assessment to ensure that your infrastructure would comply with your own specific security and quality control practices and standards, as well as the local laws, rules, and regulations that govern you and your content.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""Resource implementations for the Terraform expert."""
|
|
2
|
+
|
|
3
|
+
from .terraform_aws_provider_resources_listing import terraform_aws_provider_assets_listing_impl
|
|
4
|
+
from .terraform_awscc_provider_resources_listing import (
|
|
5
|
+
terraform_awscc_provider_resources_listing_impl,
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
__all__ = [
|
|
9
|
+
'terraform_aws_provider_assets_listing_impl',
|
|
10
|
+
'terraform_awscc_provider_resources_listing_impl',
|
|
11
|
+
]
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"""Implementation for terraform_aws_provider_resources_listing resource."""
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
from loguru import logger
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
# Configure logger for enhanced diagnostics with stacktraces
|
|
9
|
+
logger.configure(
|
|
10
|
+
handlers=[
|
|
11
|
+
{
|
|
12
|
+
'sink': sys.stderr,
|
|
13
|
+
'backtrace': True,
|
|
14
|
+
'diagnose': True,
|
|
15
|
+
'format': '<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green> | <level>{level: <8}</level> | <cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - <level>{message}</level>',
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
# Path to the static markdown file
|
|
21
|
+
STATIC_RESOURCES_PATH = (
|
|
22
|
+
Path(__file__).parent.parent.parent / 'static' / 'AWS_PROVIDER_RESOURCES.md'
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
async def terraform_aws_provider_assets_listing_impl() -> str:
|
|
27
|
+
"""Generate a comprehensive listing of AWS provider resources and data sources.
|
|
28
|
+
|
|
29
|
+
This implementation reads from a pre-generated static markdown file instead of
|
|
30
|
+
scraping the web in real-time. The static file should be generated using the
|
|
31
|
+
generate_aws_provider_resources.py script.
|
|
32
|
+
|
|
33
|
+
Returns:
|
|
34
|
+
A markdown formatted string with categorized resources and data sources
|
|
35
|
+
"""
|
|
36
|
+
logger.info('Loading AWS provider resources listing from static file')
|
|
37
|
+
|
|
38
|
+
try:
|
|
39
|
+
# Check if the static file exists
|
|
40
|
+
if STATIC_RESOURCES_PATH.exists():
|
|
41
|
+
# Read the static file content
|
|
42
|
+
with open(STATIC_RESOURCES_PATH, 'r') as f:
|
|
43
|
+
content = f.read()
|
|
44
|
+
logger.info('Successfully loaded AWS Provider asset list')
|
|
45
|
+
return content
|
|
46
|
+
else:
|
|
47
|
+
# Send error if static file does not exist
|
|
48
|
+
logger.debug(f"Static assets list file not found at '{STATIC_RESOURCES_PATH}'")
|
|
49
|
+
raise Exception('Static assets list file not found')
|
|
50
|
+
except Exception as e:
|
|
51
|
+
logger.error(f'Error generating AWS provider assets listing: {e}')
|
|
52
|
+
return f'# AWS Provider Assets Listing\n\nError generating listing: {str(e)}'
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"""Implementation for terraform_awscc_provider_resources_listing resource."""
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
from loguru import logger
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
# Configure logger for enhanced diagnostics with stacktraces
|
|
9
|
+
logger.configure(
|
|
10
|
+
handlers=[
|
|
11
|
+
{
|
|
12
|
+
'sink': sys.stderr,
|
|
13
|
+
'backtrace': True,
|
|
14
|
+
'diagnose': True,
|
|
15
|
+
'format': '<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green> | <level>{level: <8}</level> | <cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - <level>{message}</level>',
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
# Path to the static markdown file
|
|
21
|
+
STATIC_RESOURCES_PATH = (
|
|
22
|
+
Path(__file__).parent.parent.parent / 'static' / 'AWSCC_PROVIDER_RESOURCES.md'
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
async def terraform_awscc_provider_resources_listing_impl() -> str:
|
|
27
|
+
"""Generate a comprehensive listing of AWSCC provider resources and data sources.
|
|
28
|
+
|
|
29
|
+
This implementation reads from a pre-generated static markdown file instead of
|
|
30
|
+
scraping the web in real-time. The static file should be generated using the
|
|
31
|
+
generate_awscc_provider_resources.py script.
|
|
32
|
+
|
|
33
|
+
Returns:
|
|
34
|
+
A markdown formatted string with categorized resources and data sources
|
|
35
|
+
"""
|
|
36
|
+
logger.info('Loading AWSCC provider resources listing from static file')
|
|
37
|
+
|
|
38
|
+
try:
|
|
39
|
+
# Check if the static file exists
|
|
40
|
+
if STATIC_RESOURCES_PATH.exists():
|
|
41
|
+
# Read the static file content
|
|
42
|
+
with open(STATIC_RESOURCES_PATH, 'r') as f:
|
|
43
|
+
content = f.read()
|
|
44
|
+
|
|
45
|
+
logger.info(
|
|
46
|
+
f'Successfully loaded AWSCC provider resources from {STATIC_RESOURCES_PATH}'
|
|
47
|
+
)
|
|
48
|
+
return content
|
|
49
|
+
else:
|
|
50
|
+
# Send error if static file does not exist
|
|
51
|
+
logger.debug(f"Static assets list file not found at '{STATIC_RESOURCES_PATH}'")
|
|
52
|
+
raise Exception('Static assets list file not found')
|
|
53
|
+
except Exception as e:
|
|
54
|
+
logger.error(f'Error generating AWSCC provider resources listing: {e}')
|
|
55
|
+
return f'# AWSCC Provider Resources Listing\n\nError generating listing: {str(e)}'
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"""Tool implementations for the terraform MCP server."""
|
|
2
|
+
|
|
3
|
+
from .execute_terraform_command import execute_terraform_command_impl
|
|
4
|
+
from .search_aws_provider_docs import search_aws_provider_docs_impl
|
|
5
|
+
from .search_awscc_provider_docs import search_awscc_provider_docs_impl
|
|
6
|
+
from .search_specific_aws_ia_modules import search_specific_aws_ia_modules_impl
|
|
7
|
+
from .run_checkov_scan import run_checkov_scan_impl
|
|
8
|
+
|
|
9
|
+
__all__ = [
|
|
10
|
+
'execute_terraform_command_impl',
|
|
11
|
+
'search_aws_provider_docs_impl',
|
|
12
|
+
'search_awscc_provider_docs_impl',
|
|
13
|
+
'search_specific_aws_ia_modules_impl',
|
|
14
|
+
'run_checkov_scan_impl',
|
|
15
|
+
]
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
"""Implementation of Terraform command execution tool."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
import re
|
|
6
|
+
import subprocess
|
|
7
|
+
from awslabs.terraform_mcp_server.impl.tools.utils import get_dangerous_patterns
|
|
8
|
+
from awslabs.terraform_mcp_server.models import TerraformExecutionRequest, TerraformExecutionResult
|
|
9
|
+
from loguru import logger
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
async def execute_terraform_command_impl(
|
|
13
|
+
request: TerraformExecutionRequest,
|
|
14
|
+
) -> TerraformExecutionResult:
|
|
15
|
+
"""Execute Terraform workflow commands against an AWS account.
|
|
16
|
+
|
|
17
|
+
This tool runs Terraform commands (init, plan, validate, apply, destroy) in the
|
|
18
|
+
specified working directory, with optional variables and region settings.
|
|
19
|
+
|
|
20
|
+
Parameters:
|
|
21
|
+
request: Details about the Terraform command to execute
|
|
22
|
+
|
|
23
|
+
Returns:
|
|
24
|
+
A TerraformExecutionResult object containing command output and status
|
|
25
|
+
"""
|
|
26
|
+
logger.info(f"Executing 'terraform {request.command}' in {request.working_directory}")
|
|
27
|
+
|
|
28
|
+
# Helper function to clean output text
|
|
29
|
+
def clean_output_text(text: str) -> str:
|
|
30
|
+
"""Clean output text by removing or replacing problematic Unicode characters.
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
text: The text to clean
|
|
34
|
+
|
|
35
|
+
Returns:
|
|
36
|
+
Cleaned text with ASCII-friendly replacements
|
|
37
|
+
"""
|
|
38
|
+
if not text:
|
|
39
|
+
return text
|
|
40
|
+
|
|
41
|
+
# First remove ANSI escape sequences (color codes, cursor movement)
|
|
42
|
+
ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
|
|
43
|
+
text = ansi_escape.sub('', text)
|
|
44
|
+
|
|
45
|
+
# Remove C0 and C1 control characters (except common whitespace)
|
|
46
|
+
control_chars = re.compile(r'[\x00-\x08\x0B-\x0C\x0E-\x1F\x7F-\x9F]')
|
|
47
|
+
text = control_chars.sub('', text)
|
|
48
|
+
|
|
49
|
+
# Replace HTML entities
|
|
50
|
+
html_entities = {
|
|
51
|
+
'->': '->', # Replace HTML arrow
|
|
52
|
+
'<': '<', # Less than
|
|
53
|
+
'>': '>', # Greater than
|
|
54
|
+
'&': '&', # Ampersand
|
|
55
|
+
}
|
|
56
|
+
for entity, replacement in html_entities.items():
|
|
57
|
+
text = text.replace(entity, replacement)
|
|
58
|
+
|
|
59
|
+
# Replace box-drawing and other special Unicode characters with ASCII equivalents
|
|
60
|
+
unicode_chars = {
|
|
61
|
+
'\u2500': '-', # Horizontal line
|
|
62
|
+
'\u2502': '|', # Vertical line
|
|
63
|
+
'\u2514': '+', # Up and right
|
|
64
|
+
'\u2518': '+', # Up and left
|
|
65
|
+
'\u2551': '|', # Double vertical
|
|
66
|
+
'\u2550': '-', # Double horizontal
|
|
67
|
+
'\u2554': '+', # Double down and right
|
|
68
|
+
'\u2557': '+', # Double down and left
|
|
69
|
+
'\u255a': '+', # Double up and right
|
|
70
|
+
'\u255d': '+', # Double up and left
|
|
71
|
+
'\u256c': '+', # Double cross
|
|
72
|
+
'\u2588': '#', # Full block
|
|
73
|
+
'\u25cf': '*', # Black circle
|
|
74
|
+
'\u2574': '-', # Left box drawing
|
|
75
|
+
'\u2576': '-', # Right box drawing
|
|
76
|
+
'\u2577': '|', # Down box drawing
|
|
77
|
+
'\u2575': '|', # Up box drawing
|
|
78
|
+
}
|
|
79
|
+
for char, replacement in unicode_chars.items():
|
|
80
|
+
text = text.replace(char, replacement)
|
|
81
|
+
|
|
82
|
+
return text
|
|
83
|
+
|
|
84
|
+
# Set environment variables for AWS region if provided
|
|
85
|
+
env = os.environ.copy()
|
|
86
|
+
if request.aws_region:
|
|
87
|
+
env['AWS_REGION'] = request.aws_region
|
|
88
|
+
|
|
89
|
+
# Security check for command injection
|
|
90
|
+
allowed_commands = ['init', 'plan', 'validate', 'apply', 'destroy']
|
|
91
|
+
if request.command not in allowed_commands:
|
|
92
|
+
logger.error(f'Invalid Terraform command: {request.command}')
|
|
93
|
+
return TerraformExecutionResult(
|
|
94
|
+
command=f'terraform {request.command}',
|
|
95
|
+
status='error',
|
|
96
|
+
error_message=f'Invalid Terraform command: {request.command}. Allowed commands are: {", ".join(allowed_commands)}',
|
|
97
|
+
working_directory=request.working_directory,
|
|
98
|
+
outputs=None,
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
# Check for potentially dangerous characters or command injection attempts
|
|
102
|
+
dangerous_patterns = get_dangerous_patterns()
|
|
103
|
+
logger.debug(f'Checking for {len(dangerous_patterns)} dangerous patterns')
|
|
104
|
+
|
|
105
|
+
for pattern in dangerous_patterns:
|
|
106
|
+
if request.variables:
|
|
107
|
+
# Check if the pattern is in any of the variable values
|
|
108
|
+
for var_name, var_value in request.variables.items():
|
|
109
|
+
if pattern in str(var_value) or pattern in str(var_name):
|
|
110
|
+
logger.error(
|
|
111
|
+
f'Potentially dangerous pattern detected in variable {var_name}: {pattern}'
|
|
112
|
+
)
|
|
113
|
+
return TerraformExecutionResult(
|
|
114
|
+
command=f'terraform {request.command}',
|
|
115
|
+
status='error',
|
|
116
|
+
error_message=f"Security violation: Potentially dangerous pattern '{pattern}' detected in variable '{var_name}'",
|
|
117
|
+
working_directory=request.working_directory,
|
|
118
|
+
outputs=None,
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
# Build the command
|
|
122
|
+
cmd = ['terraform', request.command]
|
|
123
|
+
|
|
124
|
+
# Add auto-approve flag for apply and destroy commands to make them non-interactive
|
|
125
|
+
if request.command in ['apply', 'destroy']:
|
|
126
|
+
logger.info(f'Adding -auto-approve flag to {request.command} command')
|
|
127
|
+
cmd.append('-auto-approve')
|
|
128
|
+
|
|
129
|
+
# Add variables only for commands that accept them (plan, apply, destroy)
|
|
130
|
+
if request.command in ['plan', 'apply', 'destroy'] and request.variables:
|
|
131
|
+
logger.info(f'Adding {len(request.variables)} variables to {request.command} command')
|
|
132
|
+
for key, value in request.variables.items():
|
|
133
|
+
cmd.append(f'-var={key}={value}')
|
|
134
|
+
|
|
135
|
+
# Execute command
|
|
136
|
+
try:
|
|
137
|
+
process = subprocess.run(
|
|
138
|
+
cmd, cwd=request.working_directory, capture_output=True, text=True, env=env
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
# Prepare the result
|
|
142
|
+
stdout = process.stdout
|
|
143
|
+
stderr = process.stderr if process.stderr else ''
|
|
144
|
+
|
|
145
|
+
# Clean output text if requested
|
|
146
|
+
if request.strip_ansi:
|
|
147
|
+
logger.debug('Cleaning command output text (ANSI codes and control characters)')
|
|
148
|
+
stdout = clean_output_text(stdout)
|
|
149
|
+
stderr = clean_output_text(stderr)
|
|
150
|
+
|
|
151
|
+
result = {
|
|
152
|
+
'command': f'terraform {request.command}',
|
|
153
|
+
'status': 'success' if process.returncode == 0 else 'error',
|
|
154
|
+
'return_code': process.returncode,
|
|
155
|
+
'stdout': stdout,
|
|
156
|
+
'stderr': stderr,
|
|
157
|
+
'working_directory': request.working_directory,
|
|
158
|
+
'outputs': None,
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
# Get outputs if this was a successful apply command
|
|
162
|
+
if request.command == 'apply' and process.returncode == 0:
|
|
163
|
+
try:
|
|
164
|
+
logger.info('Getting Terraform outputs')
|
|
165
|
+
output_process = subprocess.run(
|
|
166
|
+
['terraform', 'output', '-json'],
|
|
167
|
+
cwd=request.working_directory,
|
|
168
|
+
capture_output=True,
|
|
169
|
+
text=True,
|
|
170
|
+
env=env,
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
if output_process.returncode == 0 and output_process.stdout:
|
|
174
|
+
# Get output and clean it if needed
|
|
175
|
+
output_stdout = output_process.stdout
|
|
176
|
+
if request.strip_ansi:
|
|
177
|
+
output_stdout = clean_output_text(output_stdout)
|
|
178
|
+
|
|
179
|
+
# Parse the JSON output
|
|
180
|
+
raw_outputs = json.loads(output_stdout)
|
|
181
|
+
|
|
182
|
+
# Process outputs to extract values from complex structure
|
|
183
|
+
processed_outputs = {}
|
|
184
|
+
for key, value in raw_outputs.items():
|
|
185
|
+
# Terraform outputs in JSON format have a nested structure
|
|
186
|
+
# with 'value', 'type', and sometimes 'sensitive'
|
|
187
|
+
if isinstance(value, dict) and 'value' in value:
|
|
188
|
+
processed_outputs[key] = value['value']
|
|
189
|
+
else:
|
|
190
|
+
processed_outputs[key] = value
|
|
191
|
+
|
|
192
|
+
result['outputs'] = processed_outputs
|
|
193
|
+
logger.info(f'Extracted {len(processed_outputs)} Terraform outputs')
|
|
194
|
+
except Exception as e:
|
|
195
|
+
logger.warning(f'Failed to get Terraform outputs: {e}')
|
|
196
|
+
|
|
197
|
+
# Return the output
|
|
198
|
+
return TerraformExecutionResult(**result)
|
|
199
|
+
except Exception as e:
|
|
200
|
+
return TerraformExecutionResult(
|
|
201
|
+
command=f'terraform {request.command}',
|
|
202
|
+
status='error',
|
|
203
|
+
error_message=str(e),
|
|
204
|
+
working_directory=request.working_directory,
|
|
205
|
+
outputs=None,
|
|
206
|
+
)
|