Skip to main content
Glama

azure_container_apps_deploy

Deploy container applications to Azure Container Apps for managing DevOps workflows and cloud deployments.

Instructions

Deploy container to Azure Container Apps

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • Primary handler function implementing the tool logic: creates Container Apps environment if needed, deploys the image via az CLI, handles ACR images, retrieves and returns the app FQDN URL.
        let output = "";
        const envName = environment || `${app_name}-env`;
    
        // Check if environment exists, create if not
        const envCheck = await runCommand(`az containerapp env show -n ${envName} -g ${resource_group} 2>/dev/null`);
        if (!envCheck.success) {
          output += `Creating Container Apps environment: ${envName}...\n`;
          const envCreate = await runCommand(
            `az containerapp env create -n ${envName} -g ${resource_group}`,
            { timeout: 300000 }
          );
          if (!envCreate.success) {
            return {
              content: [{
                type: "text",
                text: `Failed to create environment!\n\nError: ${envCreate.stderr || envCreate.error}`
              }]
            };
          }
          output += `Environment created.\n\n`;
        }
    
        // Deploy container app
        output += `Deploying container app: ${app_name}...\n`;
    
        // Determine if this is an ACR image
        const isAcr = image.includes(".azurecr.io");
        let registryArgs = "";
        if (isAcr) {
          const acrName = image.split(".")[0];
          registryArgs = `--registry-server ${acrName}.azurecr.io`;
        }
    
        const deployCmd = `az containerapp create \\
          -n ${app_name} \\
          -g ${resource_group} \\
          --environment ${envName} \\
          --image ${image} \\
          --target-port ${port} \\
          --ingress external \\
          --cpu ${cpu} \\
          --memory ${memory} \\
          ${registryArgs}`;
    
        const deploy = await runCommand(deployCmd.replace(/\\\n/g, " "), { timeout: 300000 });
    
        if (!deploy.success) {
          return {
            content: [{
              type: "text",
              text: `Failed to deploy!\n\nError: ${deploy.stderr || deploy.error}\n\nCommand:\n${deployCmd}\n\nCommon issues:\n- Image not found in registry\n- Registry authentication failed\n- Resource quota exceeded`
            }]
          };
        }
    
        // Get the app URL
        const appUrl = await runCommand(`az containerapp show -n ${app_name} -g ${resource_group} --query properties.configuration.ingress.fqdn -o tsv`);
    
        output += `
    Deployment successful!
    
    APP DETAILS:
    ------------
    Name: ${app_name}
    Resource Group: ${resource_group}
    Image: ${image}
    URL: https://${appUrl.stdout}
    
    USEFUL COMMANDS:
    ----------------
    # View logs
    az containerapp logs show -n ${app_name} -g ${resource_group} --follow
    
    # Scale replicas
    az containerapp update -n ${app_name} -g ${resource_group} --min-replicas 1 --max-replicas 10
    
    # Update image
    az containerapp update -n ${app_name} -g ${resource_group} --image ${image}
    
    # View revisions
    az containerapp revision list -n ${app_name} -g ${resource_group} -o table
    
    ENVIRONMENT VARIABLES:
    ----------------------
    az containerapp update -n ${app_name} -g ${resource_group} \\
      --set-env-vars "KEY=value" "DATABASE_URL=secretref:db-url"
    
    SECRETS:
    --------
    az containerapp secret set -n ${app_name} -g ${resource_group} \\
      --secrets "db-url=your-connection-string"`;
    
        return { content: [{ type: "text", text: output }] };
      }
  • Input schema defining parameters for the azure_container_apps_deploy tool with types, descriptions, and defaults.
      app_name: { type: "string", description: "Container app name" },
      resource_group: { type: "string", description: "Resource group name" },
      image: { type: "string", description: "Container image (e.g., myacr.azurecr.io/app:latest)" },
      environment: { type: "string", description: "Container Apps environment name", default: "" },
      port: { type: "number", description: "Container port", default: 8080 },
      cpu: { type: "string", description: "CPU cores (0.25, 0.5, 1, 2)", default: "0.5" },
      memory: { type: "string", description: "Memory (0.5Gi, 1Gi, 2Gi, 4Gi)", default: "1Gi" }
    },
    async ({ app_name, resource_group, image, environment, port, cpu, memory }) => {
  • src/index.js:1280-1386 (registration)
    MCP server.tool registration call that registers the tool with name, description, schema, and handler function.
      "azure_container_apps_deploy",
      "Deploy container to Azure Container Apps",
      {
        app_name: { type: "string", description: "Container app name" },
        resource_group: { type: "string", description: "Resource group name" },
        image: { type: "string", description: "Container image (e.g., myacr.azurecr.io/app:latest)" },
        environment: { type: "string", description: "Container Apps environment name", default: "" },
        port: { type: "number", description: "Container port", default: 8080 },
        cpu: { type: "string", description: "CPU cores (0.25, 0.5, 1, 2)", default: "0.5" },
        memory: { type: "string", description: "Memory (0.5Gi, 1Gi, 2Gi, 4Gi)", default: "1Gi" }
      },
      async ({ app_name, resource_group, image, environment, port, cpu, memory }) => {
        let output = "";
        const envName = environment || `${app_name}-env`;
    
        // Check if environment exists, create if not
        const envCheck = await runCommand(`az containerapp env show -n ${envName} -g ${resource_group} 2>/dev/null`);
        if (!envCheck.success) {
          output += `Creating Container Apps environment: ${envName}...\n`;
          const envCreate = await runCommand(
            `az containerapp env create -n ${envName} -g ${resource_group}`,
            { timeout: 300000 }
          );
          if (!envCreate.success) {
            return {
              content: [{
                type: "text",
                text: `Failed to create environment!\n\nError: ${envCreate.stderr || envCreate.error}`
              }]
            };
          }
          output += `Environment created.\n\n`;
        }
    
        // Deploy container app
        output += `Deploying container app: ${app_name}...\n`;
    
        // Determine if this is an ACR image
        const isAcr = image.includes(".azurecr.io");
        let registryArgs = "";
        if (isAcr) {
          const acrName = image.split(".")[0];
          registryArgs = `--registry-server ${acrName}.azurecr.io`;
        }
    
        const deployCmd = `az containerapp create \\
          -n ${app_name} \\
          -g ${resource_group} \\
          --environment ${envName} \\
          --image ${image} \\
          --target-port ${port} \\
          --ingress external \\
          --cpu ${cpu} \\
          --memory ${memory} \\
          ${registryArgs}`;
    
        const deploy = await runCommand(deployCmd.replace(/\\\n/g, " "), { timeout: 300000 });
    
        if (!deploy.success) {
          return {
            content: [{
              type: "text",
              text: `Failed to deploy!\n\nError: ${deploy.stderr || deploy.error}\n\nCommand:\n${deployCmd}\n\nCommon issues:\n- Image not found in registry\n- Registry authentication failed\n- Resource quota exceeded`
            }]
          };
        }
    
        // Get the app URL
        const appUrl = await runCommand(`az containerapp show -n ${app_name} -g ${resource_group} --query properties.configuration.ingress.fqdn -o tsv`);
    
        output += `
    Deployment successful!
    
    APP DETAILS:
    ------------
    Name: ${app_name}
    Resource Group: ${resource_group}
    Image: ${image}
    URL: https://${appUrl.stdout}
    
    USEFUL COMMANDS:
    ----------------
    # View logs
    az containerapp logs show -n ${app_name} -g ${resource_group} --follow
    
    # Scale replicas
    az containerapp update -n ${app_name} -g ${resource_group} --min-replicas 1 --max-replicas 10
    
    # Update image
    az containerapp update -n ${app_name} -g ${resource_group} --image ${image}
    
    # View revisions
    az containerapp revision list -n ${app_name} -g ${resource_group} -o table
    
    ENVIRONMENT VARIABLES:
    ----------------------
    az containerapp update -n ${app_name} -g ${resource_group} \\
      --set-env-vars "KEY=value" "DATABASE_URL=secretref:db-url"
    
    SECRETS:
    --------
    az containerapp secret set -n ${app_name} -g ${resource_group} \\
      --secrets "db-url=your-connection-string"`;
    
        return { content: [{ type: "text", text: output }] };
      }
    );
  • Testing/exported version of the handler function (identical logic), exported for unit testing purposes.
    export async function azureContainerAppsDeploy({ app_name, resource_group, image, environment, port, cpu, memory }) {
      const envName = environment || `${app_name}-env`;
      let output = "";
    
      const envCheck = await commandRunner(`az containerapp env show -n ${envName} -g ${resource_group} 2>/dev/null`);
      if (!envCheck.success) {
        output += `Creating Container Apps environment: ${envName}...\n`;
        const envCreate = await commandRunner(
          `az containerapp env create -n ${envName} -g ${resource_group}`,
          { timeout: 300000 }
        );
        if (!envCreate.success) {
          return {
            content: [{
              type: "text",
              text: `Failed to create environment!\n\nError: ${envCreate.stderr || envCreate.error}`
            }]
          };
        }
        output += `Environment created.\n\n`;
      }
    
      output += `Deploying container app: ${app_name}...\n`;
    
      const isAcr = image.includes(".azurecr.io");
      let registryArgs = "";
      if (isAcr) {
        const acrName = image.split(".")[0];
        registryArgs = `--registry-server ${acrName}.azurecr.io`;
      }
    
      const deployCmd = `az containerapp create -n ${app_name} -g ${resource_group} --environment ${envName} --image ${image} --target-port ${port} --ingress external --cpu ${cpu} --memory ${memory} ${registryArgs}`;
    
      const deploy = await commandRunner(deployCmd, { timeout: 300000 });
    
      if (!deploy.success) {
        return {
          content: [{
            type: "text",
            text: `Failed to deploy!\n\nError: ${deploy.stderr || deploy.error}`
          }]
        };
      }
    
      const appUrl = await commandRunner(`az containerapp show -n ${app_name} -g ${resource_group} --query properties.configuration.ingress.fqdn -o tsv`);
    
      output += `\nDeployment successful!\n\nApp: ${app_name}\nURL: https://${appUrl.stdout}`;
    
      return { content: [{ type: "text", text: output }] };
    }
  • src/tools.js:576-597 (registration)
    Exported tools object including azureContainerAppsDeploy for testing/import in other contexts.
    export const tools = {
      // Git
      gitStatusExplained,
      gitBranchExplained,
      gitCommitGuided,
      // Docker
      dockerCheckSetup,
      dockerAnalyzeProject,
      dockerBuild,
      // GitHub
      githubSecretsList,
      githubSecretsSet,
      // Azure
      azureCheckCli,
      azureAcrSetup,
      azureContainerAppsDeploy,
      // SonarCloud
      sonarcloudSetupGuide,
      sonarcloudCreateConfig,
      // Onboarding
      devOnboardingCheck,
    };
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full burden but only states the action without disclosing behavioral traits. It does not cover permissions needed, whether it's destructive, rate limits, or what the deployment entails (e.g., overwrites existing apps). This leaves significant gaps in understanding the tool's behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, clear sentence with no wasted words. It is front-loaded and efficiently conveys the core action, making it highly concise and well-structured for its simplicity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity of a deployment tool with no annotations, no output schema, and 0 parameters, the description is incomplete. It lacks details on what the tool does beyond the basic verb, such as expected inputs, outcomes, or error handling, making it inadequate for informed use.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 0 parameters with 100% coverage, so no parameter documentation is needed. The description does not add param info, which is acceptable here, but it could hint at implicit inputs (e.g., container image source), keeping it from a perfect score.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states the action ('Deploy') and target resource ('container to Azure Container Apps'), which provides a basic purpose. However, it lacks specificity about what exactly gets deployed (e.g., from where, with what configuration) and does not differentiate from sibling tools like 'docker_build' or 'azure_create_workflow', making it vague in context.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus alternatives. It does not mention prerequisites, context (e.g., after building a container), or exclusions, leaving the agent without direction on its appropriate application among the many sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/rideRTD/RTD-DevOps'

If you have feedback or need assistance with the MCP directory API, please join our Discord server