Web Components ????????? Infrastructure as Code ?????????????????????
Web Components ????????????????????????????????? web ???????????????????????????????????? reusable UI components ???????????? Custom Elements, Shadow DOM ????????? HTML Templates ????????????????????????????????? framework (React, Vue, Angular) ???????????? vanilla JavaScript Infrastructure as Code (IaC) ???????????????????????????????????? infrastructure ???????????? code ?????????????????? configure ????????????????????? ????????? tools ???????????? Terraform, Pulumi, AWS CDK
?????????????????? Web Components ????????? IaC ??????????????? UI components ?????????????????? infrastructure management dashboards, ??????????????? visual editors ?????????????????? Terraform configurations, ??????????????? reusable infrastructure widgets ????????? embed ???????????????????????????, ??????????????? self-service portals ?????????????????? DevOps teams
??????????????? Framework-agnostic ???????????????????????????????????? frontend framework, Native browser support ????????????????????? library ???????????????, Encapsulation ???????????? Shadow DOM ???????????????????????? CSS ??????????????????, Reusable ???????????? projects ????????? organizations, Lightweight ??????????????? runtime dependency
??????????????? Web Components ?????????????????? IaC Dashboard
??????????????? custom elements ?????????????????? infrastructure management
// === Infrastructure Dashboard Web Components ===
// 1. Resource Status Component
class InfraResourceStatus extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
}
static get observedAttributes() {
return ['name', 'type', 'status', 'provider', 'region'];
}
connectedCallback() {
this.render();
}
attributeChangedCallback() {
this.render();
}
get statusColor() {
const status = this.getAttribute('status') || 'unknown';
const colors = {
running: '#22c55e',
stopped: '#ef4444',
pending: '#f59e0b',
creating: '#3b82f6',
destroying: '#dc2626',
unknown: '#6b7280',
};
return colors[status] || colors.unknown;
}
render() {
const name = this.getAttribute('name') || 'Unknown';
const type = this.getAttribute('type') || 'resource';
const status = this.getAttribute('status') || 'unknown';
const provider = this.getAttribute('provider') || 'aws';
const region = this.getAttribute('region') || 'us-east-1';
this.shadowRoot.innerHTML = `
`;
}
}
customElements.define('infra-resource-status', InfraResourceStatus);
// 2. Terraform Plan Viewer Component
class TerraformPlanViewer extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this._plan = { add: 0, change: 0, destroy: 0, resources: [] };
}
set plan(value) {
this._plan = value;
this.render();
}
connectedCallback() {
this.render();
}
render() {
const { add, change, destroy, resources } = this._plan;
const resourceHTML = resources.map(r => `
`).join('');
this.shadowRoot.innerHTML = `
to add
to change
to destroy
`;
}
}
customElements.define('terraform-plan-viewer', TerraformPlanViewer);
// Usage
// document.querySelector('terraform-plan-viewer').plan = {
// add: 3, change: 1, destroy: 0,
// resources: [
// { action: 'create', type: 'aws_instance', name: 'web-server' },
// { action: 'create', type: 'aws_security_group', name: 'web-sg' },
// ]
// };
Terraform Provider ???????????? Web Components
??????????????? visual Terraform configuration editor
// === Terraform Visual Editor Component ===
class TerraformEditor extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this._config = {
provider: 'aws',
region: 'ap-southeast-1',
resources: [],
};
}
connectedCallback() {
this.render();
this.setupEvents();
}
addResource(type, name, config) {
this._config.resources.push({ type, name, config });
this.render();
this.setupEvents();
this.dispatchEvent(new CustomEvent('config-changed', {
detail: this._config,
bubbles: true,
}));
}
generateHCL() {
let hcl = `provider "" {\n`;
hcl += ` region = ""\n}\n\n`;
for (const res of this._config.resources) {
hcl += `resource "" "" {\n`;
for (const [key, value] of Object.entries(res.config)) {
if (typeof value === 'string') {
hcl += ` = ""\n`;
} else if (typeof value === 'number') {
hcl += ` = \n`;
} else if (typeof value === 'boolean') {
hcl += ` = \n`;
}
}
hcl += `}\n\n`;
}
return hcl;
}
render() {
const resourceItems = this._config.resources.map((r, i) => `
""
`).join('');
this.shadowRoot.innerHTML = `
`;
}
setupEvents() {
const addBtn = this.shadowRoot.getElementById('addBtn');
const genBtn = this.shadowRoot.getElementById('generateBtn');
if (addBtn) {
addBtn.onclick = () => {
const type = this.shadowRoot.getElementById('resourceType').value;
const name = this.shadowRoot.getElementById('resourceName').value;
const defaults = {
aws_instance: { ami: 'ami-0abcdef1234567890', instance_type: 't3.micro' },
aws_s3_bucket: { bucket: `-bucket`, acl: 'private' },
aws_security_group: { name: `-sg`, description: 'Managed by Terraform' },
aws_rds_instance: { engine: 'postgres', instance_class: 'db.t3.micro' },
aws_lambda_function: { runtime: 'python3.12', handler: 'index.handler' },
};
this.addResource(type, name, defaults[type] || {});
};
}
this.shadowRoot.querySelectorAll('.remove-btn').forEach(btn => {
btn.onclick = () => {
const idx = parseInt(btn.dataset.index);
this._config.resources.splice(idx, 1);
this.render();
this.setupEvents();
};
});
}
}
customElements.define('terraform-editor', TerraformEditor);
CI/CD Pipeline ?????????????????? Web Components
????????????????????? CI/CD ?????????????????? build, test, publish components
# === CI/CD Pipeline ===
# 1. GitHub Actions workflow
cat > .github/workflows/web-components.yml << 'EOF'
name: Web Components CI/CD
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npm run lint
- run: npm run test
- run: npm run build
publish:
needs: test
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
registry-url: 'https://registry.npmjs.org'
- run: npm ci
- run: npm run build
- run: npm publish --access public
env:
NODE_AUTH_TOKEN: }
deploy-storybook:
needs: test
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npm run build-storybook
- uses: peaceiris/actions-gh-pages@v3
with:
github_token: }
publish_dir: ./storybook-static
EOF
# 2. Package.json
cat > package.json << 'EOF'
{
"name": "@myorg/infra-components",
"version": "1.0.0",
"type": "module",
"main": "dist/index.js",
"module": "dist/index.js",
"types": "dist/index.d.ts",
"files": ["dist"],
"scripts": {
"build": "vite build",
"test": "vitest run",
"lint": "eslint src/",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build"
},
"devDependencies": {
"vite": "^5.0.0",
"vitest": "^1.0.0",
"@open-wc/testing": "^4.0.0",
"eslint": "^8.0.0",
"@storybook/web-components-vite": "^8.0.0"
}
}
EOF
# 3. Vite config
cat > vite.config.js << 'EOF'
import { defineConfig } from 'vite';
export default defineConfig({
build: {
lib: {
entry: 'src/index.js',
formats: ['es'],
fileName: 'index',
},
rollupOptions: {
external: [],
},
},
});
EOF
echo "CI/CD pipeline configured"
Testing ????????? Quality Assurance
??????????????? Web Components
#!/usr/bin/env python3
# component_testing.py ??? Web Component Testing Strategy
import json
import logging
from typing import Dict, List
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("testing")
class ComponentTestingStrategy:
def __init__(self):
pass
def test_types(self):
return {
"unit_tests": {
"tool": "Vitest + @open-wc/testing",
"coverage": "Component logic, attribute handling, events",
"example": """
import { fixture, html, expect } from '@open-wc/testing';
describe('infra-resource-status', () => {
it('renders with attributes', async () => {
const el = await fixture(html`
`);
const shadow = el.shadowRoot;
expect(shadow.querySelector('.name').textContent).to.equal('web-server');
expect(shadow.querySelector('.status').textContent).to.include('running');
});
it('updates on attribute change', async () => {
const el = await fixture(html` `);
el.setAttribute('status', 'stopped');
await el.updateComplete;
expect(el.statusColor).to.equal('#ef4444');
});
});
""",
},
"visual_regression": {
"tool": "Playwright + Storybook",
"coverage": "Visual appearance across browsers",
},
"accessibility": {
"tool": "@open-wc/testing (a11y)",
"coverage": "ARIA roles, keyboard navigation, color contrast",
},
"integration": {
"tool": "Playwright",
"coverage": "Component interaction with IaC APIs",
},
}
strategy = ComponentTestingStrategy()
tests = strategy.test_types()
print("Web Component Testing Strategy:")
for name, info in tests.items():
print(f"\n {name}:")
print(f" Tool: {info['tool']}")
print(f" Coverage: {info['coverage']}")
Monitoring ????????? Observability
????????????????????????????????????????????? components
#!/usr/bin/env python3
# component_monitor.py ??? Web Component Usage Monitor
import json
import logging
from typing import Dict, List
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("monitor")
class ComponentMonitor:
def __init__(self):
pass
def dashboard(self):
return {
"component_usage": {
"infra-resource-status": {"instances": 450, "pages": 12, "avg_render_ms": 3.2},
"terraform-plan-viewer": {"instances": 85, "pages": 5, "avg_render_ms": 8.5},
"terraform-editor": {"instances": 30, "pages": 3, "avg_render_ms": 15.2},
"cost-dashboard": {"instances": 120, "pages": 8, "avg_render_ms": 5.1},
},
"performance": {
"bundle_size": "24 KB (gzipped)",
"first_render_p95": "12ms",
"memory_per_instance": "2.1 KB",
"lighthouse_score": 98,
},
"adoption": {
"teams_using": 8,
"projects": 15,
"npm_downloads_monthly": 2500,
"github_stars": 120,
},
"quality": {
"test_coverage": "92%",
"accessibility_score": "A",
"browser_support": "Chrome 90+, Firefox 90+, Safari 15+, Edge 90+",
"bugs_open": 3,
"bugs_closed_30d": 12,
},
}
monitor = ComponentMonitor()
dash = monitor.dashboard()
print("Web Components Dashboard:")
for comp, info in dash["component_usage"].items():
print(f" {comp}: {info['instances']} instances, {info['avg_render_ms']}ms render")
perf = dash["performance"]
print(f"\nPerformance: Bundle {perf['bundle_size']}, Render P95 {perf['first_render_p95']}")
adoption = dash["adoption"]
print(f"Adoption: {adoption['teams_using']} teams, {adoption['projects']} projects")
quality = dash["quality"]
print(f"Quality: {quality['test_coverage']} coverage, A11y {quality['accessibility_score']}")
FAQ ??????????????????????????????????????????
Q: Web Components ????????? React Components ???????????????????????????????????????????
A: Web Components ???????????? web standard (Custom Elements, Shadow DOM, HTML Templates) ????????????????????? browser ?????????????????? ????????????????????? framework ??????????????????????????? React, Vue, Angular, Svelte ???????????? vanilla JS ??????????????? Framework-agnostic, ??????????????? runtime dependency, native browser support ????????????????????? Ecosystem ????????????????????????, Developer experience ??????????????????????????? React, SSR ????????????????????????????????? React Components ?????????????????? React ecosystem ????????? JSX, virtual DOM, hooks, state management ??????????????? Ecosystem ?????????????????????, DX ??????, tooling ????????? ????????????????????? ????????????????????????????????? React ??????????????? ????????? Web Components ?????????????????? design systems ????????????????????? share ???????????? frameworks ????????? React ?????????????????? app ?????????????????? React ??????????????????????????????
Q: IaC Dashboard ????????????????????????????????? Web Components?
A: IaC tools ??????????????????????????? (Terraform, Pulumi, CloudFormation, Ansible) ?????????????????????????????????????????? frontend framework ????????????????????? Web Components ???????????? framework-agnostic ????????? infra-resource-status ???????????? terraform-plan-viewer ?????????????????? app ???????????????????????????????????? React, Vue ???????????? Angular ?????????????????????????????????????????? DevOps portals ????????????????????? internal tools ?????????????????? framework ????????????????????????, ??????????????? component library ?????????????????????????????? ?????????????????? project, Embed ?????? Backstage, Grafana panels ???????????? custom portals, ????????????????????? bundle React/Vue ???????????????????????? lightweight widgets ???????????????????????????????????? framework ??????????????? (???????????? React ????????? project) ???????????????????????????????????????????????? Web Components ????????? React components ????????????????????????
Q: Lit ????????? vanilla Web Components ??????????????????????????????????
A: Vanilla Web Components ??????????????? components ??????????????? (status badge, tooltip), ????????????????????? dependency ?????????, bundle size ??????????????????????????????, ???????????????????????? web standard ?????????????????? Lit (Google) ??????????????? components ????????????????????? (forms, editors, data grids), Reactive properties ?????????????????? UI ???????????????????????????, Template syntax ?????? (html tagged template), Decorators ?????? boilerplate, 5KB runtime ????????????????????? ???????????????????????????????????? Stencil (Ionic) compile ???????????? Web Components ????????? JSX, FAST (Microsoft) high-performance, Shoelace component library ???????????????????????? ??????????????? ??????????????????????????? Lit ???????????????????????? balance ????????????????????? DX ????????? bundle size ????????? component ????????????????????? ????????? vanilla ????????????
Q: Web Components ????????? Micro Frontends ?????????????????????????????????????????????????
A: Micro Frontends ????????? architecture pattern ???????????? frontend ???????????? independent, deployable units Web Components ????????????????????????????????? technology choices ?????????????????? implement Micro Frontends ??????????????? ??????????????? team ????????? framework ?????????????????????????????? (Team A ????????? React, Team B ????????? Vue) wrap ???????????? Web Component ???????????? compose ?????????????????????????????????????????? Shadow DOM ????????????????????? CSS conflict ????????????????????? micro frontends Deploy ?????????????????? update ????????????????????????????????? ???????????????????????? Shared state ????????????????????? micro frontends ????????????????????? (????????? Custom Events ???????????? shared store), Performance ????????? load ???????????? frameworks, Bundle size management ?????????????????? IaC dashboard ????????? Web Components-based micro frontends ?????? ??????????????? team (networking, compute, security) ??????????????? widgets ??????????????????????????? compose ?????? portal ???????????????
