Close Menu
    DevStackTipsDevStackTips
    • Home
    • News & Updates
      1. Tech & Work
      2. View All

      Coded Smorgasbord: High Strung

      September 26, 2025

      Chainguard launches trusted collection of verified JavaScript libraries

      September 26, 2025

      CData launches Connect AI to provide agents access to enterprise data sources

      September 26, 2025

      PostgreSQL 18 adds asynchronous I/O to improve performance

      September 26, 2025

      Distribution Release: Neptune 9.0

      September 25, 2025

      Distribution Release: Kali Linux 2025.3

      September 23, 2025

      Distribution Release: SysLinuxOS 13

      September 23, 2025

      Development Release: MX Linux 25 Beta 1

      September 22, 2025
    • Development
      1. Algorithms & Data Structures
      2. Artificial Intelligence
      3. Back-End Development
      4. Databases
      5. Front-End Development
      6. Libraries & Frameworks
      7. Machine Learning
      8. Security
      9. Software Engineering
      10. Tools & IDEs
      11. Web Design
      12. Web Development
      13. Web Security
      14. Programming Languages
        • PHP
        • JavaScript
      Featured

      PHP 8.5.0 RC 1 available for testing

      September 26, 2025
      Recent

      PHP 8.5.0 RC 1 available for testing

      September 26, 2025

      Terraform Code Generator Using Ollama and CodeGemma

      September 26, 2025

      Beyond Denial: How AI Concierge Services Can Transform Healthcare from Reactive to Proactive

      September 25, 2025
    • Operating Systems
      1. Windows
      2. Linux
      3. macOS
      Featured

      Distribution Release: Neptune 9.0

      September 25, 2025
      Recent

      Distribution Release: Neptune 9.0

      September 25, 2025

      FOSS Weekly #25.39: Kill Switch Phones, LMDE 7, Zorin OS 18 Beta, Polybar, Apt History and More Linux Stuff

      September 25, 2025

      Distribution Release: Kali Linux 2025.3

      September 23, 2025
    • Learning Resources
      • Books
      • Cheatsheets
      • Tutorials & Guides
    Home»Development»Terraform Code Generator Using Ollama and CodeGemma

    Terraform Code Generator Using Ollama and CodeGemma

    September 26, 2025

    In modern cloud infrastructure development, writing Terraform code manually can be time-consuming and error-prone—especially for teams that frequently deploy modular and scalable environments. There’s a growing need for tools that:

    • Allow natural language input to describe infrastructure requirements.
    • Automatically generate clean, modular Terraform code.
    • Integrate with cloud authentication mechanisms.
    • Save and organize code into execution-ready files.

    This model bridges the gap between human-readable Infrastructure descriptions and machine-executable Terraform scripts, making infrastructure-as-code more accessible and efficient. To build this model, we utilize CodeGemma, a lightweight AI model optimized for coding tasks, which runs locally via Ollama.

    Qadkyxzvpwpsnkuajbujylwozlw36aeyw Mos4qgcxocvikd9fqwlwi18nu1eejv9khrb52r Ak3lastherfdzlfuhwfzzf4kelmucdplzzkdezh90a

    In this blog, we explore how to build a Terraform code generator web app using:

    • Flask for the web interface
    • Ollama’s CodeGemma model for AI-powered code generation
    • Azure CLI authentication using service principal credentials
    • Modular Terraform file creation based on user queries

    This tool empowers developers to describe infrastructure needs in natural language and receive clean, modular Terraform code ready for deployment.

    Technologies Used

    CodeGemma

    CodeGemma is a family of lightweight, open-source models optimized for coding tasks. It supports code generation from natural language.

    Running CodeGemma locally via Ollama means:

    • No cloud dependency: You don’t need to send data to external APIs.
    • Faster response times: Ideal for iterative development.
    • Privacy and control: Your infrastructure queries and generated code stay on your machine.
    • Offline capability: Ideal for use in restricted or secure environments.
    • Zero cost: Since the model runs locally, there’s no usage fee or subscription required—unlike cloud-based AI services.

    Flask

    We chose Flask as the web framework for this project because of its:

    • Simplicity and flexibility: Flask is a lightweight and easy-to-set-up framework, making it ideal for quick prototyping.

    Initial Setup

    • Install Python.
    winget install Python.Python.3
    • Install Visual Studio.
    • Install Download Ollama on Windows.
    • Pull and run the codegemma:7b.
    ollama pull codegemma:7b
    ollama run codegemma:7b
    
    • Install the Ollama Python library to use Gemma 3 in your Python projects.
    pip install ollama

    Folder Structure

    Folder Structure

     

    Code

    from flask import Flask, jsonify, request, render_template_string
    from ollama import generate
    import subprocess
    import re
    import os
    
    app = Flask(__name__)
    # Azure credentials
    CLIENT_ID = "Enter your credentials here."
    CLIENT_SECRET = "Enter your credentials here."
    TENANT_ID = "Enter your credentials here."
    
    auth_status = {"status": "not_authenticated", "details": ""}
    input_fields_html = ""
    def authenticate_with_azure():
        try:
            result = subprocess.run(
                ["cmd.exe", "/c", "C:\Program Files\Microsoft SDKs\Azure\CLI2\wbin\az.cmd",
                 "login", "--service-principal", "-u", CLIENT_ID, "-p", CLIENT_SECRET, "--tenant", TENANT_ID],
                capture_output=True, text=True, check=True
            )
            auth_status["status"] = "success"
            auth_status["details"] = result.stdout
        except subprocess.CalledProcessError as e:
            auth_status["status"] = "failed"
            auth_status["details"] = e.stderr
        except Exception as ex:
            auth_status["status"] = "terminated"
            auth_status["details"] = str(ex)
    
    @app.route('/', methods=['GET', 'POST'])
    def home():
        terraform_code = ""
        user_query = ""
        input_fields_html = ""
    
        if request.method == 'POST':
            user_query = request.form.get('query', '')
    
            base_prompt = (
                "Generate modular Terraform code using best practices. "
                "Create separate files for main.tf, vm.tf, vars.tf, terraform.tfvars, subnet.tf, kubernetes_cluster etc. "
                "Ensure the code is clean and execution-ready. "
                "Use markdown headers like ## Main.tf: followed by code blocks."
            )
    
            full_prompt = base_prompt + "n" + user_query
            try:
                response_cleaned = generate(model='codegemma:7b', prompt=full_prompt)
                terraform_code = response_cleaned.get('response', '').strip()
            except Exception as e:
                terraform_code = f"# Error generating code: {str(e)}"
    
                provider_block = f"""
                  provider "azurerm" {{
                  features {{}}
                  subscription_id = "Enter your credentials here."
                  client_id       = "{CLIENT_ID}"
                  client_secret   = "{CLIENT_SECRET}"
                  tenant_id       = "{TENANT_ID}"
                }}"""
                terraform_code = provider_block + "nn" + terraform_code
    
            with open('main.tf', 'w', encoding='utf-8') as f:
                f.write(terraform_code)
    
    
            # Create output directory
            output_dir = r"C:Usersriya.achkarpohreDesktopAItest7terraform_output"
            os.makedirs(output_dir, exist_ok=True)
    
            # Define output paths
            paths = {
                "main.tf": os.path.join(output_dir, "Main.tf"),
                "vm.tf": os.path.join(output_dir, "VM.tf"),
                "subnet.tf": os.path.join(output_dir, "Subnet.tf"),
                "vpc.tf": os.path.join(output_dir, "VPC.tf"),
                "vars.tf": os.path.join(output_dir, "Vars.tf"),
                "terraform.tfvars": os.path.join(output_dir, "Terraform.tfvars"),
                "kubernetes_cluster.tf": os.path.join(output_dir, "kubernetes_cluster.tf")
            }
    
            # Split response using markdown headers
            sections = re.split(r'##s*(.*?).tf:s*n+```(?:terraform)?n', terraform_code)
    
            # sections = ['', 'Main', '<code>', 'VM', '<code>', ...]
            for i in range(1, len(sections), 2):
                filename = sections[i].strip().lower() + '.tf'
                code_block = sections[i + 1].strip()
    
                # Remove closing backticks if present
                code_block = re.sub(r'```$', '', code_block)
    
                # Save to file if path is defined
                if filename in paths:
                    with open(paths[filename], 'w', encoding='utf-8') as f:
                        f.write(code_block)
                        print(f"n--- Written: {filename} ---")
                        print(code_block)
                else:
                    print(f"n--- Skipped unknown file: {filename} ---")
    
            return render_template_string(f"""
            <html>
            <head><title>Terraform Generator</title></head>
            <body>
                <form method="post">
                    <center>
                        <label>Enter your query:</label><br>
                        <textarea name="query" rows="6" cols="80" placeholder="Describe your infrastructure requirement here..."></textarea><br><br>
                        <input type="submit" value="Generate Terraform">
                    </center>
                </form>
                <hr>
                <h2>Generated Terraform Code:</h2>
                <pre>{terraform_code}</pre>
                <h2>Enter values for the required variables:</h2>
                <h2>Authentication Status:</h2>
                <pre>Status: {auth_status['status']}n{auth_status['details']}</pre>
            </body>
            </html>
            """)
    
        # Initial GET request
        return render_template_string('''
        <html>
        <head><title>Terraform Generator</title></head>
        <body>
            <form method="post">
                <center>
                    <label>Enter your query:</label><br>
                    <textarea name="query" rows="6" cols="80" placeholder="Describe your infrastructure requirement here..."></textarea><br><br>
                    <input type="submit" value="Generate Terraform">
                </center>
            </form>
        </body>
        </html>
        ''')
    
    authenticate_with_azure()
    @app.route('/authenticate', methods=['POST'])
    def authenticate():
        authenticate_with_azure()
        return jsonify(auth_status)
    
    if __name__ == '__main__':
        app.run(debug=True)
    

    Open Visual Studio, create a new file named file.py, and paste the code into it. Then, open the terminal and run the script by typing:

    python file.py
    

    Flask Development Server

    Out1

    Code Structure Explanation

    • Azure Authentication
      • The app uses the Azure CLI (az.cmd) via Python’s subprocess.run() to authenticate with Azure using a service principal. This ensures secure access to Azure resources before generating Terraform code.
    • User Query Handling
      • When a user submits a query through the web form, it is captured using:
    user_query = request.form.get('query', '')
    • Prompt Construction
      • The query is appended to a base prompt that instructs CodeGemma to generate modular Terraform code using best practices. This prompt includes instructions to split the code into files, such as main.tf, vm.tf, subnet.tf, etc.
    • Code Generation via CodeGemma
      • The prompt is sent to the CodeGemma:7b model using:
    response_cleaned = generate(model='codegemma:7b', prompt=full_prompt)
    • Saving the Full Response
      • The entire generated Terraform code is first saved to a main.tf file as a backup.
    • Output Directory Setup
      • A specific output directory is created using os.makedirs() to store the split .tf files:
    output_dir = r"C:Usersriya.achkarpohreDesktopAItest7terraform_output"
    • File Path Mapping
      • A dictionary maps expected filenames (such as main.tf and vm.tf) to their respective output paths. This ensures each section of the generated code is saved correctly.
    • Code Splitting Logic
      • The response is split using a regex-based approach, based on markdown headers like ## main.tf: followed by Terraform code blocks. This helps isolate each module.
    • Conditional File Writing
      • For each split section, the code checks if the filename exists in the predefined path dictionary:
        • If defined, the code block is written to the corresponding file.
        • If not defined, the section is skipped and logged as  “unknown file”.
    • Web Output Rendering
      • The generated code and authentication status are displayed on the webpage using render_template_string().

    Terminal

    Term1

    The Power of AI in Infrastructure Automation

    This project demonstrates how combining AI models, such as CodeGemma, with simple tools like Flask and Terraform can revolutionize the way we approach cloud infrastructure provisioning. By allowing developers to describe their infrastructure in natural language and instantly receive clean, modular Terraform code, we eliminate the need for repetitive manual scripting and reduce the chances of human error.

    Running CodeGemma locally via Ollama ensures:

    • Full control over data
    • Zero cost for code generation
    • Fast and private execution
    • Seamless integration with existing workflows

    The use of Azure CLI authentication adds a layer of real-world applicability, making the generated code deployable in enterprise environments.

    Whether you’re a cloud engineer, DevOps practitioner, or technical consultant, this tool empowers you to move faster, prototype smarter, and deploy infrastructure with confidence.

    As AI continues to evolve, tools like this will become essential in bridging the gap between human intent and machine execution, making infrastructure-as-code not only powerful but also intuitive.

    Source: Read More 

    Facebook Twitter Reddit Email Copy Link
    Previous ArticleCoded Smorgasbord: High Strung
    Next Article PHP 8.5.0 RC 1 available for testing

    Related Posts

    Development

    PHP 8.5.0 RC 1 available for testing

    September 26, 2025
    Development

    Beyond Denial: How AI Concierge Services Can Transform Healthcare from Reactive to Proactive

    September 25, 2025
    Leave A Reply Cancel Reply

    For security, use of Google's reCAPTCHA service is required which is subject to the Google Privacy Policy and Terms of Use.

    Continue Reading

    Comprendere il Riavvio dello Spazio Utente nei Sistemi GNU/Linux

    Linux

    How JavaScript Lint Rules Work (and Why Abstract Syntax Trees Matter)

    Development

    Leadership lessons from growing 3x in 1 year

    Learning Resources

    CVE-2025-4034 – Projectworlds Online Examination System SQL Injection Vulnerability

    Common Vulnerabilities and Exposures (CVEs)

    Highlights

    That post-grad software job might be harder to get, thanks to AI

    August 27, 2025

    New research shows the AI revolution is impacting younger workers more than older ones -…

    CVE-2025-31249 – Apple macOS Sequoia Logic Flaw Allows Sensitive Data Exposure

    May 12, 2025

    CVE-2012-10025 – “WordPress Advanced Custom Fields RFI Remote Code Execution”

    August 5, 2025

    How to Add Live Chat to Your Applications with Rocket.chat

    April 7, 2025
    © DevStackTips 2025. All rights reserved.
    • Contact
    • Privacy Policy

    Type above and press Enter to search. Press Esc to cancel.