Skip to content

Commit d7dd7a8

Browse files
author
naman-msft
committed
updated doc and tool
1 parent 14f103b commit d7dd7a8

File tree

11 files changed

+2487
-364
lines changed

11 files changed

+2487
-364
lines changed
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
---
2+
title: 'Quickstart: Create a Linux VM and SSH into it'
3+
description: Learn how to create a Linux virtual machine in Azure using Azure CLI and then SSH into it.
4+
ms.topic: quickstart
5+
ms.date: 10/12/2023
6+
author: yourgithubusername
7+
ms.author: yourgithubusername
8+
ms.custom: innovation-engine, azurecli, linux-related-content
9+
---
10+
11+
# Quickstart: Create a Linux VM and SSH into it
12+
13+
This Exec Doc demonstrates how to create a resource group, deploy a Linux VM using a supported Ubuntu image, retrieve its public IP address, and then SSH into the VM. The process uses environment variables to manage configuration details and appends a random suffix to resource names to ensure uniqueness.
14+
15+
The following sections walk through each step with code blocks. Remember that you must already be logged in to Azure and have your subscription set.
16+
17+
## Step 1: Create a Resource Group
18+
19+
In this section, we declare environment variables necessary for the deployment and create a resource group in the "centralindia" region. A random suffix is appended to the resource group name to guarantee uniqueness.
20+
21+
```bash
22+
export RANDOM_SUFFIX=$(openssl rand -hex 3)
23+
export REGION="centralindia"
24+
export RG_NAME="LinuxRG$RANDOM_SUFFIX"
25+
az group create --name $RG_NAME --location $REGION
26+
```
27+
28+
Results:
29+
30+
<!-- expected_similarity=0.3 -->
31+
```JSON
32+
{
33+
"id": "/subscriptions/xxxxx/resourceGroups/LinuxRGabc123",
34+
"location": "centralindia",
35+
"managedBy": null,
36+
"name": "LinuxRGabc123",
37+
"properties": {
38+
"provisioningState": "Succeeded"
39+
},
40+
"tags": null,
41+
"type": "Microsoft.Resources/resourceGroups"
42+
}
43+
```
44+
45+
## Step 2: Create a Linux Virtual Machine
46+
47+
Now we create a Linux VM using a supported Ubuntu image ('Ubuntu2204'). In this example, we use a Standard_B1s VM size. We also set an administrator username and let Azure generate SSH key pairs automatically. A random suffix is used in the VM name for uniqueness.
48+
49+
```bash
50+
export VM_NAME="LinuxVM$RANDOM_SUFFIX"
51+
export ADMIN_USERNAME="azureuser"
52+
az vm create \
53+
--resource-group $RG_NAME \
54+
--name $VM_NAME \
55+
--image Ubuntu2204 \
56+
--size Standard_B1s \
57+
--admin-username $ADMIN_USERNAME \
58+
--generate-ssh-keys
59+
```
60+
61+
Results:
62+
63+
<!-- expected_similarity=0.3 -->
64+
```JSON
65+
{
66+
"fqdns": "",
67+
"id": "/subscriptions/xxxxx/resourceGroups/LinuxRGabc123/providers/Microsoft.Compute/virtualMachines/LinuxVMabc123",
68+
"location": "centralindia",
69+
"macAddress": "00-0X-0X-0X-0X-0X",
70+
"machineId": "xxxxx",
71+
"name": "LinuxVMabc123",
72+
"powerState": "VM running",
73+
"privateIpAddress": "10.0.0.4",
74+
"publicIpAddress": "13.92.xxx.xxx",
75+
"resourceGroup": "LinuxRGabc123",
76+
"zones": ""
77+
}
78+
```
79+
80+
## Step 3: Retrieve the VM Public IP Address
81+
82+
This step retrieves the public IP address of the newly created VM. The public IP is stored in an environment variable to be used in the SSH step.
83+
84+
```bash
85+
export VM_PUBLIC_IP=$(az vm list-ip-addresses --resource-group $RG_NAME --name $VM_NAME --query "[].virtualMachine.network.publicIpAddresses[0].ipAddress" --output tsv)
86+
echo "The public IP address of the VM is: $VM_PUBLIC_IP"
87+
```
88+
89+
Results:
90+
91+
<!-- expected_similarity=0.3 -->
92+
```text
93+
The public IP address of the VM is: 13.92.xxx.xxx
94+
```
95+
96+
## Step 4: SSH into the Linux VM
97+
98+
Finally, once you have retrieved the public IP address, you can SSH into your Linux VM using the generated SSH key pair. This command establishes an SSH connection without prompting for host key verification.
99+
100+
```bash
101+
ssh -o StrictHostKeyChecking=no $ADMIN_USERNAME@$VM_PUBLIC_IP
102+
```
103+
104+
When executed, this command initiates an SSH session with your Linux VM. After connecting, you will have full access to manage and configure the VM as needed.
105+
106+
---
107+
108+
This Exec Doc has successfully deployed a Linux VM in Azure using a supported Ubuntu image and shown how to connect to it using SSH, all accomplished with a series of Azure CLI commands executed via the Innovation Engine.

