Spaces:
Runtime error
Runtime error
Nathan Slaughter
commited on
Commit
Β·
e5d1a79
1
Parent(s):
e0ab403
terraform generator
Browse files- README.md +5 -6
- app.py +133 -0
- requirements.txt +3 -0
README.md
CHANGED
@@ -1,14 +1,13 @@
|
|
1 |
---
|
2 |
-
title:
|
3 |
-
emoji:
|
4 |
-
colorFrom:
|
5 |
-
colorTo:
|
6 |
sdk: gradio
|
7 |
sdk_version: 4.44.0
|
8 |
app_file: app.py
|
9 |
pinned: false
|
10 |
-
|
11 |
-
short_description: Demo Terraform module generator
|
12 |
---
|
13 |
|
14 |
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
1 |
---
|
2 |
+
title: Terraform Generator
|
3 |
+
emoji: π¨
|
4 |
+
colorFrom: red
|
5 |
+
colorTo: gray
|
6 |
sdk: gradio
|
7 |
sdk_version: 4.44.0
|
8 |
app_file: app.py
|
9 |
pinned: false
|
10 |
+
short_description: A terraform generating app
|
|
|
11 |
---
|
12 |
|
13 |
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
app.py
ADDED
@@ -0,0 +1,133 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from typing import Optional, Tuple
|
2 |
+
from os import getenv
|
3 |
+
|
4 |
+
import gradio as gr
|
5 |
+
|
6 |
+
from pydantic import BaseModel, Field
|
7 |
+
from langchain_openai import ChatOpenAI
|
8 |
+
|
9 |
+
def get_openai_key(api_key: Optional[str]) -> str:
|
10 |
+
"""Use the supplied API key or fallback to the environment variable."""
|
11 |
+
if not api_key:
|
12 |
+
api_key = getenv("OPENAI_API_KEY")
|
13 |
+
if not api_key:
|
14 |
+
raise ValueError("OpenAI API key is required.")
|
15 |
+
return api_key
|
16 |
+
|
17 |
+
# Define the schema for the Terraform configurations
|
18 |
+
class Terraform(BaseModel):
|
19 |
+
"""
|
20 |
+
A Terraform module with a list of resources, provider, and configuration files.
|
21 |
+
"""
|
22 |
+
readme: str = Field(..., description="A readme for the module.")
|
23 |
+
main_tf: str = Field(..., description="The main Terraform configuration file.")
|
24 |
+
variables_tf: str = Field(..., description="The Terraform variables configuration file.")
|
25 |
+
outputs_tf: str = Field(..., description="The Terraform outputs configuration file.")
|
26 |
+
|
27 |
+
def generate(resources: str, provider: str, model: str, api_key: str = "") -> Tuple[str, str, str]:
|
28 |
+
try:
|
29 |
+
llm = ChatOpenAI(model=model, temperature=0.7, max_tokens=4096)
|
30 |
+
structured_llm = llm.with_structured_output(Terraform)
|
31 |
+
response = structured_llm.invoke(f"""You are an expert SRE assistant specialized in Terraform.
|
32 |
+
|
33 |
+
Generate a Terraform configuration for the following resources:
|
34 |
+
{resources} using the {provider} provider.
|
35 |
+
|
36 |
+
You always remember all of the necessary permissions and roles to configure for connecting the resources.
|
37 |
+
""")
|
38 |
+
return response.main_tf, response.variables_tf, response.outputs_tf
|
39 |
+
except Exception as e:
|
40 |
+
raise ValueError(f"Failed to generate Terraform configuration: {e}")
|
41 |
+
|
42 |
+
# Define the Gradio interface
|
43 |
+
def create_interface():
|
44 |
+
"""Interface for the Terraform Module Generator."""
|
45 |
+
with gr.Blocks() as demo:
|
46 |
+
# Title
|
47 |
+
gr.Markdown("## π Terraform Module Generator")
|
48 |
+
|
49 |
+
# Instructional Markdown Box
|
50 |
+
gr.Markdown("""
|
51 |
+
**Welcome to the Terraform Module Generator!**
|
52 |
+
|
53 |
+
This app assists you in generating Terraform configuration files based on your cloud provider and a natural language description of how your module should work.
|
54 |
+
|
55 |
+
**How to Use:**
|
56 |
+
1. **π OpenAI API Key**: Enter your OpenAI API key to authenticate.
|
57 |
+
2. **π¦ Module Description**: Describe the key resources and how they work together.
|
58 |
+
3. **π Provider**: Select your cloud provider from the dropdown.
|
59 |
+
4. **π€ Language Model**: Choose the OpenAI model to use for generation.
|
60 |
+
5. Click the **Generate Terraform Configuration** button to create your `.tf` files.
|
61 |
+
|
62 |
+
The generated configurations will be displayed in separate tabs for easy access. There's a copy button in the upper right.
|
63 |
+
""")
|
64 |
+
with gr.Row():
|
65 |
+
with gr.Column(scale=2):
|
66 |
+
api_key = gr.Textbox(
|
67 |
+
label="π OpenAI API Key",
|
68 |
+
type="password",
|
69 |
+
placeholder="Enter your OpenAI API key",
|
70 |
+
)
|
71 |
+
with gr.Column(scale=1):
|
72 |
+
model = gr.Dropdown(
|
73 |
+
label="π€ Language Model",
|
74 |
+
choices=["gpt-4o", "gpt-4o-mini"],
|
75 |
+
value="gpt-4o-mini", # Default selection
|
76 |
+
type="value",
|
77 |
+
)
|
78 |
+
|
79 |
+
with gr.Row():
|
80 |
+
resources = gr.Textbox(
|
81 |
+
label="π¦ Module Description",
|
82 |
+
placeholder="Describe the resources and how they work together.",
|
83 |
+
lines=5,
|
84 |
+
scale=2,
|
85 |
+
)
|
86 |
+
provider = gr.Dropdown(
|
87 |
+
label="β Cloud Provider",
|
88 |
+
choices=["aws", "azure", "google"],
|
89 |
+
value="aws",
|
90 |
+
type="value",
|
91 |
+
scale=1,
|
92 |
+
)
|
93 |
+
|
94 |
+
with gr.Row():
|
95 |
+
generate_btn = gr.Button("βοΈ Generate Terraform Configuration")
|
96 |
+
|
97 |
+
with gr.Tab("π main.tf"):
|
98 |
+
main_tf_output = gr.Textbox(
|
99 |
+
label="π main.tf",
|
100 |
+
lines=20,
|
101 |
+
show_copy_button=True,
|
102 |
+
interactive=False
|
103 |
+
)
|
104 |
+
|
105 |
+
with gr.Tab("π§ variables.tf"):
|
106 |
+
variables_tf_output = gr.Textbox(
|
107 |
+
label="π§ variables.tf",
|
108 |
+
lines=20,
|
109 |
+
show_copy_button=True,
|
110 |
+
interactive=False
|
111 |
+
)
|
112 |
+
|
113 |
+
with gr.Tab("π€ outputs.tf"):
|
114 |
+
outputs_tf_output = gr.Textbox(
|
115 |
+
label="π€ outputs.tf",
|
116 |
+
lines=20,
|
117 |
+
show_copy_button=True,
|
118 |
+
interactive=False
|
119 |
+
)
|
120 |
+
|
121 |
+
# Define the button click event
|
122 |
+
generate_btn.click(
|
123 |
+
fn=generate,
|
124 |
+
inputs=[resources, provider, model, api_key],
|
125 |
+
outputs=[main_tf_output, variables_tf_output, outputs_tf_output]
|
126 |
+
)
|
127 |
+
|
128 |
+
return demo
|
129 |
+
|
130 |
+
# Launch the interface
|
131 |
+
if __name__ == "__main__":
|
132 |
+
demo = create_interface()
|
133 |
+
demo.launch()
|
requirements.txt
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
langchain-openai
|
2 |
+
pydantic
|
3 |
+
gradio
|