argobox-portfolio/ansible-sandbox.html

1598 lines
50 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Argobox | Ansible Sandbox</title>
<!-- SEO Meta Tags -->
<meta name="description" content="Interactive Ansible playbook testing environment. Deploy test configurations and see infrastructure automation in action.">
<!-- Favicon -->
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 width=%22256%22 height=%22256%22 viewBox=%220 0 100 100%22><rect width=%22100%22 height=%22100%22 rx=%2220%22 fill=%22%230f172a%22></rect><path fill=%22%233b82f6%22 d=%22M30 40L50 20L70 40L50 60L30 40Z%22></path><path fill=%22%233b82f6%22 d=%22M50 60L70 40L70 70L50 90L30 70L30 40L50 60Z%22 fill-opacity=%220.6%22></path></svg>">
<!-- Google Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
<!-- FontAwesome -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css">
<style>
:root {
/* Main Colors */
--primary-bg: #0f172a;
--secondary-bg: #1e293b;
--accent: #3b82f6;
--accent-darker: #2563eb;
--accent-gradient: linear-gradient(135deg, #2563eb, #3b82f6);
--accent-red: #ef4444;
--accent-green: #10b981;
--accent-yellow: #f59e0b;
--accent-glow: 0 0 15px rgba(59, 130, 246, 0.5);
/* Text Colors */
--text-primary: #e2e8f0;
--text-secondary: #94a3b8;
--text-accent: #3b82f6;
/* Status Colors */
--success: #10b981;
--warning: #f59e0b;
--error: #ef4444;
--info: #0ea5e9;
/* UI Elements */
--border: rgba(71, 85, 105, 0.5);
--card-bg: rgba(30, 41, 59, 0.8);
--card-hover-bg: rgba(30, 41, 59, 0.95);
--card-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.3);
--glass-effect: saturate(180%) blur(10px);
/* Animation Timing */
--transition-fast: 0.2s ease;
--transition-normal: 0.3s ease;
--transition-slow: 0.5s ease;
}
/* Reset & Base Styles */
*, *::before, *::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
font-family: 'Inter', system-ui, -apple-system, sans-serif;
background-color: var(--primary-bg);
color: var(--text-primary);
line-height: 1.6;
overflow-x: hidden;
min-height: 100vh;
background-image:
radial-gradient(circle at 20% 35%, rgba(29, 78, 216, 0.15) 0%, transparent 50%),
radial-gradient(circle at 75% 60%, rgba(14, 165, 233, 0.1) 0%, transparent 50%);
}
.container {
max-width: 1400px;
margin: 0 auto;
padding: 0 1.5rem;
}
/* Navigation Bar */
.navbar {
background-color: rgba(15, 23, 42, 0.9);
backdrop-filter: var(--glass-effect);
-webkit-backdrop-filter: var(--glass-effect);
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 1000;
padding: 1.25rem 0;
border-bottom: 1px solid var(--border);
}
.navbar .container {
display: flex;
justify-content: space-between;
align-items: center;
}
.logo a {
color: var(--text-primary);
text-decoration: none;
display: flex;
align-items: center;
gap: 0.25rem;
}
.logo-text-glow {
background: var(--accent-gradient);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
font-size: 1.5rem;
font-weight: 600;
text-shadow: 0 0 10px rgba(59, 130, 246, 0.3);
position: relative;
}
.logo-text-glow::before {
content: "";
position: absolute;
inset: -5px;
background: radial-gradient(circle at center, rgba(59, 130, 246, 0.2), transparent 60%);
z-index: -1;
filter: blur(5px);
}
.logo-dot-glow {
color: var(--text-secondary);
font-size: 1.5rem;
font-weight: 600;
}
.nav-menu {
display: flex;
gap: 2.5rem;
}
.nav-link {
color: var(--text-secondary);
text-decoration: none;
font-size: 0.95rem;
font-weight: 500;
transition: all var(--transition-normal);
position: relative;
}
.nav-link::after {
content: "";
position: absolute;
bottom: -5px;
left: 0;
width: 0;
height: 2px;
background: var(--accent-gradient);
transition: width var(--transition-normal);
}
.nav-link:hover {
color: var(--text-primary);
}
.nav-link:hover::after {
width: 100%;
}
.nav-link.active {
color: var(--accent);
}
.nav-link.active::after {
width: 100%;
}
.nav-buttons {
display: flex;
align-items: center;
gap: 1.25rem;
}
.dashboard-link {
display: flex;
align-items: center;
gap: 0.75rem;
padding: 0.625rem 1.25rem;
font-size: 0.95rem;
font-weight: 500;
color: var(--text-primary);
background-color: rgba(59, 130, 246, 0.1);
border: 1px solid rgba(59, 130, 246, 0.2);
border-radius: 0.5rem;
text-decoration: none;
transition: all var(--transition-normal);
}
.dashboard-link:hover {
background-color: rgba(59, 130, 246, 0.2);
border-color: rgba(59, 130, 246, 0.3);
}
.live-indicator {
width: 8px;
height: 8px;
background-color: var(--success);
border-radius: 50%;
animation: pulse 2s infinite;
}
.menu-toggle {
display: none;
background: none;
border: none;
color: var(--text-primary);
font-size: 1.25rem;
cursor: pointer;
}
/* Sandbox Specific Styles */
.sandbox-container {
padding: 5rem 0 2rem;
margin-top: 4rem;
}
.sandbox-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 2rem;
}
.sandbox-title {
display: flex;
align-items: center;
gap: 1rem;
}
.sandbox-title h1 {
font-size: 1.75rem;
font-weight: 600;
}
.sandbox-actions {
display: flex;
gap: 1rem;
}
.sandbox-btn {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.5rem 1rem;
border-radius: 0.5rem;
background-color: var(--card-bg);
border: 1px solid var(--border);
color: var(--text-primary);
font-size: 0.9rem;
font-weight: 500;
cursor: pointer;
transition: all var(--transition-normal);
}
.sandbox-btn:hover {
background-color: var(--card-hover-bg);
border-color: var(--accent);
}
.sandbox-btn i {
color: var(--accent);
}
.btn-primary {
background: var(--accent-gradient);
color: white;
border: none;
}
.btn-primary:hover {
box-shadow: var(--accent-glow);
transform: translateY(-2px);
}
.sandbox-grid {
display: grid;
grid-template-columns: 1fr 2fr;
gap: 1.5rem;
}
.playbook-list {
display: flex;
flex-direction: column;
gap: 1rem;
max-height: 80vh;
overflow-y: auto;
padding-right: 0.5rem;
scrollbar-width: thin;
scrollbar-color: var(--border) transparent;
}
.playbook-list::-webkit-scrollbar {
width: 6px;
}
.playbook-list::-webkit-scrollbar-track {
background: transparent;
}
.playbook-list::-webkit-scrollbar-thumb {
background-color: var(--border);
border-radius: 3px;
}
.playbook-card {
background-color: var(--card-bg);
border: 1px solid var(--border);
border-radius: 0.75rem;
padding: 1.25rem;
cursor: pointer;
transition: all var(--transition-normal);
}
.playbook-card:hover {
transform: translateY(-3px);
border-color: var(--accent);
box-shadow: var(--card-shadow);
}
.playbook-card.active {
border-color: var(--accent);
background-color: rgba(59, 130, 246, 0.1);
}
.playbook-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 0.5rem;
}
.playbook-title {
font-weight: 600;
font-size: 1.1rem;
}
.playbook-tag {
font-size: 0.75rem;
padding: 0.15rem 0.5rem;
border-radius: 9999px;
background-color: rgba(59, 130, 246, 0.1);
color: var(--accent);
font-weight: 500;
}
.playbook-description {
font-size: 0.9rem;
color: var(--text-secondary);
margin-bottom: 1rem;
}
.playbook-details {
display: flex;
gap: 1rem;
font-size: 0.8rem;
color: var(--text-secondary);
}
.playbook-detail {
display: flex;
align-items: center;
gap: 0.35rem;
}
.playbook-detail i {
font-size: 0.85rem;
color: var(--accent);
}
.sandbox-preview {
display: flex;
flex-direction: column;
min-height: 80vh;
}
.preview-container {
background-color: var(--card-bg);
border: 1px solid var(--border);
border-radius: 0.75rem;
flex: 1;
overflow: hidden;
display: flex;
flex-direction: column;
}
.preview-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 1.5rem;
border-bottom: 1px solid var(--border);
}
.preview-title {
font-weight: 600;
font-size: 1.1rem;
display: flex;
align-items: center;
gap: 0.75rem;
}
.preview-tabs {
display: flex;
gap: 1rem;
}
.preview-tab {
color: var(--text-secondary);
font-size: 0.9rem;
font-weight: 500;
cursor: pointer;
padding-bottom: 0.25rem;
border-bottom: 2px solid transparent;
transition: all var(--transition-normal);
}
.preview-tab:hover {
color: var(--text-primary);
}
.preview-tab.active {
color: var(--accent);
border-bottom-color: var(--accent);
}
.preview-content {
flex: 1;
overflow: hidden;
display: flex;
flex-direction: column;
}
.tab-content {
display: none;
flex: 1;
overflow: auto;
padding: 1.5rem;
}
.tab-content.active {
display: block;
}
.code-editor {
font-family: 'JetBrains Mono', monospace;
font-size: 0.9rem;
line-height: 1.5;
overflow: auto;
height: 100%;
}
.code-line {
display: flex;
}
.line-number {
width: 3rem;
text-align: right;
padding-right: 1rem;
user-select: none;
color: var(--text-secondary);
opacity: 0.5;
}
.line-content {
flex: 1;
}
.code-comment {
color: #6b7280;
font-style: italic;
}
.code-key {
color: #93c5fd;
}
.code-value {
color: #fbbf24;
}
.code-string {
color: #a3be8c;
}
.preview-form {
padding: 1.5rem;
overflow: auto;
}
.form-group {
margin-bottom: 1.5rem;
}
.form-label {
display: block;
margin-bottom: 0.5rem;
font-weight: 500;
font-size: 0.9rem;
}
.form-control {
width: 100%;
padding: 0.75rem 1rem;
background-color: var(--primary-bg);
border: 1px solid var(--border);
border-radius: 0.5rem;
color: var(--text-primary);
font-family: 'Inter', sans-serif;
font-size: 0.9rem;
transition: all var(--transition-normal);
}
.form-control:focus {
outline: none;
border-color: var(--accent);
box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2);
}
.form-select {
appearance: none;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke='%2394a3b8'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M19 9l-7 7-7-7'%3E%3C/path%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 1rem center;
background-size: 1em;
}
.form-text {
font-size: 0.8rem;
color: var(--text-secondary);
margin-top: 0.5rem;
}
.form-check {
display: flex;
align-items: center;
margin-bottom: 0.75rem;
}
.form-check-input {
margin-right: 0.75rem;
appearance: none;
width: 1.25rem;
height: 1.25rem;
background-color: var(--primary-bg);
border: 1px solid var(--border);
border-radius: 0.25rem;
cursor: pointer;
transition: all var(--transition-normal);
position: relative;
}
.form-check-input:checked {
background-color: var(--accent);
border-color: var(--accent);
}
.form-check-input:checked::after {
content: '✓';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: white;
font-size: 0.85rem;
}
.form-check-label {
font-size: 0.9rem;
}
.terminal {
font-family: 'JetBrains Mono', monospace;
font-size: 0.85rem;
line-height: 1.5;
padding: 1.5rem;
background-color: #1a1a1a;
color: #e2e8f0;
overflow: auto;
height: 100%;
white-space: pre-wrap;
}
.terminal-line {
margin-bottom: 0.5rem;
}
.terminal-success {
color: var(--success);
}
.terminal-error {
color: var(--error);
}
.terminal-warning {
color: var(--warning);
}
.terminal-command {
color: var(--accent);
font-weight: 500;
}
.preview-actions {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 1.5rem;
border-top: 1px solid var(--border);
}
.preview-status {
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 0.9rem;
}
.status-dot {
width: 10px;
height: 10px;
border-radius: 50%;
}
.status-ready {
background-color: var(--info);
}
.status-running {
background-color: var(--warning);
animation: pulse 1s infinite;
}
.status-success {
background-color: var(--success);
}
.status-error {
background-color: var(--error);
}
.preview-buttons {
display: flex;
gap: 1rem;
}
.vm-status {
display: flex;
flex-direction: column;
gap: 0.75rem;
padding: 1.5rem;
display: none;
}
.vm-status.active {
display: flex;
}
.vm-card {
background-color: rgba(30, 41, 59, 0.5);
border-radius: 0.5rem;
padding: 1rem;
display: flex;
align-items: center;
gap: 1rem;
}
.vm-icon {
width: 3rem;
height: 3rem;
background-color: var(--secondary-bg);
border-radius: 0.5rem;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.5rem;
color: var(--accent);
}
.vm-info {
flex: 1;
}
.vm-name {
font-weight: 600;
margin-bottom: 0.25rem;
}
.vm-details {
font-size: 0.85rem;
color: var(--text-secondary);
}
.vm-progress {
flex: 1;
height: 4px;
background-color: rgba(255, 255, 255, 0.1);
border-radius: 2px;
overflow: hidden;
margin-top: 0.5rem;
}
.vm-progress-bar {
height: 100%;
background-color: var(--accent);
border-radius: 2px;
transition: width 0.3s ease;
}
.vm-state {
padding: 0.25rem 0.75rem;
border-radius: 9999px;
font-size: 0.75rem;
font-weight: 500;
}
.vm-state-provisioning {
background-color: rgba(245, 158, 11, 0.1);
color: var(--warning);
}
.vm-state-running {
background-color: rgba(16, 185, 129, 0.1);
color: var(--success);
}
.vm-state-stopping {
background-color: rgba(239, 68, 68, 0.1);
color: var(--error);
}
.time-remaining {
font-size: 0.85rem;
color: var(--text-secondary);
text-align: center;
margin-top: 1.5rem;
}
.time-progress {
width: 100%;
height: 4px;
background-color: rgba(255, 255, 255, 0.1);
border-radius: 2px;
overflow: hidden;
margin-top: 0.75rem;
}
.time-progress-bar {
height: 100%;
background-color: var(--accent);
border-radius: 2px;
transition: width 1s linear;
}
/* Footer */
.footer {
background-color: var(--secondary-bg);
border-top: 1px solid var(--border);
padding: 3rem 0 1.5rem;
margin-top: 5rem;
}
.footer-content {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 2rem;
}
.footer-logo {
font-weight: 600;
font-size: 1.5rem;
}
.footer-links {
display: flex;
gap: 2rem;
}
.footer-links a {
color: var(--text-secondary);
text-decoration: none;
font-size: 0.95rem;
transition: color var(--transition-normal);
}
.footer-links a:hover {
color: var(--accent);
}
.footer-social {
display: flex;
gap: 1.25rem;
}
.footer-social a {
color: var(--text-secondary);
font-size: 1.25rem;
transition: color var(--transition-normal);
}
.footer-social a:hover {
color: var(--accent);
}
.footer-bottom {
padding-top: 1.5rem;
border-top: 1px solid var(--border);
text-align: center;
font-size: 0.9rem;
color: var(--text-secondary);
}
/* Animation */
@keyframes pulse {
0% {
opacity: 1;
}
50% {
opacity: 0.5;
}
100% {
opacity: 1;
}
}
/* Responsive */
@media (max-width: 992px) {
.sandbox-grid {
grid-template-columns: 1fr;
}
.playbook-list {
max-height: initial;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
}
.nav-menu {
position: fixed;
top: 75px;
left: 0;
right: 0;
background-color: var(--primary-bg);
flex-direction: column;
align-items: center;
padding: 2rem 0;
gap: 1.5rem;
transition: transform var(--transition-normal);
transform: translateY(-150%);
border-bottom: 1px solid var(--border);
}
.nav-menu.show {
transform: translateY(0);
}
.menu-toggle {
display: block;
}
}
@media (max-width: 768px) {
.sandbox-header {
flex-direction: column;
align-items: flex-start;
gap: 1rem;
}
.sandbox-actions {
width: 100%;
justify-content: flex-end;
}
.preview-tabs {
display: none;
}
.footer-content {
flex-direction: column;
gap: 2rem;
align-items: flex-start;
}
.footer-links {
flex-wrap: wrap;
justify-content: center;
gap: 1.5rem;
row-gap: 1rem;
}
}
/* Documentation Specific Styles */
.docs-container {
display: grid;
grid-template-columns: 300px 1fr;
gap: 2rem;
max-width: 1400px;
margin: 2rem auto;
padding: 0 1.5rem;
}
.sidebar {
position: sticky;
top: 100px;
height: calc(100vh - 120px);
overflow-y: auto;
background-color: var(--sidebar-bg);
border-radius: 0.75rem;
padding: 1.5rem;
border: 1px solid var(--border);
}
.sidebar-header {
margin-bottom: 2rem;
}
.sidebar-title {
font-size: 1.5rem;
font-weight: 600;
color: var(--text-primary);
margin-bottom: 1rem;
}
.back-link {
display: flex;
align-items: center;
gap: 0.5rem;
color: var(--text-secondary);
text-decoration: none;
font-size: 0.95rem;
transition: color var(--transition-normal);
}
.back-link:hover {
color: var(--accent);
}
.sidebar-section {
margin-bottom: 2rem;
}
.sidebar-section-title {
font-size: 1rem;
font-weight: 600;
color: var(--text-primary);
margin-bottom: 1rem;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.sidebar-nav {
list-style: none;
}
.sidebar-nav-item {
margin-bottom: 0.5rem;
}
.sidebar-nav-link {
display: block;
padding: 0.5rem;
color: var(--text-secondary);
text-decoration: none;
border-radius: 0.375rem;
transition: all var(--transition-normal);
}
.sidebar-nav-link:hover,
.sidebar-nav-link.active {
color: var(--accent);
background-color: rgba(59, 130, 246, 0.1);
}
.main-content {
background-color: var(--card-bg);
border-radius: 0.75rem;
padding: 2rem;
border: 1px solid var(--border);
}
.docs-header {
margin-bottom: 3rem;
text-align: center;
}
.docs-title {
font-size: 2.5rem;
font-weight: 700;
color: var(--text-primary);
margin-bottom: 1rem;
background: var(--accent-gradient);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
.docs-subtitle {
font-size: 1.125rem;
color: var(--text-secondary);
}
.docs-section {
margin-bottom: 4rem;
}
.docs-section-title {
font-size: 1.75rem;
font-weight: 600;
color: var(--text-primary);
margin-bottom: 1.5rem;
padding-bottom: 0.75rem;
border-bottom: 1px solid var(--border);
}
.docs-subsection {
margin-bottom: 2rem;
}
.docs-subsection-title {
font-size: 1.25rem;
font-weight: 600;
color: var(--text-primary);
margin-bottom: 1rem;
}
.docs-text {
color: var(--text-secondary);
margin-bottom: 1.5rem;
line-height: 1.7;
}
.docs-list {
color: var(--text-secondary);
margin-bottom: 1.5rem;
padding-left: 1.5rem;
}
.docs-list li {
margin-bottom: 0.75rem;
}
.docs-table {
width: 100%;
border-collapse: collapse;
margin-bottom: 1.5rem;
}
.docs-table th,
.docs-table td {
padding: 0.75rem;
text-align: left;
border-bottom: 1px solid var(--border);
}
.docs-table th {
font-weight: 600;
color: var(--text-primary);
background-color: rgba(30, 41, 59, 0.5);
}
.docs-table td {
color: var(--text-secondary);
}
.docs-code {
background-color: rgba(15, 23, 42, 0.6);
border-radius: 0.5rem;
padding: 1.5rem;
margin-bottom: 1.5rem;
overflow-x: auto;
}
.docs-code pre {
font-family: 'JetBrains Mono', monospace;
font-size: 0.9rem;
color: var(--text-primary);
line-height: 1.5;
}
.docs-warning,
.docs-note {
background-color: rgba(245, 158, 11, 0.1);
border: 1px solid var(--warning);
border-radius: 0.5rem;
padding: 1.25rem;
margin-bottom: 1.5rem;
}
.docs-note {
background-color: rgba(14, 165, 233, 0.1);
border-color: var(--info);
}
.docs-warning-title,
.docs-note-title {
display: flex;
align-items: center;
gap: 0.5rem;
font-weight: 600;
color: var(--warning);
margin-bottom: 0.5rem;
}
.docs-note-title {
color: var(--info);
}
.docs-button {
display: inline-flex;
align-items: center;
gap: 0.5rem;
padding: 0.75rem 1.5rem;
background: var(--accent-gradient);
color: var(--text-primary);
text-decoration: none;
border-radius: 0.5rem;
font-weight: 500;
transition: all var(--transition-normal);
}
.docs-button:hover {
box-shadow: var(--accent-glow);
transform: translateY(-1px);
}
@media (max-width: 992px) {
.docs-container {
grid-template-columns: 1fr;
}
.sidebar {
position: fixed;
left: -300px;
top: 0;
bottom: 0;
width: 300px;
z-index: 1000;
transition: left var(--transition-normal);
}
.sidebar.active {
left: 0;
}
.mobile-menu-toggle {
position: fixed;
bottom: 2rem;
right: 2rem;
width: 3rem;
height: 3rem;
border-radius: 50%;
background: var(--accent-gradient);
border: none;
color: var(--text-primary);
font-size: 1.25rem;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
z-index: 1001;
box-shadow: var(--card-shadow);
transition: all var(--transition-normal);
}
.mobile-menu-toggle:hover {
box-shadow: var(--accent-glow);
transform: scale(1.05);
}
}
</style>
</head>
<body>
<!-- Navigation Bar -->
<nav class="navbar">
<div class="container">
<div class="logo">
<a href="index.html">
<span class="logo-text-glow">Argobox</span>
<span class="logo-dot-glow">.com</span>
</a>
</div>
<div class="nav-menu" id="navMenu">
<a href="index.html#home" class="nav-link">Home</a>
<a href="index.html#technologies" class="nav-link">Technologies</a>
<a href="index.html#services" class="nav-link">Services</a>
<a href="index.html#projects" class="nav-link">Projects</a>
<a href="index.html#dashboards" class="nav-link">Dashboards</a>
<a href="index.html#contact" class="nav-link">Contact</a>
</div>
<div class="nav-buttons">
<a href="dashboard.html" class="dashboard-link" target="_blank">
<span class="live-indicator"></span>
<span>Live Dashboard</span>
</a>
<button class="menu-toggle" id="menuToggle" aria-label="Toggle menu">
<i class="fas fa-bars"></i>
</button>
</div>
</div>
</nav>
<div class="construction-warning">
<i class="fas fa-hard-hat"></i>
<div>
<h3>Under Construction</h3>
<p>This page is still being developed. Check back soon for updates!</p>
</div>
</div>
<div class="docs-container">
<aside class="sidebar">
<div class="sidebar-header">
<h2 class="sidebar-title">Ansible Sandbox</h2>
<a href="index.html" class="back-link">
<i class="fas fa-arrow-left"></i>
Back to Home
</a>
</div>
<div class="sidebar-section">
<h3 class="sidebar-section-title">Getting Started</h3>
<ul class="sidebar-nav">
<li class="sidebar-nav-item">
<a href="#introduction" class="sidebar-nav-link active">Introduction</a>
</li>
<li class="sidebar-nav-item">
<a href="#prerequisites" class="sidebar-nav-link">Prerequisites</a>
</li>
<li class="sidebar-nav-item">
<a href="#quick-start" class="sidebar-nav-link">Quick Start Guide</a>
</li>
</ul>
</div>
<div class="sidebar-section">
<h3 class="sidebar-section-title">Features</h3>
<ul class="sidebar-nav">
<li class="sidebar-nav-item">
<a href="#sandbox-environment" class="sidebar-nav-link">Sandbox Environment</a>
</li>
<li class="sidebar-nav-item">
<a href="#playbook-examples" class="sidebar-nav-link">Playbook Examples</a>
</li>
<li class="sidebar-nav-item">
<a href="#best-practices" class="sidebar-nav-link">Best Practices</a>
</li>
</ul>
</div>
<div class="sidebar-section">
<h3 class="sidebar-section-title">Resources</h3>
<ul class="sidebar-nav">
<li class="sidebar-nav-item">
<a href="#documentation" class="sidebar-nav-link">Documentation</a>
</li>
<li class="sidebar-nav-item">
<a href="#troubleshooting" class="sidebar-nav-link">Troubleshooting</a>
</li>
<li class="sidebar-nav-item">
<a href="#community" class="sidebar-nav-link">Community</a>
</li>
</ul>
</div>
</aside>
<main class="main-content">
<header class="docs-header">
<h1 class="docs-title">Ansible Sandbox Documentation</h1>
<p class="docs-subtitle">Learn, experiment, and master Ansible automation in a safe environment</p>
</header>
<section id="introduction" class="docs-section">
<h2 class="docs-section-title">Introduction</h2>
<p class="docs-text">
Welcome to the ArgoBox Ansible Sandbox! This environment provides a safe and isolated space for learning
and experimenting with Ansible automation. Whether you're new to Ansible or an experienced user, our
sandbox offers the perfect platform to develop and test your automation skills.
</p>
<div class="docs-note">
<div class="docs-note-title">
<i class="fas fa-info-circle"></i>
Note
</div>
<p>The Ansible Sandbox is part of the ArgoBox Lab Environment, designed to provide hands-on experience
with enterprise-grade automation tools.</p>
</div>
</section>
<section id="prerequisites" class="docs-section">
<h2 class="docs-section-title">Prerequisites</h2>
<div class="docs-subsection">
<h3 class="docs-subsection-title">System Requirements</h3>
<ul class="docs-list">
<li>Access to ArgoBox Lab Environment</li>
<li>Basic understanding of YAML syntax</li>
<li>Familiarity with command-line interface</li>
<li>Text editor or IDE for writing playbooks</li>
</ul>
</div>
<div class="docs-subsection">
<h3 class="docs-subsection-title">Required Knowledge</h3>
<p class="docs-text">
While no prior Ansible experience is required, basic understanding of the following concepts will be
helpful:
</p>
<ul class="docs-list">
<li>Linux/Unix command line basics</li>
<li>SSH and basic networking concepts</li>
<li>Version control with Git (optional)</li>
</ul>
</div>
</section>
<section id="quick-start" class="docs-section">
<h2 class="docs-section-title">Quick Start Guide</h2>
<div class="docs-warning">
<div class="docs-warning-title">
<i class="fas fa-exclamation-triangle"></i>
Important
</div>
<p>Make sure you have completed the initial setup and have your credentials ready before proceeding.</p>
</div>
<div class="docs-subsection">
<h3 class="docs-subsection-title">Getting Started Steps</h3>
<ol class="docs-list">
<li>Log in to your ArgoBox environment</li>
<li>Navigate to the Ansible Sandbox section</li>
<li>Create your first playbook using the provided templates</li>
<li>Test your playbook in the sandbox environment</li>
</ol>
</div>
<div class="docs-code">
<pre>
# Example playbook structure
---
- name: My First Playbook
hosts: sandbox
tasks:
- name: Ensure Apache is installed
ansible.builtin.package:
name: apache2
state: present</pre>
</div>
</section>
<section id="sandbox-environment" class="docs-section">
<h2 class="docs-section-title">Sandbox Environment</h2>
<p class="docs-text">
Our sandbox environment provides a fully isolated space where you can experiment with Ansible playbooks
without affecting production systems. The environment includes multiple target hosts, common services, and
pre-configured inventory files.
</p>
<div class="docs-subsection">
<h3 class="docs-subsection-title">Available Resources</h3>
<table class="docs-table">
<thead>
<tr>
<th>Resource</th>
<th>Description</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr>
<td>Control Node</td>
<td>Main Ansible control server</td>
<td>Available</td>
</tr>
<tr>
<td>Target Hosts</td>
<td>3 Ubuntu servers for testing</td>
<td>Available</td>
</tr>
<tr>
<td>Example Playbooks</td>
<td>Pre-configured templates</td>
<td>Available</td>
</tr>
</tbody>
</table>
</div>
</section>
<div class="docs-section">
<a href="construction.html" class="docs-button">
<i class="fas fa-book"></i>
View Full Documentation
</a>
</div>
</main>
</div>
<button class="mobile-menu-toggle">
<i class="fas fa-bars"></i>
</button>
<!-- Footer -->
<footer class="footer">
<div class="container">
<div class="footer-content">
<div class="footer-logo">
<span class="logo-text-glow">Argobox</span>
<span class="logo-dot-glow">.com</span>
</div>
<div class="footer-links">
<a href="index.html">Home</a>
<a href="index.html#services">Services</a>
<a href="index.html#lab">Live Lab</a>
<a href="index.html#projects">Projects</a>
<a href="index.html#experience">Experience</a>
<a href="index.html#contact">Contact</a>
</div>
<div class="footer-social">
<a href="https://linkedin.com/in/danlaforce" target="_blank"><i class="fab fa-linkedin"></i></a>
<a href="https://github.com/keyargo" target="_blank"><i class="fab fa-github"></i></a>
</div>
</div>
<div class="footer-bottom">
<p>&copy; <span id="current-year">2025</span> All rights reserved. Inovin LLC</p>
</div>
</div>
</footer>
<!-- JavaScript -->
<script>
document.addEventListener('DOMContentLoaded', function() {
// Set current year for copyright
document.getElementById('current-year').textContent = new Date().getFullYear();
// Mobile menu toggle
const menuToggle = document.getElementById('menuToggle');
const navMenu = document.getElementById('navMenu');
menuToggle.addEventListener('click', function() {
navMenu.classList.toggle('show');
const icon = menuToggle.querySelector('i');
if (navMenu.classList.contains('show')) {
icon.classList.remove('fa-bars');
icon.classList.add('fa-times');
} else {
icon.classList.remove('fa-times');
icon.classList.add('fa-bars');
}
});
// Tab switching
const tabs = document.querySelectorAll('.preview-tab');
const tabContents = document.querySelectorAll('.tab-content');
tabs.forEach(tab => {
tab.addEventListener('click', function() {
const tabId = this.getAttribute('data-tab');
tabs.forEach(t => t.classList.remove('active'));
tabContents.forEach(tc => tc.classList.remove('active'));
this.classList.add('active');
document.getElementById(`${tabId}-tab`).classList.add('active');
});
});
// Playbook selection
const playbooks = document.querySelectorAll('.playbook-card');
const previewTitle = document.querySelector('.preview-title span');
playbooks.forEach(playbook => {
playbook.addEventListener('click', function() {
playbooks.forEach(p => p.classList.remove('active'));
this.classList.add('active');
const playbookName = this.querySelector('.playbook-title').textContent;
previewTitle.textContent = playbookName;
// Reset status
const statusIndicator = document.querySelector('.preview-status');
statusIndicator.innerHTML = '<div class="status-dot status-ready"></div><span>Ready to deploy</span>';
// Switch back to code tab
tabs.forEach(t => t.classList.remove('active'));
tabContents.forEach(tc => tc.classList.remove('active'));
document.querySelector('[data-tab="code"]').classList.add('active');
document.getElementById('code-tab').classList.add('active');
});
});
// Deploy button
const deployBtn = document.getElementById('deploy-btn');
const resetBtn = document.getElementById('reset-btn');
const statusIndicator = document.querySelector('.preview-status');
deployBtn.addEventListener('click', function() {
// Show the "running" tab
tabs.forEach(t => t.classList.remove('active'));
tabContents.forEach(tc => tc.classList.remove('active'));
document.querySelector('[data-tab="output"]').classList.add('active');
document.getElementById('output-tab').classList.add('active');
// Update status to "running"
statusIndicator.innerHTML = '<div class="status-dot status-running"></div><span>Deploying...</span>';
// Disable the deploy button while "running"
deployBtn.disabled = true;
deployBtn.style.opacity = "0.7";
deployBtn.style.cursor = "not-allowed";
// Simulate a delay for deployment
setTimeout(function() {
// Update status to "success"
statusIndicator.innerHTML = '<div class="status-dot status-success"></div><span>Deployment successful</span>';
// Re-enable the deploy button
deployBtn.disabled = false;
deployBtn.style.opacity = "1";
deployBtn.style.cursor = "pointer";
// Switch to the VM status tab
tabs.forEach(t => t.classList.remove('active'));
tabContents.forEach(tc => tc.classList.remove('active'));
document.querySelector('[data-tab="status"]').classList.add('active');
document.getElementById('status-tab').classList.add('active');
// Start the countdown timer simulation
let timeLeft = 15; // minutes
const timeRemainingDiv = document.querySelector('.time-remaining div');
const timeProgressBar = document.querySelector('.time-progress-bar');
// For demo purposes, we'll just set the initial values
timeRemainingDiv.textContent = "Sandbox environment active for 15 more minutes";
timeProgressBar.style.width = "100%";
// In a real implementation, you would use setInterval to update the countdown
// This is left commented out to avoid unnecessary timer in the demo
/*
const countdownInterval = setInterval(function() {
timeLeft -= 1;
const width = (timeLeft / 15) * 100;
if (timeLeft <= 0) {
clearInterval(countdownInterval);
timeRemainingDiv.textContent = "Sandbox environment expired";
timeProgressBar.style.width = "0%";
// Reset status
statusIndicator.innerHTML = '<div class="status-dot status-ready"></div><span>Ready to deploy</span>';
} else {
timeRemainingDiv.textContent = `Sandbox environment active for ${timeLeft} more minutes`;
timeProgressBar.style.width = `${width}%`;
}
}, 60000); // Update every minute
*/
}, 3000); // Simulate 3 second deployment
});
// Reset button
resetBtn.addEventListener('click', function() {
// Reset status
statusIndicator.innerHTML = '<div class="status-dot status-ready"></div><span>Ready to deploy</span>';
// Switch back to code tab
tabs.forEach(t => t.classList.remove('active'));
tabContents.forEach(tc => tc.classList.remove('active'));
document.querySelector('[data-tab="code"]').classList.add('active');
document.getElementById('code-tab').classList.add('active');
});
});
</script>
</body>
</html>