tools/ada.py

Lines changed: 104 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,31 @@ def generate_dependency_files(doc_path):
438438

439439
print("\nAnalyzing document for dependencies...")
440440

441+
# First, detect file creation patterns in the document to avoid conflicts
442+
file_creation_patterns = [
443+
# Cat heredoc to a file
444+
(r'cat\s*<<\s*[\'"]?(EOF|END)[\'"]?\s*>\s*([^\s;]+)', 1),
445+
# Echo content to a file
446+
(r'echo\s+.*?>\s*([^\s;]+)', 0),
447+
# Tee command
448+
(r'tee\s+([^\s;]+)', 0)
449+
]
450+
451+
doc_created_files = []
452+
for pattern, group_idx in file_creation_patterns:
453+
matches = re.findall(pattern, doc_content, re.DOTALL)
454+
for match in matches:
455+
if isinstance(match, tuple):
456+
filename = match[group_idx]
457+
else:
458+
filename = match
459+
doc_created_files.append(filename)
460+
461+
if doc_created_files:
462+
print("\nDetected file creation commands in document:")
463+
for file in doc_created_files:
464+
print(f" - {file}")
465+
441466
# Enhanced prompt for better dependency file identification
442467
dependency_prompt = """Analyze this Exec Doc and identify ANY files that the user is instructed to create.
443468
@@ -507,9 +532,23 @@ def generate_dependency_files(doc_path):
507532
print("\nNo dependency files identified.")
508533
return True, []
509534

535+
# Filter out dependency files that have inline creation commands in the document
536+
filtered_deps = []
537+
for dep in dependency_list:
538+
filename = dep.get("filename")
539+
if not filename:
540+
continue
541+
542+
if filename in doc_created_files:
543+
print(f"\nWARNING: File '{filename}' is both created in document and identified as a dependency.")
544+
print(f" - Skipping dependency management for this file to avoid conflicts.")
545+
continue
546+
547+
filtered_deps.append(dep)
548+
510549
# Create each dependency file with type-specific handling
511550
created_files = []
512-
for dep in dependency_list:
551+
for dep in filtered_deps:
513552
filename = dep.get("filename")
514553
content = dep.get("content")
515554
file_type = dep.get("type", "").lower()
@@ -596,6 +635,60 @@ def generate_dependency_files(doc_path):
596635
print("\nResponse from model was not valid JSON. Raw response:")
597636
return False, []
598637

638+
# Add this function after generate_dependency_files function (approximately line 609)
639+
640+
def transform_document_for_dependencies(doc_path, dependency_files):
641+
"""Remove file creation commands from document when using dependency files."""
642+
if not dependency_files:
643+
return False
644+
645+
try:
646+
with open(doc_path, "r") as f:
647+
doc_content = f.read()
648+
649+
original_content = doc_content
650+
modified = False
651+
652+
for dep_file in dependency_files:
653+
filename = dep_file["filename"]
654+
655+
# Pattern to match cat/EOF blocks for file creation
656+
cat_pattern = re.compile(
657+
r'```(?:bash|azurecli|azure-cli-interactive|azurecli-interactive)\s*\n'
658+
r'(.*?cat\s*<<\s*[\'"]?(EOF|END)[\'"]?\s*>\s*' + re.escape(filename) + r'.*?EOF.*?)'
659+
r'\n```',
660+
re.DOTALL
661+
)
662+
663+
# Replace with a reference to the external file
664+
if cat_pattern.search(doc_content):
665+
replacement = f"```bash\n# Using external file: {filename}\n```\n\n"
666+
doc_content = cat_pattern.sub(replacement, doc_content)
667+
modified = True
668+
print(f"\nTransformed document to use external {filename} instead of inline creation")
669+
670+
# Handle other file creation patterns (echo, tee)
671+
echo_pattern = re.compile(
672+
r'```(?:bash|azurecli|azure-cli-interactive|azurecli-interactive)\s*\n'
673+
r'(.*?echo\s+.*?>\s*' + re.escape(filename) + r'.*?)'
674+
r'\n```',
675+
re.DOTALL
676+
)
677+
if echo_pattern.search(doc_content):
678+
replacement = f"```bash\n# Using external file: {filename}\n```\n\n"
679+
doc_content = echo_pattern.sub(replacement, doc_content)
680+
modified = True
681+
682+
if modified:
683+
with open(doc_path, "w") as f:
684+
f.write(doc_content)
685+
print("\nDocument transformed to use external dependency files")
686+
return True
687+
return False
688+
except Exception as e:
689+
print(f"\nError transforming document: {e}")
690+
return False
691+
599692
def update_dependency_file(file_info, error_message, main_doc_path):
600693
"""Update a dependency file based on error message."""
601694
filename = file_info["filename"]
@@ -857,7 +950,7 @@ def main():
857950
print(" 2. Describe workload to generate a new Exec Doc")
858951
print(" 3. Add descriptions to a shell script as an Exec Doc")
859952
print(" 4. Redact PII from an existing Exec Doc")
860-
print(" 5. Perform security vulnerability check on an Exec Doc")
953+
print(" 5. Generate a security analysis report for an Exec Doc")
861954
choice = input("\nEnter the number corresponding to your choice: ")
862955

863956
if choice == "1":
@@ -949,6 +1042,15 @@ def main():
9491042
if generate_deps and not dependency_files_generated:
9501043
_, dependency_files = generate_dependency_files(output_file)
9511044
dependency_files_generated = True
1045+
1046+
# Generate dependency files after first creation
1047+
if generate_deps and not dependency_files_generated:
1048+
_, dependency_files = generate_dependency_files(output_file)
1049+
dependency_files_generated = True
1050+
1051+
# Add this new line to transform the document after dependency generation
1052+
if dependency_files:
1053+
transform_document_for_dependencies(output_file, dependency_files)
9521054
else:
9531055
print(f"\n{'='*40}\nAttempt {attempt}: Generating corrections based on error...\n{'='*40}")
9541056

tools/aks.sh

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#!/bin/bash
2+
# This script creates an AKS cluster using Azure CLI
3+
4+
# Exit on error
5+
set -e
6+
7+
# Configuration variables
8+
RESOURCE_GROUP="myAKSResourceGroup"
9+
LOCATION="eastus"
10+
CLUSTER_NAME="myAKSCluster"
11+
NODE_COUNT=3
12+
NODE_VM_SIZE="Standard_DS2_v2"
13+
KUBERNETES_VERSION="1.26.3" # Check available versions with: az aks get-versions --location $LOCATION --output table
14+
15+
# Login to Azure (uncomment if not already logged in)
16+
# az login
17+
18+
# Create resource group
19+
echo "Creating resource group $RESOURCE_GROUP in $LOCATION..."
20+
az group create --name $RESOURCE_GROUP --location $LOCATION
21+
22+
# Create AKS cluster
23+
echo "Creating AKS cluster $CLUSTER_NAME..."
24+
az aks create \
25+
--resource-group $RESOURCE_GROUP \
26+
--name $CLUSTER_NAME \
27+
--node-count $NODE_COUNT \
28+
--node-vm-size $NODE_VM_SIZE \
29+
--kubernetes-version $KUBERNETES_VERSION \
30+
--generate-ssh-keys \
31+
--enable-managed-identity \
32+
--enable-cluster-autoscaler \
33+
--min-count 1 \
34+
--max-count 5
35+
36+
# Get credentials for the Kubernetes cluster
37+
echo "Getting credentials for cluster $CLUSTER_NAME..."
38+
az aks get-credentials --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME
39+
40+
echo "AKS cluster $CLUSTER_NAME has been created successfully!"
41+
echo "You can now use kubectl to manage your cluster"
42+
43+
# Verify connection to the cluster
44+
echo "Verifying connection to the cluster..."
45+
kubectl get nodes

0 commit comments

Comments
 (0)