diff --git a/.github/workflows/helm-test.yml b/.github/workflows/helm-test.yml new file mode 100644 index 00000000..10167a0f --- /dev/null +++ b/.github/workflows/helm-test.yml @@ -0,0 +1,30 @@ +name: Helm Tests + +on: + push: + branches: [main] + paths: + - 'charts/**' + - 'test/helm-test.sh' + pull_request: + branches: [main] + paths: + - 'charts/**' + - 'test/helm-test.sh' + workflow_dispatch: + +jobs: + helm-test: + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - uses: actions/checkout@v4 + + - name: Set up Helm + uses: azure/setup-helm@v4 + + - name: Install helm-unittest plugin + run: helm plugin install https://github.com/helm-unittest/helm-unittest.git + + - name: Run helm lint + unittest + run: ./test/helm-test.sh diff --git a/.github/workflows/publish-images.yml b/.github/workflows/publish-images.yml new file mode 100644 index 00000000..5ae79b6d --- /dev/null +++ b/.github/workflows/publish-images.yml @@ -0,0 +1,44 @@ +name: Build and Push Example Images + +on: + push: + branches: [main] + paths: + - 'examples/**' + - 'docker-compose/canary/**' + - '.github/workflows/publish-images.yml' + workflow_dispatch: + +# Only runs on the fork — skips silently on opensearch-project/observability-stack +jobs: + build: + if: github.repository == 'kylehounslow/observability-stack' + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + strategy: + matrix: + include: + - name: weather-agent + context: examples/plain-agents/weather-agent + - name: travel-planner + context: examples/plain-agents/multi-agent-planner/orchestrator + - name: events-agent + context: examples/plain-agents/multi-agent-planner/events-agent + - name: mcp-server + context: examples/plain-agents/multi-agent-planner/mcp-server + - name: canary + context: docker-compose/canary + steps: + - uses: actions/checkout@v4 + - uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - uses: docker/build-push-action@v6 + with: + context: ${{ matrix.context }} + push: true + tags: ghcr.io/${{ github.repository }}/${{ matrix.name }}:latest diff --git a/.gitignore b/.gitignore index 2ec88dbe..ee10f6a9 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,20 @@ node_modules dist build .DS_Store + +# Agent worktrees +.worktrees/ + +# Terraform +*.tfstate +*.tfstate.backup +.terraform/ +.terraform.lock.hcl +.terraform.tfstate.lock.info + +# Helm dependency artifacts (regenerated by `helm dependency build`) +charts/*/Chart.lock +charts/*/charts/*.tgz + +# Terraform plan files +*.plan diff --git a/AGENTS.md b/AGENTS.md index 9c15f30d..eec07c4a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -905,6 +905,38 @@ When creating examples or documentation, always reference the OpenTelemetry Gen- 6. **Commit**: Use descriptive commit messages 7. **Submit PR**: Follow CONTRIBUTING.md guidelines + +## Multi-Agent Development with Worktrees + +When multiple agents or sessions work on this repo simultaneously, each feature branch gets its own worktree for isolation. + +### Structure + +``` +observability-stack/ +├── .worktrees/ # gitignored — one per feature branch +│ ├── feat-self-monitoring/ +│ ├── feat-helm-charts/ +│ └── fix-docs/ +└── ... # main branch +``` + +### Usage + +```bash +# Create +mkdir -p .worktrees +git worktree add .worktrees/ + +# REQUIRED: Clean up after PR merge +git worktree remove .worktrees/ +git branch -d +``` + +**You MUST remove worktrees after their PR is merged.** Stale worktrees waste disk space and cause confusion about what work is active. + +**Terraform limitation:** Terraform state is local and lives in the main repo's `terraform/aws/` directory. It is NOT shared across worktrees. Only run `terraform plan/apply` from the main repo, never from a worktree. + ## Common Pitfalls to Avoid - ❌ Using `latest` image tags (use specific versions) diff --git a/charts/observability-stack/.helmignore b/charts/observability-stack/.helmignore new file mode 100644 index 00000000..a8aea9f3 --- /dev/null +++ b/charts/observability-stack/.helmignore @@ -0,0 +1,5 @@ +.DS_Store +.git +*.swp +*.bak +*.tmp diff --git a/charts/observability-stack/Chart.yaml b/charts/observability-stack/Chart.yaml new file mode 100644 index 00000000..aab8b244 --- /dev/null +++ b/charts/observability-stack/Chart.yaml @@ -0,0 +1,52 @@ +apiVersion: v2 +name: observability-stack +description: OpenTelemetry-native observability platform for microservices, web apps, and AI agents +type: application +version: 0.1.0 +appVersion: "3.6.0" + +home: https://github.com/opensearch-project/observability-stack +sources: + - https://github.com/opensearch-project/observability-stack + +maintainers: + - name: kylehounslow + url: https://github.com/kylehounslow + +keywords: + - opensearch + - observability + - opentelemetry + - data-prepper + - agent-tracing + +dependencies: + - name: opensearch + version: "3.5.0" + repository: "https://opensearch-project.github.io/helm-charts/" + condition: opensearch.enabled + + - name: opensearch-dashboards + version: "3.5.0" + repository: "https://opensearch-project.github.io/helm-charts/" + condition: opensearch-dashboards.enabled + + - name: data-prepper + version: "0.3.1" + repository: "https://opensearch-project.github.io/helm-charts/" + condition: data-prepper.enabled + + - name: opentelemetry-collector + version: "0.147.0" + repository: "https://open-telemetry.github.io/opentelemetry-helm-charts" + condition: opentelemetry-collector.enabled + + - name: prometheus + version: "28.13.0" + repository: "https://prometheus-community.github.io/helm-charts" + condition: prometheus.enabled + + - name: opentelemetry-demo + version: "0.40.5" + repository: "https://open-telemetry.github.io/opentelemetry-helm-charts" + condition: opentelemetry-demo.enabled diff --git a/charts/observability-stack/README.md b/charts/observability-stack/README.md new file mode 100644 index 00000000..d46c830c --- /dev/null +++ b/charts/observability-stack/README.md @@ -0,0 +1,199 @@ +# Observability Stack Helm Chart + +Umbrella Helm chart that deploys the full observability stack to Kubernetes. Wraps community subcharts (OpenSearch, Prometheus, OTel Collector, Data Prepper) with opinionated defaults and adds self-monitoring dashboards. + +## Components + +| Subchart | Source | Purpose | +|----------|--------|---------| +| `opensearch` | opensearch-project/helm-charts | Log and trace storage | +| `opensearch-dashboards` | opensearch-project/helm-charts | Web UI | +| `data-prepper` | opensearch-project/helm-charts | OTLP → OpenSearch pipeline | +| `opentelemetry-collector` | open-telemetry/helm-charts | Telemetry receiver and router | +| `prometheus` | prometheus-community/helm-charts | Metrics storage (OTLP + scrape) | + +Additional templates (not subcharts): +- `opensearch-exporter` — Prometheus exporter for OpenSearch cluster metrics +- `init-dashboards-job` — Post-install hook that creates index patterns, dashboards, saved queries +- `opensearch-credentials-secret` — Shared credentials secret + +## Install + +```bash +cd charts/observability-stack +helm dependency build +helm install obs-stack . -n observability-stack --create-namespace +``` + +For EKS with ALB ingress, use the values override: +```bash +helm install obs-stack . -n observability-stack --create-namespace -f ../../terraform/aws/values-eks.yaml +``` + +Or use Terraform (recommended) — see `terraform/aws/README.md`. + +## Upgrading + +The init job (dashboard/index pattern setup) runs as a post-install/post-upgrade hook. It installs pip packages and takes 3-5 minutes, which often exceeds helm's default timeout. + +**Recommended upgrade workflow:** +```bash +# 1. Deploy chart changes (skip hooks to avoid timeout) +helm upgrade obs-stack . -n observability-stack -f ../../terraform/aws/values-eks.yaml --no-hooks + +# 2. If dashboard or init script changed, trigger the job manually: +kubectl delete job obs-stack-observability-stack-init-dashboards -n observability-stack 2>/dev/null +helm get hooks obs-stack -n observability-stack | kubectl apply -n observability-stack -f - +kubectl wait --for=condition=complete job/obs-stack-observability-stack-init-dashboards -n observability-stack --timeout=10m +kubectl logs -n observability-stack job/obs-stack-observability-stack-init-dashboards --tail=30 +``` + +If only `values.yaml` scrape configs changed (no dashboard changes), step 2 is not needed — but you may need to restart Prometheus to pick up the new configmap: +```bash +kubectl rollout restart deployment obs-stack-prometheus-server -n observability-stack +``` + +## Self-Monitoring Dashboards + +Three dashboards are auto-created by the init job from YAML config files in `files/`: + +| Dashboard | Panels | File | +|-----------|--------|------| +| Kubernetes Cluster Health | 8 | `files/dashboard-k8s-cluster-health.yaml` | +| Observability Pipeline Health | 24 | `files/dashboard-pipeline-health.yaml` | +| OpenSearch Cluster Health | 10 | `files/dashboard-opensearch-health.yaml` | + +**Adding a new dashboard:** +1. Create `files/dashboard-my-thing.yaml` (see existing files for format) +2. Add it to `templates/init-dashboards-configmap.yaml` +3. Add one line to `main()` in `files/init-opensearch-dashboards.py`: + ```python + create_promql_dashboard_from_yaml(workspace_id, "/config/dashboard-my-thing.yaml") + ``` + +**Dashboard YAML format:** +```yaml +dashboard: + id: my-dashboard-id + title: My Dashboard + description: What this monitors + +panels: + - id: panel-unique-id + title: "Panel Title" + query: "rate(some_metric_total[5m])" + chartType: line +``` + +**Syncing with docker-compose:** The docker-compose init script and dashboard YAMLs (`docker-compose/opensearch-dashboards/`) are the source of truth. The helm versions in `files/` should be kept in sync. The only helm-specific addition is the K8s Cluster Health dashboard (not applicable to docker-compose) and the `BASE_URL` env var override in the init script (line 11). + +## Prometheus Scrape Targets + +Configured via `scrapeConfigs` in `values.yaml`. Default K8s scrape jobs are disabled (saves ~60k series). Active targets: + +| Job | Target | Interval | +|-----|--------|----------| +| `prometheus` | localhost:9090 | 60s | +| `otel-collector` | ``-opentelemetry-collector:8888 | 10s | +| `opensearch` | ``-observability-stack-opensearch-exporter:9114 | 30s | +| `data-prepper` | ``-data-prepper:4900 | 30s | +| `node-exporter` | auto-discovered via kubernetes_sd | 60s | +| `kube-state-metrics` | auto-discovered via kubernetes_sd | 60s | + +> **Note:** Targets use the helm release name as prefix. The values in `values.yaml` are hardcoded to `obs-stack-*` — update them if you change the release name. + +## Sizing Guide + +The default values are tuned for development/demo (single-node OpenSearch, minimal resources). For production or enterprise-scale deployments, adjust the following knobs. + +### OpenSearch Cluster + +| Knob | Default | Production Guidance | +|------|---------|---------------------| +| `opensearch.replicas` | `1` | 3+ data nodes minimum for HA | +| `opensearch.singleNode` | `true` | Set `false` for multi-node | +| `opensearch.resources.requests.memory` | `2Gi` | 8–64Gi per node (JVM gets 50%) | +| `opensearch.persistence.size` | `8Gi` | Size per formula below | +| `opensearch.extraEnvs[OPENSEARCH_JAVA_OPTS]` | `-Xms1g -Xmx1g` | 50% of node RAM, max 31g | + +**Storage formula:** +``` +storage_per_node = (daily_ingest_GB × 1.45 × (replicas + 1) × retention_days) / node_count +``` +The 1.45x multiplier accounts for indexing overhead (10%), OS reserved space for merges (20%), filesystem overhead (5%), and node failure buffer (10%). + +**Shard sizing:** +- Logs/traces (write-heavy): 30–50 GB per primary shard +- Search (latency-sensitive): 10–30 GB per primary shard +- Total shards should be a multiple of data node count +- Max 25 shards per GB of JVM heap + +Shard count is configurable per Data Prepper pipeline sink via `number_of_shards` and `number_of_replicas` (commented out in `values.yaml`). + +### Data Prepper Pipeline Tuning + +| Knob | Default | Description | +|------|---------|-------------| +| `data-prepper.pipelineConfig.config.otel-logs-pipeline.workers` | `5` | Parallel log processing threads | +| `...opensearch.number_of_shards` | (OS default: 1) | Primary shards per index | +| `...opensearch.number_of_replicas` | (OS default: 1) | Replica shards per primary | +| `...opensearch.bulk_size` | `5` (MiB) | Bulk request size to OpenSearch | + +### Prometheus + +| Knob | Default | Description | +|------|---------|-------------| +| `prometheus.server.retention` | `15d` | How long metrics are kept | +| `prometheus.server.persistentVolume.enabled` | `false` | Enable for production | +| `prometheus.server.persistentVolume.size` | `8Gi` | Disk for metrics TSDB | + +### Quick Reference: Sizing Profiles + +| Profile | OS Nodes | OS Memory | OS Disk | Prometheus Retention | +|---------|----------|-----------|---------|---------------------| +| **Dev/Demo** (default) | 1 | 2Gi | 8Gi | 15d | +| **Small team** (~10 GB/day) | 3 | 8Gi | 100Gi | 30d | +| **Enterprise** (~100 GB/day) | 6+ | 32Gi | 500Gi+ | 90d | + +Sources: [OpenSearch shard sizing](https://opensearch.org/blog/optimize-opensearch-index-shard-size/), [AWS sizing guide](https://docs.aws.amazon.com/prescriptive-guidance/latest/opensearch-service-migration/sizing.html), [AWS shard best practices](https://docs.aws.amazon.com/opensearch-service/latest/developerguide/bp-sharding.html) + +## Key Values + +See `values.yaml` for all options. Notable settings: + +```yaml +# Credentials (update opensearchPassword before any real deployment) +opensearchUsername: "admin" +opensearchPassword: "My_password_123!@#" + +# Data Prepper metrics port (must be in ports list for Prometheus to scrape) +data-prepper: + ports: + - name: metrics + port: 4900 + +# Disable noisy K8s scrape defaults +prometheus: + scrapeConfigs: + kubernetes-api-servers: { enabled: false } + # ... etc +``` + +## OpenTelemetry Demo (Optional) + +The [OpenTelemetry Demo](https://opentelemetry.io/docs/demo/) is available as an optional subchart. It deploys a full microservices e-commerce app (20+ services) that generates realistic telemetry — useful for load testing and showcasing the stack. + +Disabled by default (~2GB additional memory required). + +**Enable:** +```bash +helm upgrade obs-stack . -n observability-stack -f ../../terraform/aws/values-eks.yaml \ + --set opentelemetry-demo.enabled=true --no-hooks +``` + +**Disable:** +```bash +helm upgrade obs-stack . -n observability-stack -f ../../terraform/aws/values-eks.yaml --no-hooks +``` + +All bundled backends (Jaeger, Grafana, Prometheus, OpenSearch) in the demo chart are disabled — demo services send telemetry to our OTel Collector. No duplicate infrastructure. diff --git a/charts/observability-stack/docs/local-tls.md b/charts/observability-stack/docs/local-tls.md new file mode 100644 index 00000000..0984abb8 --- /dev/null +++ b/charts/observability-stack/docs/local-tls.md @@ -0,0 +1,101 @@ +# Local Development with TLS + +Test the full Gateway API + TLS flow locally on kind without a cloud provider. + +## Prerequisites + +- [kind](https://kind.sigs.k8s.io/) cluster running +- [Envoy Gateway](https://gateway.envoyproxy.io/) installed +- [mkcert](https://github.com/FiloSottile/mkcert) for locally-trusted certificates + +## Setup + +### 1. Install mkcert and create a local CA + +```bash +brew install mkcert # macOS +mkcert -install # adds local CA to system trust store (needs sudo on macOS) +``` + +This creates a Certificate Authority on your machine. Any cert signed by it +will be trusted by your browser and curl — no warnings, green lock. + +### 2. Generate a certificate + +```bash +mkcert dashboards.local localhost 127.0.0.1 +``` + +Creates `dashboards.local+2.pem` (cert) and `dashboards.local+2-key.pem` (key) +in the current directory, valid for all three names. + +### 3. Add DNS entry + +```bash +echo "127.0.0.1 dashboards.local" | sudo tee -a /etc/hosts +``` + +### 4. Install Envoy Gateway + +```bash +helm install eg oci://docker.io/envoyproxy/gateway-helm \ + --version v1.3.2 \ + -n envoy-gateway-system --create-namespace + +kubectl apply -f - <85% indicates need to scale + language: PROMQL + query: | + 100 * elasticsearch_jvm_memory_used_bytes{area="heap"} / elasticsearch_jvm_memory_max_bytes{area="heap"} + + - id: os_thread_pool_rejections + title: "OpenSearch Thread Pool Rejections" + description: Rejected requests per second — non-zero means OpenSearch is overloaded + language: PROMQL + query: | + rate(elasticsearch_thread_pool_rejected_count[5m]) + + - id: os_active_searches + title: "OpenSearch Active Searches" + description: Currently executing search queries + language: PROMQL + query: | + elasticsearch_indices_search_query_current + + - id: os_search_latency + title: "OpenSearch Search Latency (sec/query)" + description: Average time per search query + language: PROMQL + query: | + rate(elasticsearch_indices_search_query_time_seconds_total[5m]) / rate(elasticsearch_indices_search_query_total[5m]) + + # --- OTel Collector --- + - id: otel_spans_dropped + title: "OTel Collector Spans Dropped/sec" + description: Failed span exports — non-zero indicates backpressure or downstream failure + language: PROMQL + query: | + rate(otelcol_exporter_send_failed_spans_total[5m]) + + - id: otel_batch_timeout_sends + title: "OTel Batch Timeout Sends/sec" + description: Batches sent due to timeout rather than reaching batch size — high rate means low throughput + language: PROMQL + query: | + rate(otelcol_processor_batch_timeout_trigger_send_total[5m]) + + # --- Prometheus --- + - id: prom_query_latency_p99 + title: "Prometheus Query Latency P99" + description: 99th percentile query duration — degrades under concurrent PromQL load + language: PROMQL + query: | + histogram_quantile(0.99, rate(prometheus_http_request_duration_seconds_bucket{handler="/api/v1/query"}[5m])) + + - id: prom_range_query_latency_p99 + title: "Prometheus Range Query Latency P99" + description: 99th percentile range query duration — expensive for long time ranges + language: PROMQL + query: | + histogram_quantile(0.99, rate(prometheus_http_request_duration_seconds_bucket{handler="/api/v1/query_range"}[5m])) + + - id: prom_active_series + title: "Prometheus Active Time Series" + description: Total active time series — drives memory usage + language: PROMQL + query: | + prometheus_tsdb_head_series + + - id: prom_ingestion_rate + title: "Prometheus Sample Ingestion Rate" + description: Samples appended per second + language: PROMQL + query: | + rate(prometheus_tsdb_head_samples_appended_total[5m]) + + # --- Data Prepper --- + - id: dp_buffer_capacity_used + title: "Data Prepper Buffer Capacity Used" + description: Combined buffer usage across all pipelines — approaching max means backpressure + language: PROMQL + query: | + otlp_pipeline_BlockingBuffer_capacityUsed + otel_logs_pipeline_BlockingBuffer_capacityUsed + otel_traces_pipeline_BlockingBuffer_capacityUsed + + - id: dp_bulk_write_errors + title: "Data Prepper Bulk Write Errors/sec" + description: OpenSearch bulk request errors from Data Prepper + language: PROMQL + query: | + sum(rate(otel_logs_pipeline_opensearch_bulkRequestErrors_total[5m])) + sum(rate(traces_raw_pipeline_opensearch_bulkRequestErrors_total[5m])) diff --git a/charts/observability-stack/files/saved-queries-traces.yaml b/charts/observability-stack/files/saved-queries-traces.yaml new file mode 100644 index 00000000..9ee6ec3e --- /dev/null +++ b/charts/observability-stack/files/saved-queries-traces.yaml @@ -0,0 +1,93 @@ +# Saved queries for OpenSearch Dashboards +# These queries are automatically created during initialization +# and provide quick access to common agent observability patterns + +queries: + - id: all_agent_invocations + title: All agent invocations + description: Find all agent invocation spans + language: PPL + query: | + source=otel-v1-apm-span-* + | WHERE `attributes.gen_ai.operation.name` = 'invoke_agent' + + - id: tool_executions + title: Tool executions + description: Find all tool execution spans + language: PPL + query: | + source=otel-v1-apm-span-* + | WHERE `attributes.gen_ai.operation.name` = 'execute_tool' + + - id: high_token_usage + title: High token usage + description: Find spans with high token usage (>1000 tokens) + language: PPL + query: | + source=otel-v1-apm-span-* + | WHERE `attributes.gen_ai.usage.input_tokens` + `attributes.gen_ai.usage.output_tokens` > 1000 + + - id: error_spans + title: Error spans + description: Find spans with errors + language: PPL + query: | + source=otel-v1-apm-span-* + | WHERE `status.code` = 2 + + - id: slow_operations + title: Slow operations + description: Find operations taking longer than 5 seconds + language: PPL + query: | + source=otel-v1-apm-span-* + | WHERE `durationInNanos` > 5000000000 + + - id: agent_by_model + title: LLM requests by model + description: Count LLM spans grouped by model + language: PPL + query: | + source=otel-v1-apm-span-* + | WHERE NOT isnull(`attributes.gen_ai.request.model`) AND NOT isnull(`traceId`) + | stats count() by `attributes.gen_ai.request.model` + + - id: tool_usage_stats + title: Tool usage statistics + description: Count tool execution spans by tool name + language: PPL + query: | + source=otel-v1-apm-span-* + | WHERE NOT isnull(`attributes.gen_ai.tool.name`) AND NOT isnull(`traceId`) + | stats count() by `attributes.gen_ai.tool.name` + + - id: token_usage_by_agent + title: Token usage by agent + description: Sum token usage from spans grouped by agent name + language: PPL + query: | + source=otel-v1-apm-span-* + | WHERE NOT isnull(`attributes.gen_ai.agent.name`) AND NOT isnull(`traceId`) + | stats sum(`attributes.gen_ai.usage.input_tokens`) as input_tokens, + sum(`attributes.gen_ai.usage.output_tokens`) as output_tokens + by `attributes.gen_ai.agent.name` + + - id: token_usage_by_model + title: Token usage by model + description: Sum token usage from spans grouped by model name + language: PPL + query: | + source=otel-v1-apm-span-* + | WHERE NOT isnull(`attributes.gen_ai.request.model`) AND NOT isnull(`traceId`) + | stats sum(`attributes.gen_ai.usage.input_tokens`) as input_tokens, + sum(`attributes.gen_ai.usage.output_tokens`) as output_tokens + by `attributes.gen_ai.request.model` + + - id: agent_operation_names + title: Agent operations used by services + description: Agent operations used by services + language: PPL + query: | + source=otel-v1-apm-span-* + | WHERE NOT isnull(`attributes.gen_ai.operation.name`) + | stats count() as operations by serviceName, `attributes.gen_ai.operation.name` diff --git a/charts/observability-stack/templates/NOTES.txt b/charts/observability-stack/templates/NOTES.txt new file mode 100644 index 00000000..89e75f72 --- /dev/null +++ b/charts/observability-stack/templates/NOTES.txt @@ -0,0 +1,26 @@ +🚀 Observability Stack deployed! + +Access OpenSearch Dashboards: + + kubectl port-forward -n {{ .Release.Namespace }} svc/{{ .Release.Name }}-opensearch-dashboards 5601:5601 + + Then open: http://localhost:5601 + Username: {{ .Values.opensearchUsername }} + Password: {{ .Values.opensearchPassword }} + +Send telemetry: + + kubectl port-forward -n {{ .Release.Namespace }} svc/{{ .Release.Name }}-opentelemetry-collector 4317:4317 4318:4318 + + OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317 + +{{- if .Values.gateway.enabled }} + +Gateway API ({{ .Values.gateway.provider }}): + + Gateway: kubectl get gateway -n {{ .Release.Namespace }} + HTTPRoute: kubectl get httproute -n {{ .Release.Namespace }} + {{- if .Values.gateway.host }} + Host: {{ .Values.gateway.host }} + {{- end }} +{{- end }} diff --git a/charts/observability-stack/templates/_helpers.tpl b/charts/observability-stack/templates/_helpers.tpl new file mode 100644 index 00000000..f4bfe253 --- /dev/null +++ b/charts/observability-stack/templates/_helpers.tpl @@ -0,0 +1,31 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "observability-stack.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +*/}} +{{- define "observability-stack.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "observability-stack.labels" -}} +helm.sh/chart: {{ include "observability-stack.name" . }}-{{ .Chart.Version }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +app.kubernetes.io/part-of: observability-stack +{{- end }} diff --git a/charts/observability-stack/templates/examples.yaml b/charts/observability-stack/templates/examples.yaml new file mode 100644 index 00000000..9499dce1 --- /dev/null +++ b/charts/observability-stack/templates/examples.yaml @@ -0,0 +1,209 @@ +{{- if .Values.examples.enabled }} +# MCP Server +apiVersion: apps/v1 +kind: Deployment +metadata: + name: example-mcp-server + labels: + app: example-mcp-server +spec: + replicas: 1 + selector: + matchLabels: + app: example-mcp-server + template: + metadata: + labels: + app: example-mcp-server + spec: + containers: + - name: mcp-server + image: {{ .Values.examples.mcpServer.image }} + imagePullPolicy: {{ .Values.examples.imagePullPolicy | default "IfNotPresent" }} + ports: + - containerPort: 8003 + env: + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: "http://{{ .Release.Name }}-opentelemetry-collector:4317" + resources: + limits: + memory: "128Mi" +--- +apiVersion: v1 +kind: Service +metadata: + name: mcp-server +spec: + selector: + app: example-mcp-server + ports: + - port: 8003 + targetPort: 8003 +--- +# Weather Agent +apiVersion: apps/v1 +kind: Deployment +metadata: + name: example-weather-agent + labels: + app: example-weather-agent +spec: + replicas: 1 + selector: + matchLabels: + app: example-weather-agent + template: + metadata: + labels: + app: example-weather-agent + spec: + containers: + - name: weather-agent + image: {{ .Values.examples.weatherAgent.image }} + imagePullPolicy: {{ .Values.examples.imagePullPolicy | default "IfNotPresent" }} + ports: + - containerPort: 8000 + env: + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: "http://{{ .Release.Name }}-opentelemetry-collector:4317" + - name: MCP_SERVER_URL + value: "http://mcp-server:8003" + resources: + limits: + memory: "200Mi" +--- +apiVersion: v1 +kind: Service +metadata: + name: weather-agent +spec: + selector: + app: example-weather-agent + ports: + - port: 8000 + targetPort: 8000 +--- +# Events Agent +apiVersion: apps/v1 +kind: Deployment +metadata: + name: example-events-agent + labels: + app: example-events-agent +spec: + replicas: 1 + selector: + matchLabels: + app: example-events-agent + template: + metadata: + labels: + app: example-events-agent + spec: + containers: + - name: events-agent + image: {{ .Values.examples.eventsAgent.image }} + imagePullPolicy: {{ .Values.examples.imagePullPolicy | default "IfNotPresent" }} + ports: + - containerPort: 8002 + env: + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: "http://{{ .Release.Name }}-opentelemetry-collector:4317" + - name: MCP_SERVER_URL + value: "http://mcp-server:8003" + resources: + limits: + memory: "128Mi" +--- +apiVersion: v1 +kind: Service +metadata: + name: events-agent +spec: + selector: + app: example-events-agent + ports: + - port: 8002 + targetPort: 8002 +--- +# Travel Planner (Orchestrator) +apiVersion: apps/v1 +kind: Deployment +metadata: + name: example-travel-planner + labels: + app: example-travel-planner +spec: + replicas: 1 + selector: + matchLabels: + app: example-travel-planner + template: + metadata: + labels: + app: example-travel-planner + spec: + containers: + - name: travel-planner + image: {{ .Values.examples.travelPlanner.image }} + imagePullPolicy: {{ .Values.examples.imagePullPolicy | default "IfNotPresent" }} + ports: + - containerPort: 8000 + env: + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: "http://{{ .Release.Name }}-opentelemetry-collector:4317" + - name: WEATHER_AGENT_URL + value: "http://weather-agent:8000" + - name: EVENTS_AGENT_URL + value: "http://events-agent:8002" + - name: MCP_SERVER_URL + value: "http://mcp-server:8003" + resources: + limits: + memory: "128Mi" +--- +apiVersion: v1 +kind: Service +metadata: + name: travel-planner +spec: + selector: + app: example-travel-planner + ports: + - port: 8000 + targetPort: 8000 +--- +# Canary - periodically invokes travel-planner +apiVersion: apps/v1 +kind: Deployment +metadata: + name: example-canary + labels: + app: example-canary +spec: + replicas: 1 + selector: + matchLabels: + app: example-canary + template: + metadata: + labels: + app: example-canary + spec: + containers: + - name: canary + image: {{ .Values.examples.canary.image }} + imagePullPolicy: {{ .Values.examples.imagePullPolicy | default "IfNotPresent" }} + env: + - name: TRAVEL_PLANNER_URL + value: "http://travel-planner:8000" + - name: WEATHER_AGENT_URL + value: "http://weather-agent:8000" + - name: EVENTS_AGENT_URL + value: "http://events-agent:8002" + - name: CANARY_INTERVAL + value: {{ .Values.examples.canary.interval | default "120" | quote }} + resources: + limits: + memory: "100Mi" +{{- end }} diff --git a/charts/observability-stack/templates/gateway.yaml b/charts/observability-stack/templates/gateway.yaml new file mode 100644 index 00000000..38b9112a --- /dev/null +++ b/charts/observability-stack/templates/gateway.yaml @@ -0,0 +1,48 @@ +{{- if .Values.gateway.enabled }} +apiVersion: gateway.networking.k8s.io/v1 +kind: Gateway +metadata: + name: {{ include "observability-stack.fullname" . }}-gateway + labels: + {{- include "observability-stack.labels" . | nindent 4 }} + {{- with .Values.gateway.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + gatewayClassName: {{ .Values.gateway.className }} + listeners: + - name: https + port: 443 + protocol: HTTPS + {{- if .Values.gateway.host }} + hostname: {{ .Values.gateway.host }} + {{- end }} + tls: + mode: Terminate + {{- if and (ne .Values.gateway.provider "aws") .Values.gateway.tls }} + certificateRefs: + - name: {{ .Values.gateway.tls.secretName | default (printf "%s-dashboards-tls" (include "observability-stack.fullname" .)) }} + {{- end }} + allowedRoutes: + namespaces: + from: Same +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: {{ include "observability-stack.fullname" . }}-dashboards + labels: + {{- include "observability-stack.labels" . | nindent 4 }} +spec: + parentRefs: + - name: {{ include "observability-stack.fullname" . }}-gateway + {{- if .Values.gateway.host }} + hostnames: + - {{ .Values.gateway.host }} + {{- end }} + rules: + - backendRefs: + - name: {{ .Release.Name }}-opensearch-dashboards + port: 5601 +{{- end }} diff --git a/charts/observability-stack/templates/init-dashboards-configmap.yaml b/charts/observability-stack/templates/init-dashboards-configmap.yaml new file mode 100644 index 00000000..63e179ef --- /dev/null +++ b/charts/observability-stack/templates/init-dashboards-configmap.yaml @@ -0,0 +1,29 @@ +{{- if index .Values "opensearch-dashboards" "enabled" }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "observability-stack.fullname" . }}-init-script + labels: + {{- include "observability-stack.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": post-install,post-upgrade + "helm.sh/hook-weight": "5" + "helm.sh/hook-delete-policy": before-hook-creation +data: + init-opensearch-dashboards.py: | +{{ .Files.Get "files/init-opensearch-dashboards.py" | indent 4 }} + saved-queries-traces.yaml: | +{{ .Files.Get "files/saved-queries-traces.yaml" | indent 4 }} + saved-queries-metrics.yaml: | +{{ .Files.Get "files/saved-queries-metrics.yaml" | indent 4 }} + saved-queries-self-monitoring.yaml: | +{{ .Files.Get "files/saved-queries-self-monitoring.yaml" | indent 4 }} + dashboard-k8s-cluster-health.yaml: | +{{ .Files.Get "files/dashboard-k8s-cluster-health.yaml" | indent 4 }} + dashboard-pipeline-health.yaml: | +{{ .Files.Get "files/dashboard-pipeline-health.yaml" | indent 4 }} + dashboard-opensearch-health.yaml: | +{{ .Files.Get "files/dashboard-opensearch-health.yaml" | indent 4 }} +binaryData: + architecture.png: {{ .Files.Get "files/architecture.png" | b64enc }} +{{- end }} diff --git a/charts/observability-stack/templates/init-dashboards-job.yaml b/charts/observability-stack/templates/init-dashboards-job.yaml new file mode 100644 index 00000000..3c957106 --- /dev/null +++ b/charts/observability-stack/templates/init-dashboards-job.yaml @@ -0,0 +1,56 @@ +{{- if index .Values "opensearch-dashboards" "enabled" }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "observability-stack.fullname" . }}-init-dashboards + labels: + {{- include "observability-stack.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": post-install,post-upgrade + "helm.sh/hook-weight": "10" + "helm.sh/hook-delete-policy": before-hook-creation +spec: + backoffLimit: 5 + template: + metadata: + labels: + app.kubernetes.io/name: init-dashboards + spec: + restartPolicy: OnFailure + containers: + - name: init-dashboards + image: python:3.12-slim + command: + - /bin/sh + - -c + - | + pip install -q requests pyyaml && python /scripts/init-opensearch-dashboards.py + env: + - name: OPENSEARCH_USER + valueFrom: + secretKeyRef: + name: {{ include "observability-stack.fullname" . }}-opensearch-credentials + key: username + - name: OPENSEARCH_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "observability-stack.fullname" . }}-opensearch-credentials + key: password + - name: BASE_URL + value: "http://{{ .Release.Name }}-opensearch-dashboards:5601" + - name: PROMETHEUS_HOST + value: "{{ .Release.Name }}-prometheus-server" + - name: PROMETHEUS_PORT + value: "80" + - name: OPENSEARCH_ENDPOINT + value: "https://opensearch-cluster-master:9200" + volumeMounts: + - name: init-script + mountPath: /scripts + - name: init-script + mountPath: /config + volumes: + - name: init-script + configMap: + name: {{ include "observability-stack.fullname" . }}-init-script +{{- end }} diff --git a/charts/observability-stack/templates/opensearch-credentials-secret.yaml b/charts/observability-stack/templates/opensearch-credentials-secret.yaml new file mode 100644 index 00000000..a7d6e4bc --- /dev/null +++ b/charts/observability-stack/templates/opensearch-credentials-secret.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "observability-stack.fullname" . }}-opensearch-credentials + labels: + {{- include "observability-stack.labels" . | nindent 4 }} +type: Opaque +stringData: + username: {{ .Values.opensearchUsername | default "admin" | quote }} + password: {{ .Values.opensearchPassword | quote }} diff --git a/charts/observability-stack/templates/opensearch-exporter.yaml b/charts/observability-stack/templates/opensearch-exporter.yaml new file mode 100644 index 00000000..6343180a --- /dev/null +++ b/charts/observability-stack/templates/opensearch-exporter.yaml @@ -0,0 +1,65 @@ +{{- if .Values.opensearchExporter.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "observability-stack.fullname" . }}-opensearch-exporter + labels: + {{- include "observability-stack.labels" . | nindent 4 }} + app.kubernetes.io/component: opensearch-exporter +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/component: opensearch-exporter + template: + metadata: + labels: + app.kubernetes.io/component: opensearch-exporter + spec: + containers: + - name: opensearch-exporter + image: "{{ .Values.opensearchExporter.image.repository }}:{{ .Values.opensearchExporter.image.tag }}" + args: + - --es.uri=https://opensearch-cluster-master:9200 + - --es.ssl-skip-verify + - --es.all + - --es.indices + - --es.shards + env: + - name: ES_USERNAME + value: {{ .Values.opensearchUsername | default "admin" | quote }} + - name: ES_PASSWORD + value: {{ .Values.opensearchPassword | default "My_password_123!@#" | quote }} + ports: + - containerPort: 9114 + name: metrics + resources: + limits: + memory: "128Mi" + cpu: "100m" + livenessProbe: + httpGet: + path: /healthz + port: 9114 + initialDelaySeconds: 10 + readinessProbe: + httpGet: + path: /healthz + port: 9114 + initialDelaySeconds: 10 +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "observability-stack.fullname" . }}-opensearch-exporter + labels: + {{- include "observability-stack.labels" . | nindent 4 }} + app.kubernetes.io/component: opensearch-exporter +spec: + selector: + app.kubernetes.io/component: opensearch-exporter + ports: + - port: 9114 + targetPort: 9114 + name: metrics +{{- end }} diff --git a/charts/observability-stack/tests/credentials_test.yaml b/charts/observability-stack/tests/credentials_test.yaml new file mode 100644 index 00000000..98ea1571 --- /dev/null +++ b/charts/observability-stack/tests/credentials_test.yaml @@ -0,0 +1,41 @@ +suite: opensearch credentials secret +templates: + - templates/opensearch-credentials-secret.yaml +tests: + - it: should render with default credentials + asserts: + - isKind: + of: Secret + - equal: + path: stringData.username + value: admin + - equal: + path: stringData.password + value: "My_password_123!@#" + + - it: should use custom credentials + set: + opensearchUsername: myuser + opensearchPassword: "S3cret!" + asserts: + - equal: + path: stringData.username + value: myuser + - equal: + path: stringData.password + value: "S3cret!" + + - it: should include standard labels + asserts: + - exists: + path: metadata.labels["helm.sh/chart"] + - exists: + path: metadata.labels["app.kubernetes.io/managed-by"] + + - it: should respect fullnameOverride + set: + fullnameOverride: custom + asserts: + - equal: + path: metadata.name + value: custom-opensearch-credentials diff --git a/charts/observability-stack/tests/examples_test.yaml b/charts/observability-stack/tests/examples_test.yaml new file mode 100644 index 00000000..0d69259f --- /dev/null +++ b/charts/observability-stack/tests/examples_test.yaml @@ -0,0 +1,69 @@ +suite: example agents +templates: + - templates/examples.yaml +tests: + - it: should render all example deployments and services by default + asserts: + - hasDocuments: + count: 9 # 4 services + 5 deployments + - containsDocument: + kind: Deployment + apiVersion: apps/v1 + name: example-weather-agent + any: true + - containsDocument: + kind: Deployment + apiVersion: apps/v1 + name: example-events-agent + any: true + - containsDocument: + kind: Deployment + apiVersion: apps/v1 + name: example-travel-planner + any: true + - containsDocument: + kind: Deployment + apiVersion: apps/v1 + name: example-mcp-server + any: true + - containsDocument: + kind: Deployment + apiVersion: apps/v1 + name: example-canary + any: true + - containsDocument: + kind: Service + apiVersion: v1 + name: weather-agent + any: true + + - it: should not render when disabled + set: + examples.enabled: false + asserts: + - hasDocuments: + count: 0 + + - it: should set OTEL_EXPORTER_OTLP_ENDPOINT on weather-agent + documentSelector: + path: metadata.name + value: example-weather-agent + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: OTEL_EXPORTER_OTLP_ENDPOINT + value: "http://RELEASE-NAME-opentelemetry-collector:4317" + + - it: should set canary interval from values + set: + examples.canary.interval: "60" + documentSelector: + path: metadata.name + value: example-canary + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: CANARY_INTERVAL + value: "60" diff --git a/charts/observability-stack/tests/gateway_test.yaml b/charts/observability-stack/tests/gateway_test.yaml new file mode 100644 index 00000000..1925cc1b --- /dev/null +++ b/charts/observability-stack/tests/gateway_test.yaml @@ -0,0 +1,121 @@ +suite: gateway +templates: + - templates/gateway.yaml +tests: + - it: should not render when disabled + asserts: + - hasDocuments: + count: 0 + + - it: should render Gateway and HTTPRoute when enabled + set: + gateway: + enabled: true + provider: envoy + className: eg + host: dashboards.example.com + tls: + secretName: my-tls + asserts: + - hasDocuments: + count: 2 + - containsDocument: + kind: Gateway + apiVersion: gateway.networking.k8s.io/v1 + any: true + - containsDocument: + kind: HTTPRoute + apiVersion: gateway.networking.k8s.io/v1 + any: true + + - it: should set gatewayClassName + set: + gateway: + enabled: true + provider: envoy + className: eg + documentIndex: 0 + asserts: + - equal: + path: spec.gatewayClassName + value: eg + + - it: should set hostname on Gateway and HTTPRoute + set: + gateway: + enabled: true + provider: envoy + className: eg + host: dashboards.example.com + asserts: + - equal: + path: spec.listeners[0].hostname + value: dashboards.example.com + documentIndex: 0 + - contains: + path: spec.hostnames + content: dashboards.example.com + documentIndex: 1 + + - it: should include certificateRefs for envoy with TLS + set: + gateway: + enabled: true + provider: envoy + className: eg + tls: + secretName: my-cert + documentIndex: 0 + asserts: + - equal: + path: spec.listeners[0].tls.certificateRefs[0].name + value: my-cert + + - it: should not include certificateRefs for aws provider + set: + gateway: + enabled: true + provider: aws + className: amazon-vpc-lattice + documentIndex: 0 + asserts: + - notExists: + path: spec.listeners[0].tls.certificateRefs + + - it: should set TLS terminate mode + set: + gateway: + enabled: true + provider: envoy + className: eg + documentIndex: 0 + asserts: + - equal: + path: spec.listeners[0].tls.mode + value: Terminate + + - it: should route to opensearch-dashboards on port 5601 + set: + gateway: + enabled: true + provider: envoy + className: eg + documentIndex: 1 + asserts: + - equal: + path: spec.rules[0].backendRefs[0].port + value: 5601 + + - it: should apply custom annotations + set: + gateway: + enabled: true + provider: aws + className: amazon-vpc-lattice + annotations: + application-networking.k8s.aws/certificate-arn: "arn:aws:acm:us-east-1:123:certificate/abc" + documentIndex: 0 + asserts: + - equal: + path: metadata.annotations["application-networking.k8s.aws/certificate-arn"] + value: "arn:aws:acm:us-east-1:123:certificate/abc" diff --git a/charts/observability-stack/tests/init_dashboards_configmap_test.yaml b/charts/observability-stack/tests/init_dashboards_configmap_test.yaml new file mode 100644 index 00000000..614ce69d --- /dev/null +++ b/charts/observability-stack/tests/init_dashboards_configmap_test.yaml @@ -0,0 +1,24 @@ +suite: init dashboards configmap +templates: + - templates/init-dashboards-configmap.yaml +tests: + - it: should render when dashboards enabled + asserts: + - isKind: + of: ConfigMap + - isAPIVersion: + of: v1 + + - it: should not render when dashboards disabled + set: + opensearch-dashboards: + enabled: false + asserts: + - hasDocuments: + count: 0 + + - it: should use post-install hook + asserts: + - equal: + path: metadata.annotations["helm.sh/hook"] + value: post-install,post-upgrade diff --git a/charts/observability-stack/tests/init_dashboards_job_test.yaml b/charts/observability-stack/tests/init_dashboards_job_test.yaml new file mode 100644 index 00000000..d8317da1 --- /dev/null +++ b/charts/observability-stack/tests/init_dashboards_job_test.yaml @@ -0,0 +1,35 @@ +suite: init dashboards job +templates: + - templates/init-dashboards-job.yaml +tests: + - it: should render when dashboards enabled + asserts: + - isKind: + of: Job + - isAPIVersion: + of: batch/v1 + + - it: should not render when dashboards disabled + set: + opensearch-dashboards: + enabled: false + asserts: + - hasDocuments: + count: 0 + + - it: should use post-install hook + asserts: + - equal: + path: metadata.annotations["helm.sh/hook"] + value: post-install,post-upgrade + + - it: should read credentials from secret + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: OPENSEARCH_USER + valueFrom: + secretKeyRef: + name: RELEASE-NAME-observability-stack-opensearch-credentials + key: username diff --git a/charts/observability-stack/tests/opensearch_exporter_test.yaml b/charts/observability-stack/tests/opensearch_exporter_test.yaml new file mode 100644 index 00000000..ccb8e91c --- /dev/null +++ b/charts/observability-stack/tests/opensearch_exporter_test.yaml @@ -0,0 +1,57 @@ +suite: opensearch exporter +templates: + - templates/opensearch-exporter.yaml +tests: + - it: should render deployment and service by default + asserts: + - hasDocuments: + count: 2 + - containsDocument: + kind: Deployment + apiVersion: apps/v1 + any: true + - containsDocument: + kind: Service + apiVersion: v1 + any: true + + - it: should not render when disabled + set: + opensearchExporter.enabled: false + asserts: + - hasDocuments: + count: 0 + + - it: should use configured image + documentIndex: 0 + asserts: + - equal: + path: spec.template.spec.containers[0].image + value: "prometheuscommunity/elasticsearch-exporter:v1.10.0" + + - it: should use custom credentials in env + set: + opensearchUsername: myuser + opensearchPassword: "S3cret!" + documentIndex: 0 + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: ES_USERNAME + value: myuser + - contains: + path: spec.template.spec.containers[0].env + content: + name: ES_PASSWORD + value: "S3cret!" + + - it: should expose metrics port 9114 + documentIndex: 1 + asserts: + - contains: + path: spec.ports + content: + port: 9114 + targetPort: 9114 + name: metrics diff --git a/charts/observability-stack/values.yaml b/charts/observability-stack/values.yaml new file mode 100644 index 00000000..a0f1e76a --- /dev/null +++ b/charts/observability-stack/values.yaml @@ -0,0 +1,508 @@ +# Default values for observability-stack umbrella chart +# Mirrors the docker-compose setup for Kubernetes deployment + +# -- OpenSearch +# Sizing guide: +# Storage: daily_ingest_GB × 1.45 × (replicas + 1) × retention_days +# Shards: 30–50 GB per shard for logs/traces, 10–30 GB for search +# JVM: 50% of node RAM, max ~31 GB (set via OPENSEARCH_JAVA_OPTS) +# Nodes: minimum 3 for production, 1 for dev/demo +# Heap-to-shard ratio: max 25 shards per GB of JVM heap +opensearch: + enabled: true + singleNode: false + replicas: 3 + image: + repository: "opensearchstaging/opensearch" + tag: "3.6.0" + resources: + requests: + memory: "4Gi" + cpu: "2000m" + limits: + memory: "4Gi" + cpu: "4000m" + persistence: + enabled: true + size: 8Gi # Increase for production (e.g. 100Gi, 500Gi) + # storageClass: "gp3" # Uncomment for AWS gp3 (better IOPS/$ than gp2) + extraEnvs: + - name: OPENSEARCH_INITIAL_ADMIN_PASSWORD + value: "My_password_123!@#" + # JVM heap — set to 50% of resources.requests.memory, max 31g + - name: OPENSEARCH_JAVA_OPTS + value: "-Xms2g -Xmx2g" + config: + opensearch.yml: | + plugins.query.datasources.encryption.masterkey: "BTqK4Ytdz67La1kShIKV3Pu9" + +# -- OpenSearch Dashboards +opensearch-dashboards: + enabled: true + replicaCount: 3 + image: + repository: "opensearchstaging/opensearch-dashboards" + tag: "3.6.0" + resources: + requests: + cpu: "500m" + memory: "1Gi" + limits: + cpu: "2000m" + memory: "2Gi" + ingress: + enabled: true + ingressClassName: alb + annotations: + alb.ingress.kubernetes.io/scheme: internet-facing + alb.ingress.kubernetes.io/target-type: ip + alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}]' + alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-west-2:027423573553:certificate/489eff8e-d8b5-4ec3-a924-9768f518a49d + alb.ingress.kubernetes.io/ssl-policy: ELBSecurityPolicy-TLS13-1-2-2021-06 + alb.ingress.kubernetes.io/healthcheck-path: /app/login + alb.ingress.kubernetes.io/success-codes: "200" + external-dns.alpha.kubernetes.io/hostname: obs-playground-dev-027423573553.kylhouns.people.aws.dev + hosts: + - host: "" + paths: + - path: / + backend: + servicePort: 5601 + opensearchHosts: "https://opensearch-cluster-master:9200" + config: + opensearch_dashboards.yml: | + server.host: "0.0.0.0" + server.name: "observability-stack-dashboards" + opensearch.hosts: ["https://opensearch-cluster-master:9200"] + opensearch.username: "admin" + opensearch.password: "My_password_123!@#" + opensearch.ssl.verificationMode: none + opensearch.requestTimeout: 30000 + opensearch.requestHeadersAllowlist: ["authorization", "securitytenant"] + opensearch_security.multitenancy.enabled: false + opensearch_security.readonly_mode.roles: ["kibana_read_only"] + console.enabled: true + server.maxPayloadBytes: 1048576 + savedObjects.maxImportPayloadBytes: 26214400 + csp.strict: false + explore.enabled: true + explore.discoverTraces.enabled: true + explore.discoverMetrics.enabled: true + explore.agentTraces.enabled: true + workspace.enabled: true + data_source.enabled: true + data_source.ssl.verificationMode: none + datasetManagement.enabled: true + data.savedQueriesNewUI.enabled: true + opensearchDashboards.branding.useExpandedHeader: false + uiSettings.overrides.home:useNewHomePage: true + uiSettings.overrides.query:enhancements:enabled: true + uiSettings.overrides.explore:experimental: true + +# -- Data Prepper +data-prepper: + enabled: true + image: + repository: "sgguruda62324/opensearch-data-prepper" + tag: "2.15.0-SNAPSHOT" + ports: + - name: http-source + port: 2021 + - name: otel-traces + port: 21890 + - name: otel-metrics + port: 21891 + - name: otel-logs + port: 21892 + - name: metrics + port: 4900 + config: + data-prepper-config.yaml: | + ssl: false + peer_forwarder: + ssl: false + experimental: + enabled_plugins: + processor: + - otel_apm_service_map + sink: + - prometheus + livenessProbe: + initialDelaySeconds: 30 + periodSeconds: 10 + failureThreshold: 10 + readinessProbe: + initialDelaySeconds: 30 + periodSeconds: 10 + failureThreshold: 10 + pipelineConfig: + enabled: true + config: + # Main OTLP pipeline - receives all telemetry and routes by type + otlp-pipeline: + delay: 10 + source: + otlp: + port: 21890 + ssl: false + route: + - logs: 'getEventType() == "LOG"' + - traces: 'getEventType() == "TRACE"' + sink: + - pipeline: + name: "otel-logs-pipeline" + routes: ["logs"] + - pipeline: + name: "otel-traces-pipeline" + routes: ["traces"] + + otel-logs-pipeline: + workers: 5 + delay: 10 + source: + pipeline: + name: "otlp-pipeline" + buffer: + bounded_blocking: {} + processor: + - copy_values: + entries: + - from_key: "time" + to_key: "@timestamp" + sink: + - opensearch: + hosts: ["https://opensearch-cluster-master:9200"] + username: "admin" + password: "My_password_123!@#" + insecure: true + index_type: log-analytics-plain + # Shard tuning — adjust for ingest volume: + # 1 shard handles ~30-50 GB for logs. Scale shards with data node count. + # number_of_shards: 1 + # number_of_replicas: 1 + + otel-traces-pipeline: + delay: 100 + source: + pipeline: + name: "otlp-pipeline" + sink: + - pipeline: + name: "traces-raw-pipeline" + - pipeline: + name: "service-map-pipeline" + + traces-raw-pipeline: + source: + pipeline: + name: "otel-traces-pipeline" + processor: + - otel_traces: {} + sink: + - opensearch: + hosts: ["https://opensearch-cluster-master:9200"] + username: "admin" + password: "My_password_123!@#" + insecure: true + index_type: trace-analytics-plain-raw + # number_of_shards: 1 + # number_of_replicas: 1 + + service-map-pipeline: + delay: 100 + source: + pipeline: + name: "otel-traces-pipeline" + processor: + - otel_apm_service_map: + group_by_attributes: [telemetry.sdk.language] + window_duration: 10s + route: + - otel_apm_service_map_route: 'getEventType() == "SERVICE_MAP"' + - service_processed_metrics: 'getEventType() == "METRIC"' + sink: + - opensearch: + hosts: ["https://opensearch-cluster-master:9200"] + username: "admin" + password: "My_password_123!@#" + index_type: otel-v2-apm-service-map + routes: [otel_apm_service_map_route] + insecure: true + - prometheus: + url: "http://obs-stack-prometheus-server:80/api/v1/write" + threshold: + max_events: 500 + flush_interval: 5s + routes: [service_processed_metrics] + +# -- OpenTelemetry Collector +opentelemetry-collector: + enabled: true + mode: deployment + image: + repository: "otel/opentelemetry-collector-contrib" + config: + receivers: + otlp: + protocols: + grpc: + endpoint: 0.0.0.0:4317 + http: + endpoint: 0.0.0.0:4318 + cors: + allowed_origins: + - "http://*" + - "https://*" + processors: + memory_limiter: + check_interval: 5s + limit_percentage: 80 + spike_limit_percentage: 25 + batch: + timeout: 10s + send_batch_size: 1024 + resourcedetection: + detectors: [env] + transform: + error_mode: ignore + trace_statements: + - context: span + statements: + - replace_pattern(name, "\\?.*", "") + # Workaround for https://github.com/opensearch-project/data-prepper/issues/5616 + - set(attributes["error_type"], attributes["error.type"]) where attributes["error.type"] != nil + - delete_key(attributes, "error.type") + log_statements: + - context: log + statements: + - flatten(body) where IsMap(body) + - set(body, ToKeyValueString(body)) where IsMap(body) + exporters: + debug: + verbosity: detailed + otlp/opensearch: + endpoint: "obs-stack-data-prepper:21890" + tls: + insecure: true + otlphttp/prometheus: + endpoint: "http://obs-stack-prometheus-server:80/api/v1/otlp" + tls: + insecure: true + service: + pipelines: + traces: + receivers: [otlp] + processors: [resourcedetection, memory_limiter, transform, batch] + exporters: [otlp/opensearch, debug] + metrics: + receivers: [otlp] + processors: [resourcedetection, memory_limiter, batch] + exporters: [otlphttp/prometheus, debug] + logs: + receivers: [otlp] + processors: [resourcedetection, memory_limiter, transform, batch] + exporters: [otlp/opensearch, debug] + + ports: + otlp: + enabled: true + containerPort: 4317 + servicePort: 4317 + protocol: TCP + otlp-http: + enabled: true + containerPort: 4318 + servicePort: 4318 + protocol: TCP + metrics: + enabled: true + containerPort: 8888 + servicePort: 8888 + protocol: TCP + +# -- Prometheus +prometheus: + enabled: true + server: + # Retention — how long Prometheus keeps metrics. Increase for longer history. + retention: "15d" + persistentVolume: + enabled: true + size: 50Gi + resources: + requests: + memory: "2Gi" + cpu: "500m" + limits: + memory: "4Gi" + cpu: "1000m" + extraFlags: + - "web.enable-remote-write-receiver" + - "web.enable-otlp-receiver" + global: + scrape_interval: 60s + scrape_timeout: 10s + evaluation_interval: 60s + external_labels: + cluster: 'observability-stack' + environment: 'development' + # Disable default K8s scrape configs — they add ~60k series from API server internals. + # We keep node-exporter and kube-state-metrics (scraped via service endpoints below), + # and add explicit scrape for OTel Collector and Prometheus self-monitoring. + scrapeConfigs: + # Disable noisy defaults + kubernetes-api-servers: { enabled: false } + kubernetes-nodes: { enabled: false } + kubernetes-nodes-cadvisor: { enabled: false } + kubernetes-pods: { enabled: false } + kubernetes-pods-slow: { enabled: false } + kubernetes-service-endpoints: { enabled: false } + kubernetes-service-endpoints-slow: { enabled: false } + kubernetes-services: { enabled: false } + prometheus-pushgateway: { enabled: false } + # Keep self-monitoring + OTel Collector + prometheus: + static_configs: + - targets: ['localhost:9090'] + otel-collector: + static_configs: + - targets: ['obs-stack-opentelemetry-collector:8888'] + scrape_interval: 10s + opensearch: + static_configs: + - targets: ['obs-stack-observability-stack-opensearch-exporter:9114'] + scrape_interval: 30s + data-prepper: + metrics_path: '/metrics/prometheus' + static_configs: + - targets: ['obs-stack-data-prepper:4900'] + scrape_interval: 30s + node-exporter: + kubernetes_sd_configs: + - role: endpoints + relabel_configs: + - source_labels: [__meta_kubernetes_service_name] + regex: obs-stack-prometheus-node-exporter + action: keep + kube-state-metrics: + kubernetes_sd_configs: + - role: endpoints + relabel_configs: + - source_labels: [__meta_kubernetes_service_name] + regex: obs-stack-kube-state-metrics + action: keep + - source_labels: [__meta_kubernetes_endpoint_port_name] + regex: http + action: keep + scrapeConfigFiles: [] + serverFiles: + prometheus.yml: + otlp: + keep_identifying_resource_attributes: true + promote_resource_attributes: + - service.instance.id + - service.name + - service.namespace + - service.version + - deployment.environment.name + - gen_ai.agent.id + - gen_ai.agent.name + - gen_ai.provider.name + - gen_ai.request.model + - gen_ai.response.model + storage: + tsdb: + out_of_order_time_window: 30m + alertmanager: + enabled: false + kube-state-metrics: + enabled: true + prometheus-node-exporter: + enabled: true + prometheus-pushgateway: + enabled: false + +# -- Global settings +# NOTE: opensearchUsername/Password are the single source of truth. +# OpenSearch and OSD reference these via extraEnvs/config. +# Data Prepper pipeline configs don't support templating, so the password +# is duplicated there — update both if you change it. +opensearchUsername: "admin" +opensearchPassword: "My_password_123!@#" + +# -- OpenSearch Prometheus Exporter +opensearchExporter: + enabled: true + image: + repository: prometheuscommunity/elasticsearch-exporter + tag: v1.10.0 + +# -- Example agents (matches docker-compose.examples.yml) +examples: + enabled: true + imagePullPolicy: IfNotPresent + weatherAgent: + image: "ghcr.io/kylehounslow/observability-stack/weather-agent:latest" + eventsAgent: + image: "ghcr.io/kylehounslow/observability-stack/events-agent:latest" + travelPlanner: + image: "ghcr.io/kylehounslow/observability-stack/travel-planner:latest" + mcpServer: + image: "ghcr.io/kylehounslow/observability-stack/mcp-server:latest" + canary: + image: "ghcr.io/kylehounslow/observability-stack/canary:latest" + interval: "120" + +# -- OpenTelemetry Demo (optional) +# Full microservices e-commerce app that generates realistic telemetry. +# Disabled by default — adds ~2GB memory. Enable with opentelemetry-demo.enabled=true. +# All bundled backends (jaeger, grafana, prometheus, opensearch, collector) are disabled — +# demo services send telemetry to our OTel Collector instead. +opentelemetry-demo: + enabled: true + default: + envOverrides: + - name: OTEL_COLLECTOR_NAME + value: obs-stack-opentelemetry-collector + # Disable all bundled backends — we use our own stack + opentelemetry-collector: + enabled: false + jaeger: + enabled: false + prometheus: + enabled: false + grafana: + enabled: false + opensearch: + enabled: false + +# -- Gateway API for OpenSearch Dashboards +# Requires: Gateway API CRDs + a gateway controller installed on the cluster. +# Supported providers: envoy (Envoy Gateway), aws (AWS Gateway API Controller). +# Contributors welcome to add: gcp, azure, etc. +gateway: + enabled: false + # provider: envoy or aws + provider: envoy + # className maps to GatewayClass installed by your controller + className: eg + # host: dashboards.example.com + annotations: {} + tls: {} + # secretName: dashboards-tls # K8s TLS secret (envoy) + # + # --- Envoy Gateway --- + # Requires: https://gateway.envoyproxy.io/docs/install/ + # provider: envoy + # className: eg + # host: dashboards.example.com + # tls: + # secretName: dashboards-tls # cert-manager or manual secret + # + # --- AWS Gateway API Controller --- + # Requires: https://www.gateway-api-controller.eks.aws.dev/ + # provider: aws + # className: amazon-vpc-lattice + # host: dashboards.example.com + # annotations: + # application-networking.k8s.aws/certificate-arn: arn:aws:acm:REGION:ACCOUNT:certificate/ID diff --git a/docker-compose.yml b/docker-compose.yml index 23a268d3..cb26d289 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,6 +1,7 @@ # Observability Stack # Docker Compose configuration for local development # WARNING: This configuration is for development/testing only - not production-ready +name: observability-stack include: - path: ${INCLUDE_COMPOSE_EXAMPLES:-docker-compose/util/docker-compose.empty.yml} diff --git a/docker-compose/opensearch-dashboards/dashboard-pipeline-health.yaml b/docker-compose/opensearch-dashboards/dashboard-pipeline-health.yaml index 4ef8020d..1fdd2ea3 100644 --- a/docker-compose/opensearch-dashboards/dashboard-pipeline-health.yaml +++ b/docker-compose/opensearch-dashboards/dashboard-pipeline-health.yaml @@ -1,137 +1,112 @@ # Observability Pipeline Health Dashboard — OTel Collector and Prometheus self-monitoring - dashboard: id: observability-pipeline-health-dashboard title: Observability Pipeline Health description: OTel Collector throughput, Prometheus ingestion, and pipeline health - panels: # --- Row 1: OTel Collector Throughput --- - id: pipeline-otel-spans-received title: "OTel Spans Received/sec" query: "rate(otelcol_receiver_accepted_spans_total[5m])" chartType: line - - id: pipeline-otel-spans-exported title: "OTel Spans Exported/sec" query: "rate(otelcol_exporter_sent_spans_total[5m])" chartType: line - # --- Row 2: OTel Metrics & Failures --- - id: pipeline-otel-metrics-received title: "OTel Metrics Received/sec" query: "rate(otelcol_receiver_accepted_metric_points_total[5m])" chartType: line - - id: pipeline-otel-spans-dropped title: "OTel Spans Dropped/sec" query: "rate(otelcol_exporter_send_failed_spans_total[5m])" chartType: line - # --- Row 3: OTel Collector Resources --- - id: pipeline-otel-queue-size title: "OTel Exporter Queue Size" query: "otelcol_exporter_queue_size" chartType: line - - id: pipeline-otel-collector-memory title: "OTel Collector Memory (bytes)" query: "otelcol_process_memory_rss_bytes" chartType: line - # --- Row 4: OTel Collector CPU & Uptime --- - id: pipeline-otel-collector-cpu title: "OTel Collector CPU Usage" query: "rate(otelcol_process_cpu_seconds_total[5m])" chartType: line - - id: pipeline-otel-batch-cardinality title: "OTel Batch Metadata Cardinality" query: "otelcol_processor_batch_metadata_cardinality" chartType: line - # --- Row 5: Prometheus Health --- - id: pipeline-prometheus-ingestion title: "Prometheus Ingestion Rate (chunks/sec)" query: "rate(prometheus_tsdb_head_chunks_created_total[5m])" chartType: line - - id: pipeline-prometheus-active-series title: "Prometheus Active Time Series" query: "prometheus_tsdb_head_series" chartType: line - # --- Row 6: Prometheus Storage --- - id: pipeline-prometheus-wal-size title: "Prometheus WAL Size (bytes)" query: "prometheus_tsdb_wal_storage_size_bytes" chartType: line - - id: pipeline-prometheus-head-chunks title: "Prometheus Head Chunks Size (bytes)" query: "prometheus_tsdb_head_chunks_storage_size_bytes" chartType: line - - id: pipeline-prometheus-query-latency title: "Prometheus Query Latency P99 (sec)" query: "histogram_quantile(0.99, rate(prometheus_http_request_duration_seconds_bucket{handler=\"/api/v1/query\"}[5m]))" chartType: line - # --- Row 7: Data Prepper — Logs Pipeline --- - id: pipeline-dp-logs-processed title: "DP Logs Processed/sec" query: "rate(otel_logs_pipeline_recordsProcessed_total[5m])" chartType: line - - id: pipeline-dp-logs-latency title: "DP Logs Pipeline Latency (avg sec)" query: "rate(otel_logs_pipeline_opensearch_PipelineLatency_seconds_sum[5m]) / rate(otel_logs_pipeline_opensearch_PipelineLatency_seconds_count[5m])" chartType: line - # --- Row 8: Data Prepper — Traces Pipeline --- - id: pipeline-dp-traces-processed title: "DP Traces Processed/sec" query: "rate(otel_traces_pipeline_recordsProcessed_total[5m])" chartType: line - - id: pipeline-dp-traces-latency title: "DP Traces Pipeline Latency (avg sec)" query: "rate(traces_raw_pipeline_opensearch_PipelineLatency_seconds_sum[5m]) / rate(traces_raw_pipeline_opensearch_PipelineLatency_seconds_count[5m])" chartType: line - # --- Row 9: Data Prepper — Metrics Pipeline --- - id: pipeline-dp-metrics-received title: "DP Metrics Received/sec" query: "rate(otlp_metrics_requestsReceived_total[5m])" chartType: line - - id: pipeline-dp-otlp-requests title: "DP OTLP Requests Received/sec (all)" query: "rate(otlp_traces_requestsReceived_total[5m]) + rate(otlp_logs_requestsReceived_total[5m]) + rate(otlp_metrics_requestsReceived_total[5m])" chartType: line - # --- Row 10: Data Prepper — Writes & Errors --- - id: pipeline-dp-logs-docs-written title: "DP Logs Docs Written/sec" query: "rate(otel_logs_pipeline_opensearch_documentsSuccess_total[5m])" chartType: line - - id: pipeline-dp-traces-docs-written title: "DP Traces Docs Written/sec" query: "rate(traces_raw_pipeline_opensearch_documentsSuccess_total[5m])" chartType: line - # --- Row 11: Data Prepper — Errors & Buffer --- - id: pipeline-dp-bulk-errors title: "DP Bulk Request Errors" query: "sum(rate(otel_logs_pipeline_opensearch_bulkRequestErrors_total[5m])) + sum(rate(traces_raw_pipeline_opensearch_bulkRequestErrors_total[5m]))" chartType: line - - id: pipeline-dp-buffer-usage title: "DP Buffer Writes/sec" query: "rate(otel_logs_pipeline_BlockingBuffer_recordsWritten_total[5m]) + rate(otel_traces_pipeline_BlockingBuffer_recordsWritten_total[5m])" chartType: line - - id: pipeline-dp-buffer-capacity title: "DP Buffer Capacity Used %" query: "otlp_pipeline_BlockingBuffer_capacityUsed + otel_logs_pipeline_BlockingBuffer_capacityUsed + otel_traces_pipeline_BlockingBuffer_capacityUsed" diff --git a/load-testing/AGENTS.md b/load-testing/AGENTS.md new file mode 100644 index 00000000..50c2eac8 --- /dev/null +++ b/load-testing/AGENTS.md @@ -0,0 +1,255 @@ +# AGENTS.md — Load Testing Procedures + +This document captures the exact procedures for reproducing load tests against the Observability Stack Helm deployment. Designed for AI coding assistants to execute without prior context. + +## Repository Context + +- Load testing files live in `load-testing/` within the `feat/helm-charts` worktree at `.worktrees/feat-helm-charts/` +- Helm chart is at `.worktrees/feat-helm-charts/charts/observability-stack/` +- Terraform for EKS cluster is at `.worktrees/feat-helm-charts/terraform/aws/` +- Terraform for EC2 load generator is at `load-testing/terraform/` +- Results are tracked in `load-testing/RESULTS.md`, sizing in `load-testing/SIZING.md` + +## Current Deployment State (as of 2026-03-20) + +### EKS Cluster +- Name: `observability-stack`, region: `us-west-2` +- 4x m5.xlarge nodes (4 vCPU, 16 GB each) +- Helm release: `obs-stack` in namespace `observability-stack` + +### Stack Configuration +| Component | Replicas | CPU (req/limit) | Memory (req/limit) | +|-----------|----------|-----------------|-------------------| +| OpenSearch | 3 (StatefulSet) | 1000m/2000m | 4Gi/4Gi (JVM: 2Gi) | +| OpenSearch Dashboards | 3 | 500m/2000m | 1Gi/2Gi | +| OTel Collector | 1 | none | none | +| Data Prepper | 2 | none | none | +| Prometheus | 1 | none | none | +| OTel Demo | enabled | ~20 microservices | built-in load generator | + +### Access Points +- Dashboards ALB: `https://obs-playground-dev-027423573553.kylhouns.people.aws.dev` +- Credentials: `admin` / `My_password_123!@#` +- DNS configured via terraform at `.worktrees/feat-helm-charts/terraform/aws/terraform.tfvars` + +### EC2 Load Generator +- Instance: `i-08f9652631fe73302` (m5.xlarge, same VPC) +- Access: SSM only (no SSH key) +- k6 installed at `/usr/local/bin/k6` (v1.0.0) +- Scripts at `/home/ec2-user/k6/scenarios/` +- Results at `/home/ec2-user/k6/results/` +- Terraform state at `load-testing/terraform/` + +## Procedures + +### 1. Upload k6 Scripts to EC2 + +```bash +INSTANCE_ID="i-08f9652631fe73302" +SCRIPT=$(cat load-testing/k6/scenarios/api-queries-alb.js | base64) +aws ssm send-command \ + --instance-ids "$INSTANCE_ID" \ + --document-name "AWS-RunShellScript" \ + --parameters "commands=[\"echo '$SCRIPT' | base64 -d > /home/ec2-user/k6/scenarios/api-queries-alb.js\"]" \ + --region us-west-2 --output text --query 'Command.CommandId' +``` + +### 2. Run a Load Test + +```bash +INSTANCE_ID="i-08f9652631fe73302" +TARGET_URL="https://obs-playground-dev-027423573553.kylhouns.people.aws.dev" +VUS=1000 +TEST_NUM=007 + +CMD_ID=$(aws ssm send-command \ + --instance-ids "$INSTANCE_ID" \ + --document-name "AWS-RunShellScript" \ + --parameters "commands=[\"cd /home/ec2-user/k6 && k6 run --env TARGET_VUS=$VUS --env DASHBOARDS_URL=$TARGET_URL --env OSD_USER=admin --env OSD_PASSWORD='My_password_123!@#' scenarios/api-queries-alb.js 2>&1 | tee results/test-${TEST_NUM}.log\"]" \ + --timeout-seconds 1200 \ + --region us-west-2 \ + --output text --query 'Command.CommandId') +echo "Command: $CMD_ID" +``` + +### 3. Monitor During Test + +```bash +# Check test status +aws ssm get-command-invocation --command-id "$CMD_ID" --instance-id "$INSTANCE_ID" --region us-west-2 --query 'Status' --output text + +# Monitor OpenSearch nodes +kubectl exec -n observability-stack opensearch-cluster-master-0 -- curl -sk -u admin:'My_password_123!@#' \ + 'https://localhost:9200/_cat/nodes?h=name,heap.percent,cpu,load_1m,search.query_total,search.query_current' + +# Thread pool pressure +kubectl exec -n observability-stack opensearch-cluster-master-0 -- curl -sk -u admin:'My_password_123!@#' \ + 'https://localhost:9200/_cat/thread_pool/search?v&h=name,node_name,active,queue,rejected' + +# Hot threads (what's consuming CPU) +kubectl exec -n observability-stack opensearch-cluster-master-0 -- curl -sk -u admin:'My_password_123!@#' \ + 'https://localhost:9200/_nodes/hot_threads?threads=3' + +# JVM and OS stats +kubectl exec -n observability-stack opensearch-cluster-master-0 -- curl -sk -u admin:'My_password_123!@#' \ + 'https://localhost:9200/_nodes/stats/jvm,os?pretty' +``` + +### 4. Retrieve Results + +SSM truncates long output. Always read from the log file: + +```bash +RESULT_CMD=$(aws ssm send-command \ + --instance-ids "$INSTANCE_ID" \ + --document-name "AWS-RunShellScript" \ + --parameters "commands=[\"tail -35 /home/ec2-user/k6/results/test-${TEST_NUM}.log\"]" \ + --region us-west-2 --output text --query 'Command.CommandId') +sleep 5 +aws ssm get-command-invocation --command-id "$RESULT_CMD" --instance-id "$INSTANCE_ID" --region us-west-2 --query 'StandardOutputContent' --output text +``` + +### 5. Record Results + +Create `load-testing/results/NNN-description.md` with: +- Start/end timestamps (UTC and PDT) +- Configuration at time of test +- k6 summary (p50, p90, p95, max, error rate, req/s) +- Cluster observations during test (CPU, heap, thread pool, queue depths) +- Root cause analysis +- Next steps + +Update `load-testing/RESULTS.md` index table and bottleneck progression. +Update `load-testing/SIZING.md` if capacity estimates change. + +### 6. Apply Configuration Changes + +```bash +# Edit values.yaml +vim .worktrees/feat-helm-charts/charts/observability-stack/values.yaml + +# Deploy +helm upgrade obs-stack .worktrees/feat-helm-charts/charts/observability-stack \ + -n observability-stack --reuse-values + +# Or override specific values +helm upgrade obs-stack .worktrees/feat-helm-charts/charts/observability-stack \ + -n observability-stack --reuse-values \ + --set opensearch.replicas=3 +``` + +### 7. Scale EKS Nodes + +```bash +NODEGROUP=$(aws eks list-nodegroups --cluster-name observability-stack --region us-west-2 --query 'nodegroups[0]' --output text) +aws eks update-nodegroup-config \ + --cluster-name observability-stack \ + --nodegroup-name "$NODEGROUP" \ + --scaling-config minSize=2,maxSize=5,desiredSize=4 \ + --region us-west-2 +``` + +### 8. Manage EC2 Load Generator + +```bash +# Create (from load-testing/terraform/) +cd load-testing/terraform && terraform init && terraform apply + +# Destroy when done +terraform destroy + +# SSM session +aws ssm start-session --target i-08f9652631fe73302 --region us-west-2 +``` + +### 9. Redeploy Dashboards (after changing saved queries/dashboard YAMLs) + +```bash +helm upgrade obs-stack .worktrees/feat-helm-charts/charts/observability-stack \ + -n observability-stack --reuse-values +# Init job runs automatically as post-install/post-upgrade hook +``` + +## k6 Script Details + +### api-queries-alb.js +The primary load test script. Hits OSD through ALB with a mix of: +- **30% PPL queries** on span index (`/api/ppl/search`) +- **20% PPL queries** on log index +- **20% OpenSearch DSL search** via console proxy (`/api/console/proxy?path=...&method=POST`) +- **15% Saved objects list** (`/api/saved_objects/_find?type=dashboard`) +- **15% Service map query** via console proxy + +Key env vars: +- `TARGET_VUS` — peak virtual users (default 200) +- `DASHBOARDS_URL` — ALB endpoint +- `OSD_USER` / `OSD_PASSWORD` — credentials + +Ramp stages: 0→25%→50%→100% (hold 3min) →0 over 15 minutes. + +### Known Script Issues +- Console proxy path (`/api/console/proxy?path=...&method=POST`) returns 400 for some queries — needs investigation +- Prometheus queries not yet routed through OSD (datasource proxy path TBD) +- `insecureSkipTLSVerify: true` required in options block (not per-request) +- Auth uses manual `Authorization: Basic ` header via `k6/encoding` module + +## Key Learnings + +### Bottleneck Discovery Order +1. **OSD (100m CPU)** — Node.js single-threaded, saturates immediately. Fix: 3 replicas, 2 CPU each. +2. **OpenSearch (single node, 4 vCPU)** — 99% CPU, search queue depth 34. Fix: 3 data nodes. +3. **Uneven shard distribution** — original indices have 1 primary shard, load concentrates on 2 of 3 nodes. Fix: increase replica count or reindex with more shards. +4. **Data volume** (not yet tested) — 7-day data projected to reduce capacity ~40%. + +### Important Gotchas +- `kubectl port-forward` is NOT a valid load test path — it bottlenecks at the tunnel, not the cluster. Always use EC2 in the same VPC hitting the ALB. +- OSD workspace IDs differ between internal cluster access and external port-forward. The init script uses the internal workspace ID. +- The opensearch-dashboards Helm subchart uses `replicaCount` not `replicas` for scaling. +- OpenSearch `singleNode: true` must be set to `false` when scaling to multiple nodes. +- SSM command output is truncated for long-running tests. Always `tee` to a log file and read from there. + +## File Structure + +``` +load-testing/ +├── AGENTS.md # This file — procedures for AI assistants +├── README.md # Load testing plan and approach +├── RESULTS.md # Test result index with bottleneck progression +├── SIZING.md # Capacity sizing chart and projections +├── results/ +│ ├── 001-api-queries-auth-bug.md +│ ├── 002-api-queries.md +│ ├── 003-api-queries-1500vu.md +│ ├── 004-alb-1000vu-osd-bottleneck.md +│ ├── 005-alb-1000vu-opensearch-bottleneck.md +│ └── 006-alb-1000vu-3node-opensearch.md +├── k6/ +│ ├── full-test.js # Combined API + browser test +│ └── scenarios/ +│ ├── api-queries.js # Direct OpenSearch/Prometheus (port-forward) +│ ├── api-queries-alb.js # Through ALB/OSD (EC2 → ALB) +│ ├── browser-traces.js # Chromium: trace analytics flow +│ ├── browser-discover.js # Chromium: discover + PPL +│ └── browser-metrics.js # Chromium: metric dashboards +├── osb/ +│ ├── run-osb.sh # OpenSearch Benchmark runner +│ ├── workload.json # Custom trace/log workload +│ └── index-settings.json # Index mappings +├── pipeline/ +│ └── run-telemetrygen.sh # OTLP pipeline throughput test +├── terraform/ +│ ├── main.tf # EC2 load generator +│ ├── terraform.tfvars # VPC/subnet/target config +│ └── .gitignore +└── run-remote.sh # Upload + run helper +``` + +## Next Steps (Pending) + +1. **Fix shard distribution** — increase replica count on span/log indices so all 3 nodes serve searches equally +2. **Run 300 VU test** — validate the "good experience" threshold estimate +3. **7-day data test** — let OTel Demo run for a week, then re-run 1000 VU test +4. **Dedicated search nodes** — set up remote store (S3) + search node role for production config +5. **Prometheus load** — route PromQL through OSD to test single-pod Prometheus under concurrent dashboard users +6. **WAF testing** — enable WAF on ALB, measure throughput impact +7. **Browser tests** — run k6 browser module for real Chromium sessions diff --git a/load-testing/README.md b/load-testing/README.md new file mode 100644 index 00000000..e1944e3a --- /dev/null +++ b/load-testing/README.md @@ -0,0 +1,243 @@ +# Observability Stack Load Testing Plan + +## Goal + +Determine the breaking points and concurrent user capacity of the Observability Stack for a given Helm deployment. Testing is manual (not CI-automated) and covers both backend ingestion throughput and frontend dashboard responsiveness. + +## Test Environment + +- Helm release: `obs-stack` in namespace `observability-stack` +- Chart: `observability-stack-0.1.0` +- OpenTelemetry Demo: **enabled** — full microservices e-commerce app generating realistic telemetry via built-in load generator +- Prometheus: single pod (`obs-stack-prometheus-server`) +- OpenSearch: single node (`singleNode: true`) +- OTel demo services provide baseline ingestion load (traces, logs, metrics from ~20 microservices) + +## Architecture Under Test + +``` +telemetrygen / OSB + │ + ▼ +OTel Collector (4317/4318) + │ + ├──► Data Prepper ──► OpenSearch (logs, traces) + └──► Prometheus (metrics, single pod) + │ + ▼ + OpenSearch Dashboards + ├── Discover (queries OpenSearch) + ├── Trace Analytics (queries OpenSearch) + ├── Metric Panels (queries Prometheus) + └── PPL queries (queries OpenSearch) +``` + +## Tools + +| Tool | Purpose | Install | +|------|---------|---------| +| [OpenSearch Benchmark (OSB)](https://github.com/opensearch-project/OpenSearch-Benchmark) | Direct OpenSearch indexing/query load + redline testing | `pip install opensearch-benchmark` | +| [telemetrygen](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/cmd/telemetrygen) | OTLP trace/log/metric generation through the full pipeline | `go install github.com/open-telemetry/opentelemetry-collector-contrib/cmd/telemetrygen@latest` | +| [k6 + browser module](https://grafana.com/docs/k6/latest/using-k6-browser/) | HTTP API load + real browser UI simulation | `brew install k6` (browser module is built-in) | + +## Test Layers + +### Layer 1: OpenSearch Capacity (OSB Direct) + +Bypasses the pipeline to find OpenSearch's own ceiling. + +**What it tests:** Indexing throughput (docs/sec), query latency under load, heap pressure, thread pool rejections. + +**How:** +```bash +# Redline test — auto-ramps until the cluster breaks +opensearch-benchmark execute-test \ + --target-hosts=https://opensearch:9200 \ + --pipeline=benchmark-only \ + --workload=pmc \ + --client-options="use_ssl:true,verify_certs:false,basic_auth_user:admin,basic_auth_password:My_password_123!@#" \ + --redline-test +``` + +**Custom workload (TODO):** Create an OSB workload that uses trace/log document shapes matching our `otel-v1-apm-span-*` and `otel-v1-apm-log-*` indices for realistic testing. + +**Metrics to watch:** +- Indexing throughput (docs/sec) +- p50/p95/p99 query latency +- `_nodes/stats`: heap used %, thread pool rejected count, merge times +- Pod CPU/memory via `kubectl top pod` + +### Layer 2: Pipeline Throughput (telemetrygen → OTel Collector) + +Tests the full ingestion path: OTel Collector → Data Prepper → OpenSearch. + +**What it tests:** End-to-end pipeline capacity, backpressure behavior, which component saturates first. + +**How:** +```bash +# Traces — ramp up spans/sec until pipeline drops data +telemetrygen traces \ + --otlp-endpoint=otel-collector:4317 \ + --otlp-insecure \ + --rate=100 \ + --duration=5m \ + --service=load-test-agent \ + --otlp-attributes='gen_ai.agent.name="load-test"' + +# Logs +telemetrygen logs \ + --otlp-endpoint=otel-collector:4317 \ + --otlp-insecure \ + --rate=100 \ + --duration=5m \ + --service=load-test-agent + +# Metrics +telemetrygen metrics \ + --otlp-endpoint=otel-collector:4317 \ + --otlp-insecure \ + --rate=50 \ + --duration=5m \ + --service=load-test-agent +``` + +Increase `--rate` in increments (100 → 500 → 1000 → 5000) until failures appear. + +**Metrics to watch:** +- Collector: `otelcol_exporter_sent_spans` vs `otelcol_exporter_send_failed_spans` +- Collector: `otelcol_processor_batch_timeout_trigger_send` (batch pressure) +- Data Prepper: pipeline queue depth, processing latency +- OpenSearch: bulk indexing rejection rate +- End-to-end latency: time from telemetrygen send to document appearing in OpenSearch + +### Layer 3: Dashboard UI Under Load (k6) + +Simulates concurrent users interacting with OpenSearch Dashboards while the cluster is under ingestion load from Layers 1-2. + +**What it tests:** Dashboard responsiveness, PPL query performance, Prometheus query capacity (single pod), OSD server memory/CPU. + +#### Scenarios + +| # | Scenario | Target Backend | +|---|----------|----------------| +| 1 | **Dashboard viewer** — Open saved dashboard, wait for panels, change time range, refresh | OpenSearch + Prometheus | +| 2 | **Discover explorer** — Select log index, run PPL query, paginate results | OpenSearch | +| 3 | **Trace analytics** — View traces list, click into a trace, expand spans, view service map | OpenSearch | +| 4 | **Expensive PPL** — High-cardinality aggregations, long time ranges, `dedup`, `stats ... by` | OpenSearch | +| 5 | **Metrics explorer** — Open metric visualizations, PromQL queries, change time range to 7d | **Prometheus (single pod)** | +| 6 | **APM browser** — Services list, click service, view latency/error panels, drill into operations | OpenSearch + Prometheus | + +#### k6 Test Structure + +Two scenario types run concurrently in a single k6 test: + +**API-level VUs (high scale):** Replay the HTTP requests that OSD makes under the hood. Scales to hundreds of concurrent users. + +- `POST _plugins/_ppl` — PPL queries of varying complexity +- `POST _search` — Discover-style searches against trace/log indices +- `GET prometheus:9090/api/v1/query_range` — PromQL queries mirroring metric panels +- `GET _dashboards/api/saved_objects` — Dashboard/visualization loads + +**Browser VUs (low scale, high fidelity):** Real Chromium sessions clicking through OSD. 5-20 concurrent sessions. + +- Login → navigate to Traces → click trace → expand spans +- Login → Discover → run PPL → paginate +- Login → Dashboard → change time range → wait for render + +#### Ramp-Up Strategy (Finding Breaking Points) + +``` +Phase 1: API-only ramp + 0 → 50 → 200 → 500 VUs over 15 min + Find: p95 latency spike, first errors + +Phase 2: Browser users on top + Hold API at ~70% of Phase 1 breaking point + Add 5 → 10 → 15 → 20 browser VUs + Find: OSD pod OOM, page load > 10s + +Phase 3: Combined with ingestion + Run telemetrygen at ~70% of Layer 2 breaking point + Repeat Phase 1+2 + Find: degradation from concurrent read+write load +``` + +#### Prometheus-Specific Stress + +Since Prometheus is a single pod, dedicate specific API VUs to PromQL queries: + +- `rate(gen_ai_usage_input_tokens_total[5m])` — simple +- `sum by (service_name, agent_name, model) (rate(gen_ai_usage_input_tokens_total[5m]))` — high cardinality fan-out +- Same queries with `[7d]` range — memory-heavy +- Multiple concurrent `query_range` requests with overlapping time windows + +**Metrics to watch:** +- Prometheus pod CPU/memory (`kubectl top pod`) +- Prometheus query duration (`prometheus_engine_query_duration_seconds`) +- Prometheus query failures (`prometheus_engine_queries_concurrent_max`) +- OSD response times for metric panels + +### k6 Thresholds + +```javascript +thresholds: { + // API-level + http_req_duration: ['p(95)<3000'], // API queries under 3s + http_req_failed: ['rate<0.05'], // <5% error rate + + // Browser-level + browser_web_vital_lcp: ['p(95)<4000'], // Largest Contentful Paint under 4s + browser_web_vital_cls: ['p(95)<0.25'], // Cumulative Layout Shift +} +``` + +## Execution Order + +1. **Layer 1** — Run OSB redline test to establish OpenSearch ceiling (no other load) +2. **Layer 2** — Run telemetrygen ramp to find pipeline throughput limit (no UI load) +3. **Layer 3 Phase 1** — API-only k6 ramp (no ingestion load) to find query capacity +4. **Layer 3 Phase 2** — Add browser VUs to find OSD/Prometheus limits +5. **Layer 3 Phase 3** — Combine: telemetrygen at 70% + k6 at 70% to find real-world capacity +6. **Report** — Document breaking points, bottleneck component, and max concurrent users per capacity tier + +## Expected Bottleneck Order (Hypothesis) + +1. **Prometheus (single pod)** — likely first to degrade under concurrent metric queries with long time ranges +2. **Data Prepper** — pipeline queue saturation under high ingestion rates +3. **OpenSearch Dashboards** — Node.js server memory under many concurrent browser sessions +4. **OpenSearch** — heap pressure from concurrent expensive queries + indexing + +## Deliverables + +- [ ] OSB custom workload matching our trace/log document shapes +- [ ] telemetrygen wrapper script with incremental rate steps +- [ ] k6 test scripts for all 6 UI scenarios (API + browser) +- [ ] Results report: breaking points per component, max concurrent users, resource utilization graphs +- [ ] Capacity recommendations: pod sizing for N concurrent users + +## Directory Structure + +``` +load-testing/ +├── README.md +├── osb/ +│ └── workload.json # Custom OSB workload for trace/log shapes +├── pipeline/ +│ └── run-telemetrygen.sh # Incremental rate ramp script +└── k6/ + ├── scenarios/ + │ ├── api-queries.js # API-level PPL, search, PromQL + │ ├── browser-traces.js # Browser: trace analytics flow + │ ├── browser-discover.js# Browser: discover + PPL flow + │ └── browser-metrics.js # Browser: metric panels flow + └── full-test.js # Combined ramp-up test +``` + +## References + +- [OpenSearch Benchmark docs](https://opensearch.org/docs/latest/benchmark/) +- [OSB Redline Testing](https://opensearch.org/blog/redline-testing-now-available-in-opensearch-benchmark/) +- [telemetrygen](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/cmd/telemetrygen) +- [k6 Browser Module](https://grafana.com/docs/k6/latest/using-k6-browser/) +- [OpenSearch PPL API](https://docs.opensearch.org/latest/sql-and-ppl/sql-and-ppl-api/index/) +- [Prometheus Query API](https://prometheus.io/docs/prometheus/latest/querying/api/) diff --git a/load-testing/RESULTS.md b/load-testing/RESULTS.md new file mode 100644 index 00000000..f66d8cd4 --- /dev/null +++ b/load-testing/RESULTS.md @@ -0,0 +1,49 @@ +# Load Test Results + +## Baseline Topology (2026-03-20) + +### Cluster +- EKS cluster: `observability-stack`, us-west-2 +- Kubernetes: 1.32 +- Nodes: 2x `m5.xlarge` (4 vCPU, 16 GB RAM each = 8 vCPU / 32 GB total) + +### Core Stack Pods +| Component | Replicas | CPU Req | Mem Req | Node | +|-----------|----------|---------|---------|------| +| OpenSearch | 1 (single-node) | 500m | 2Gi (JVM: 1g) | node-1 | +| OpenSearch Dashboards | 1 | 100m | 512M | node-2 | +| OTel Collector | 1 | none | none | node-2 | +| Data Prepper | 2 | none | none | node-1, node-2 | +| Prometheus | 1 (no PV) | none | none | node-2 | + +### OpenSearch State +- Cluster status: yellow (3 unassigned replica shards — expected with single node) +- Active shards: 14 primary +- Indices: `otel-v1-apm-span-000001` (111k docs, 57MB), `logs-otel-v1-000001` (7k docs, 12MB), `otel-v2-apm-service-map-000001` (14k docs, 2.8MB) + +### Background Load +- OTel Demo: ~20 microservices generating traces/logs/metrics via built-in load generator +- Example agents: travel-planner, weather-agent, events-agent, canary + +--- + +## Test Results + +| # | Test | Date | Status | Result File | +|---|------|------|--------|-------------| +| 1 | API Query Load (200 OS VUs + 100 Prom VUs) | 2026-03-20 12:04–12:19 | ⚠️ Auth bug | [001-api-queries-auth-bug.md](results/001-api-queries-auth-bug.md) | +| 2 | API Query Load (300 VUs, auth fixed) | 2026-03-20 12:42–12:57 | ✅ 0% errors, p95=16ms | [002-api-queries.md](results/002-api-queries.md) | +| 3 | API Query Load (1500 VUs) | 2026-03-20 12:57–13:12 | ⚠️ p95=2.28s, 0% errors | [003-api-queries-1500vu.md](results/003-api-queries-1500vu.md) | +| 4 | ALB E2E (1000 VUs from EC2) | 2026-03-20 14:55–14:59 | 🔴 OSD saturated at 100m CPU, 3s+ latency | [004-alb-1000vu-osd-bottleneck.md](results/004-alb-1000vu-osd-bottleneck.md) | +| 5 | ALB E2E (1000 VUs, 3x OSD 2CPU) | 2026-03-20 15:08–15:24 | ⚠️ OSD fixed, OpenSearch at 99% CPU, p95=14.57s | [005-alb-1000vu-opensearch-bottleneck.md](results/005-alb-1000vu-opensearch-bottleneck.md) | +| 6 | ALB E2E (1000 VUs, 3x OS nodes) | 2026-03-20 15:47–16:02 | ⚠️ 37% better throughput, p95=10.57s, uneven shards | [006-alb-1000vu-3node-opensearch.md](results/006-alb-1000vu-3node-opensearch.md) | +| 7 | ALB E2E (1000 VUs, balanced shards) | 2026-03-20 16:18–16:33 | ⚠️ p95=6.32s (+40%), 168 req/s (+62% from baseline) | [007-alb-1000vu-balanced-shards.md](results/007-alb-1000vu-balanced-shards.md) | + +## Bottleneck Progression + +| Test | Bottleneck | Fix Applied | Result | +|------|-----------|-------------|--------| +| 004 | OSD (100m CPU, 1 replica) | Scaled to 3 replicas, 2 CPU each | ✅ Resolved | +| 005 | OpenSearch (single node, 4 vCPU, 99% CPU) | Scaled to 3 nodes, 2 CPU / 4Gi each | ✅ Improved | +| 006 | Uneven shard distribution across 3 nodes | Set number_of_replicas=2 | ✅ Improved | +| 007 | Primary shard routing preference (Node-0 overloaded) | **Next: search routing or dedicated search nodes** | Pending | diff --git a/load-testing/SIZING.md b/load-testing/SIZING.md new file mode 100644 index 00000000..c9db48d7 --- /dev/null +++ b/load-testing/SIZING.md @@ -0,0 +1,103 @@ +# Capacity Sizing Chart + +## Current Deployment (2026-03-20) + +### Infrastructure +| Component | Replicas | CPU (req/limit) | Memory (req/limit) | Nodes | +|-----------|----------|-----------------|-------------------|-------| +| OpenSearch | 3 | 1000m / 2000m | 4Gi / 4Gi | 3x m5.xlarge | +| OpenSearch Dashboards | 3 | 500m / 2000m | 1Gi / 2Gi | spread across nodes | +| OTel Collector | 1 | none | none | 1 node | +| Data Prepper | 2 | none | none | 2 nodes | +| Prometheus | 1 | none | none | 1 node | +| EKS Nodes | 4x m5.xlarge | 4 vCPU each | 16 GB each | 16 vCPU / 64 GB total | + +### Data Volume (OTel Demo + example agents) +| Metric | Current (1.7 days) | 7-Day Projection | 30-Day Projection | +|--------|-------------------|-------------------|-------------------| +| Spans | 379,025 | ~1.5M | ~6.6M | +| Logs | 139,909 | ~568K | ~2.4M | +| Service map entries | 128,604 | ~522K | ~2.2M | +| Primary store size | 316 MB | ~1.3 GB | ~5.6 GB | +| Total store (w/ replicas) | 632 MB | ~2.5 GB | ~11 GB | +| Ingestion rate (spans) | 9,163/hr | — | — | +| Ingestion rate (logs) | 3,382/hr | — | — | + +--- + +## Concurrent User Capacity (Estimated) + +Based on load tests 002–006, hitting OpenSearch Dashboards through ALB with PPL queries, _search, saved object loads, and service map queries. + +### Current Config: 3 OS Nodes + 3 OSD Replicas, ~1.7 days of data (~316 MB primary) + +| User Experience | Est. Concurrent Users (VUs) | p95 Latency | Throughput | +|----------------|---------------------------|-------------|------------| +| Excellent (< 200ms p95) | ~50 | < 200ms | ~50 req/s | +| Good (< 1s p95) | ~150–200 | < 1s | ~80 req/s | +| Acceptable (< 2s p95) | ~250–350 | < 2s | ~100 req/s | +| Degraded (< 5s p95) | ~500–700 | < 5s | ~120 req/s | +| Saturated | 1000 | **10.57s** | 143 req/s | +| Breaking (errors appear) | > 1000 (not yet found) | > 15s | — | + +### Projected: 7 Days of Data (~1.3 GB primary) + +With 4x more data, search queries scan more segments and use more heap. Expected impact: + +| User Experience | Est. Concurrent Users | Notes | +|----------------|----------------------|-------| +| Excellent (< 200ms p95) | ~30–40 | Larger indices = slower scans | +| Good (< 1s p95) | ~100–150 | Query cache helps for repeated queries | +| Acceptable (< 2s p95) | ~150–250 | JVM heap pressure increases | +| Saturated | ~500–700 | Heap at 80%+, GC pauses start | + +### Projected: 30 Days of Data (~5.6 GB primary) + +| User Experience | Est. Concurrent Users | Notes | +|----------------|----------------------|-------| +| Excellent (< 200ms p95) | ~15–25 | Need shard optimization | +| Good (< 1s p95) | ~50–100 | Need more JVM heap or nodes | +| Acceptable (< 2s p95) | ~100–150 | ISM rollover policies critical | +| Saturated | ~300–500 | Need dedicated search nodes | + +⚠️ **These are estimates** based on extrapolation from 1000 VU tests. Actual numbers depend on query complexity, time range selected, and index management policies. The 7-day and 30-day projections assume linear degradation which is optimistic — real degradation is often worse due to GC pressure and segment merge overhead. + +--- + +## Scaling Recommendations by User Count + +| Target Users | OpenSearch | OSD | EKS Nodes | Est. Monthly Cost | +|-------------|-----------|-----|-----------|-------------------| +| 10–50 | 1 node (4Gi, 2 CPU) | 1 replica | 2x m5.xlarge | ~$350 | +| 50–200 | 3 nodes (4Gi, 2 CPU) | 2 replicas | 3x m5.xlarge | ~$530 | +| 200–500 | 3 nodes (8Gi, 4 CPU) | 3 replicas | 4x m5.2xlarge | ~$1,100 | +| 500–1000 | 3 data + 2 search nodes | 3 replicas | 5x m5.2xlarge | ~$1,400 | +| 1000+ | 3 data + 3 search + 3 CM | 3+ replicas | 8x m5.2xlarge | ~$2,200 | + +--- + +## Load Test History + +| # | Date | Config | VUs | p95 | req/s | Bottleneck | +|---|------|--------|-----|-----|-------|-----------| +| 002 | 03-20 | 1 OS (direct, no OSD) | 300 | 16ms | 239 | None | +| 003 | 03-20 | 1 OS (direct, no OSD) | 1500 | 2.28s | 855 | OS CPU 99% | +| 004 | 03-20 | 1 OS + 1 OSD (ALB) | 1000 | 3s+ (broke) | ~0 | OSD 100m CPU | +| 005 | 03-20 | 1 OS + 3 OSD (ALB) | 1000 | 14.57s | 104 | OS CPU 99% | +| 006 | 03-20 | 3 OS + 3 OSD (ALB) | 1000 | 10.57s | 143 | Uneven shards | +| 007 | 03-20 | 3 OS + 3 OSD, 2 replicas | 1000 | **6.32s** | **168** | Primary routing | + +### Key Findings +1. **OSD is the first bottleneck** — default 100m CPU is unusable under load. Minimum 500m request, 2000m limit. +2. **OpenSearch single node saturates at ~100 concurrent dashboard users** through OSD. +3. **3 OS nodes improve throughput 37%** but shard distribution must be balanced. +4. **Data volume directly impacts capacity** — more data = slower queries = fewer concurrent users. +5. **Write/search contention** — continuous indexing from OTel Demo competes with search for CPU (Lucene segment refresh). + +### What We Haven't Tested Yet +- [ ] Balanced shard distribution (increase replica count) +- [ ] 7-day data volume impact +- [ ] Dedicated search nodes (requires remote store) +- [ ] Prometheus under concurrent PromQL load through OSD +- [ ] Browser-based load (real Chromium sessions) +- [ ] WAF impact on throughput diff --git a/load-testing/k6/full-test.js b/load-testing/k6/full-test.js new file mode 100644 index 00000000..d48d90ac --- /dev/null +++ b/load-testing/k6/full-test.js @@ -0,0 +1,192 @@ +// k6 combined load test — runs API-level and browser scenarios together. +// This is the "Phase 3" test from the load testing plan: combined read+write load. +// +// Usage: +// # Port-forward all services: +// kubectl port-forward -n observability-stack svc/opensearch-cluster-master 9200:9200 & +// kubectl port-forward -n observability-stack svc/obs-stack-prometheus-server 9090:80 & +// kubectl port-forward -n observability-stack svc/obs-stack-opensearch-dashboards 5601:5601 & +// +// K6_BROWSER_ENABLED=true k6 run k6/full-test.js +// K6_BROWSER_ENABLED=true k6 run k6/full-test.js --env TARGET_VUS=300 --env BROWSER_VUS=10 + +import http from 'k6/http'; +import { browser } from 'k6/browser'; +import { check, sleep } from 'k6'; + +const TARGET_VUS = parseInt(__ENV.TARGET_VUS || '150'); +const BROWSER_VUS = parseInt(__ENV.BROWSER_VUS || '5'); + +export const options = { + insecureSkipTLSVerify: true, + scenarios: { + // --- API layer: OpenSearch queries --- + api_opensearch: { + executor: 'ramping-vus', + startVUs: 0, + stages: [ + { duration: '2m', target: Math.round(TARGET_VUS * 0.5) }, + { duration: '5m', target: TARGET_VUS }, + { duration: '5m', target: TARGET_VUS }, + { duration: '2m', target: 0 }, + ], + exec: 'apiOpensearch', + }, + // --- API layer: Prometheus queries --- + api_prometheus: { + executor: 'ramping-vus', + startVUs: 0, + stages: [ + { duration: '2m', target: Math.round(TARGET_VUS * 0.25) }, + { duration: '5m', target: Math.round(TARGET_VUS * 0.5) }, + { duration: '5m', target: Math.round(TARGET_VUS * 0.5) }, + { duration: '2m', target: 0 }, + ], + exec: 'apiPrometheus', + }, + // --- Browser: Trace Analytics --- + browser_traces: { + executor: 'constant-vus', + vus: Math.max(1, Math.round(BROWSER_VUS * 0.4)), + duration: '12m', + exec: 'browserTraces', + startTime: '2m', // start after API ramp begins + options: { browser: { type: 'chromium' } }, + }, + // --- Browser: Discover + PPL --- + browser_discover: { + executor: 'constant-vus', + vus: Math.max(1, Math.round(BROWSER_VUS * 0.3)), + duration: '12m', + exec: 'browserDiscover', + startTime: '2m', + options: { browser: { type: 'chromium' } }, + }, + // --- Browser: Metrics dashboards --- + browser_metrics: { + executor: 'constant-vus', + vus: Math.max(1, Math.round(BROWSER_VUS * 0.3)), + duration: '12m', + exec: 'browserMetrics', + startTime: '2m', + options: { browser: { type: 'chromium' } }, + }, + }, + thresholds: { + http_req_duration: ['p(95)<5000'], + http_req_failed: ['rate<0.05'], + browser_web_vital_lcp: ['p(95)<8000'], + }, +}; + +// --- Config --- +const OS_BASE = __ENV.OPENSEARCH_URL || 'https://localhost:9200'; +const PROM_BASE = __ENV.PROMETHEUS_URL || 'http://localhost:9090'; +const DASHBOARDS_URL = __ENV.DASHBOARDS_URL || 'http://localhost:5601'; +const USERNAME = __ENV.OSD_USER || 'admin'; +const PASSWORD = __ENV.OSD_PASSWORD || 'My_password_123!@#'; + +const osParams = { + headers: { 'Content-Type': 'application/json' }, + auth: 'basic', + username: USERNAME, + password: PASSWORD, +}; + +const pplQueries = [ + 'source=otel-v1-apm-span-000001 | head 50', + 'source=otel-v1-apm-span-000001 | stats count() by serviceName', + 'source=otel-v1-apm-span-000001 | stats count() by serviceName, name | sort - count()', + 'source=logs-otel-v1-000001 | stats count() by serviceName', +]; + +const promQueries = [ + 'up', + 'rate(otelcol_exporter_sent_spans_total[5m])', + 'sum by (service_name) (rate(otelcol_exporter_sent_spans_total[5m]))', + 'histogram_quantile(0.99, rate(prometheus_http_request_duration_seconds_bucket{handler="/api/v1/query"}[5m]))', + 'prometheus_tsdb_head_series', +]; + +// --- API functions --- + +export function apiOpensearch() { + const q = pplQueries[Math.floor(Math.random() * pplQueries.length)]; + http.post(`${OS_BASE}/_plugins/_ppl`, JSON.stringify({ query: q }), osParams); + http.post(`${OS_BASE}/otel-v1-apm-span-*/_search`, + JSON.stringify({ size: 50, query: { match_all: {} }, sort: [{ startTime: 'desc' }] }), + osParams); + sleep(Math.random() * 2 + 1); +} + +export function apiPrometheus() { + const q = promQueries[Math.floor(Math.random() * promQueries.length)]; + const now = Math.floor(Date.now() / 1000); + http.get(`${PROM_BASE}/api/v1/query_range?query=${encodeURIComponent(q)}&start=${now - 3600}&end=${now}&step=60`); + sleep(Math.random() * 2 + 1); +} + +// --- Browser functions --- + +async function login(page) { + await page.goto(`${DASHBOARDS_URL}/app/home`); + const userField = await page.locator('[data-test-subj="user-name"]'); + if (await userField.isVisible()) { + await userField.fill(USERNAME); + await page.locator('[data-test-subj="password"]').fill(PASSWORD); + await page.locator('[data-test-subj="submit"]').click(); + await page.waitForNavigation(); + } +} + +export async function browserTraces() { + const ctx = await browser.newContext({ ignoreHTTPSErrors: true }); + const page = await ctx.newPage(); + try { + await login(page); + await page.goto(`${DASHBOARDS_URL}/app/observability-traces#/traces`); + await page.waitForTimeout(5000); + const row = await page.locator('table tbody tr').first(); + if (await row.isVisible()) { + await row.click(); + await page.waitForTimeout(5000); + } + sleep(3); + } finally { + await page.close(); + await ctx.close(); + } +} + +export async function browserDiscover() { + const ctx = await browser.newContext({ ignoreHTTPSErrors: true }); + const page = await ctx.newPage(); + try { + await login(page); + await page.goto(`${DASHBOARDS_URL}/app/data-explorer/discover`); + await page.waitForTimeout(5000); + sleep(3); + } finally { + await page.close(); + await ctx.close(); + } +} + +export async function browserMetrics() { + const ctx = await browser.newContext({ ignoreHTTPSErrors: true }); + const page = await ctx.newPage(); + try { + await login(page); + await page.goto(`${DASHBOARDS_URL}/app/dashboards`); + await page.waitForTimeout(3000); + const link = await page.locator('table tbody tr a').first(); + if (await link.isVisible()) { + await link.click(); + await page.waitForTimeout(8000); + } + sleep(3); + } finally { + await page.close(); + await ctx.close(); + } +} diff --git a/load-testing/k6/scenarios/api-queries-alb.js b/load-testing/k6/scenarios/api-queries-alb.js new file mode 100644 index 00000000..4338386c --- /dev/null +++ b/load-testing/k6/scenarios/api-queries-alb.js @@ -0,0 +1,115 @@ +// k6 API-level load test — hits OpenSearch Dashboards through ALB. +// Simulates the actual HTTP requests that a dashboard user generates. +// +// Usage (from EC2 load generator): +// k6 run --env TARGET_VUS=500 scenarios/api-queries-alb.js +// k6 run --env TARGET_VUS=1000 --env DASHBOARDS_URL=https://your-alb-dns scenarios/api-queries-alb.js + +import http from 'k6/http'; +import { check, sleep } from 'k6'; +import encoding from 'k6/encoding'; + +const TARGET_VUS = parseInt(__ENV.TARGET_VUS || '200'); +const OSD = __ENV.DASHBOARDS_URL || 'https://localhost:5601'; +const USER = __ENV.OSD_USER || 'admin'; +const PASS = __ENV.OSD_PASSWORD || 'My_password_123!@#'; +const AUTH_HEADER = `Basic ${encoding.b64encode(`${USER}:${PASS}`)}`; + +export const options = { + insecureSkipTLSVerify: true, + scenarios: { + osd_queries: { + executor: 'ramping-vus', + startVUs: 0, + stages: [ + { duration: '2m', target: Math.round(TARGET_VUS * 0.25) }, + { duration: '3m', target: Math.round(TARGET_VUS * 0.5) }, + { duration: '5m', target: TARGET_VUS }, + { duration: '3m', target: TARGET_VUS }, + { duration: '2m', target: 0 }, + ], + exec: 'osdLoad', + }, + }, + thresholds: { + http_req_duration: ['p(95)<5000'], + http_req_failed: ['rate<0.05'], + }, +}; + +const headers = { + 'Content-Type': 'application/json', + 'Authorization': AUTH_HEADER, + 'osd-xsrf': 'true', +}; + +// --- PPL queries via OSD's query endpoint --- +const pplQueries = [ + 'source=otel-v1-apm-span-000001 | head 50', + 'source=otel-v1-apm-span-000001 | stats count() by serviceName', + 'source=otel-v1-apm-span-000001 | stats count() by serviceName, kind', + 'source=otel-v1-apm-span-000001 | where durationInNanos > 1000000000 | stats count() by serviceName', + 'source=logs-otel-v1-000001 | head 50', + 'source=logs-otel-v1-000001 | stats count() by severityText', +]; + +// --- PromQL queries via OSD's datasource proxy --- +const promQueries = [ + 'up', + 'rate(otelcol_exporter_sent_spans_total[5m])', + 'sum(rate(otelcol_exporter_sent_spans_total[5m]))', + 'histogram_quantile(0.99, rate(prometheus_http_request_duration_seconds_bucket{handler="/api/v1/query"}[5m]))', + 'prometheus_tsdb_head_series', + 'sum(rate(elasticsearch_indices_search_query_time_seconds[5m]))', + 'sum(elasticsearch_index_stats_query_cache_size)', +]; + +export function osdLoad() { + const action = Math.random(); + + if (action < 0.3) { + // PPL query through OSD + const q = pplQueries[Math.floor(Math.random() * pplQueries.length)]; + const res = http.post(`${OSD}/api/ppl/search`, JSON.stringify({ + query: q, + format: 'jdbc', + }), { headers }); + check(res, { 'PPL 2xx': (r) => r.status >= 200 && r.status < 300 }); + + } else if (action < 0.5) { + // PPL query on logs + const q = pplQueries[Math.floor(Math.random() * pplQueries.length)]; + const res = http.post(`${OSD}/api/ppl/search`, JSON.stringify({ + query: q, + format: 'jdbc', + }), { headers }); + check(res, { 'PPL logs 2xx': (r) => r.status >= 200 && r.status < 300 }); + + } else if (action < 0.7) { + // Direct OpenSearch query through OSD (DSL search) + const res = http.post(`${OSD}/api/console/proxy?path=${encodeURIComponent('otel-v1-apm-span-*/_search?preference=_replica')}&method=POST`, JSON.stringify({ + size: 50, + query: { match_all: {} }, + sort: [{ startTime: 'desc' }], + }), { headers }); + check(res, { 'Search 2xx': (r) => r.status >= 200 && r.status < 400 }); + + } else if (action < 0.85) { + // Load saved objects (simulates opening a dashboard) + const res = http.get( + `${OSD}/api/saved_objects/_find?type=dashboard&per_page=10`, + { headers }, + ); + check(res, { 'Dashboards list 2xx': (r) => r.status >= 200 && r.status < 300 }); + + } else { + // Service map query + const res = http.post(`${OSD}/api/console/proxy?path=${encodeURIComponent('otel-v2-apm-service-map-*/_search?preference=_replica')}&method=POST`, JSON.stringify({ + size: 200, + query: { match_all: {} }, + }), { headers }); + check(res, { 'ServiceMap 2xx': (r) => r.status >= 200 && r.status < 400 }); + } + + sleep(Math.random() * 2 + 0.5); // 0.5-2.5s think time +} diff --git a/load-testing/k6/scenarios/api-queries.js b/load-testing/k6/scenarios/api-queries.js new file mode 100644 index 00000000..8ef49e4f --- /dev/null +++ b/load-testing/k6/scenarios/api-queries.js @@ -0,0 +1,142 @@ +// k6 API-level load test — replays the HTTP queries that OpenSearch Dashboards +// makes under the hood: PPL, _search, PromQL, saved objects. +// +// Usage: +// # Port-forward first: +// kubectl port-forward -n observability-stack svc/opensearch-cluster-master 9200:9200 & +// kubectl port-forward -n observability-stack svc/obs-stack-prometheus-server 9090:80 & +// kubectl port-forward -n observability-stack svc/obs-stack-opensearch-dashboards 5601:5601 & +// +// k6 run scenarios/api-queries.js +// k6 run scenarios/api-queries.js --env TARGET_VUS=500 # override peak + +import http from 'k6/http'; +import { check, sleep } from 'k6'; +import { Rate, Trend } from 'k6/metrics'; + +const TARGET_VUS = parseInt(__ENV.TARGET_VUS || '200'); + +export const options = { + insecureSkipTLSVerify: true, + scenarios: { + opensearch_queries: { + executor: 'ramping-vus', + startVUs: 0, + stages: [ + { duration: '2m', target: Math.round(TARGET_VUS * 0.25) }, + { duration: '3m', target: Math.round(TARGET_VUS * 0.5) }, + { duration: '5m', target: TARGET_VUS }, + { duration: '3m', target: TARGET_VUS }, // hold at peak + { duration: '2m', target: 0 }, + ], + exec: 'opensearchLoad', + }, + prometheus_queries: { + executor: 'ramping-vus', + startVUs: 0, + stages: [ + { duration: '2m', target: Math.round(TARGET_VUS * 0.1) }, + { duration: '3m', target: Math.round(TARGET_VUS * 0.25) }, + { duration: '5m', target: Math.round(TARGET_VUS * 0.5) }, + { duration: '3m', target: Math.round(TARGET_VUS * 0.5) }, + { duration: '2m', target: 0 }, + ], + exec: 'prometheusLoad', + }, + }, + thresholds: { + http_req_duration: ['p(95)<5000'], + http_req_failed: ['rate<0.05'], + }, +}; + +const OS_BASE = __ENV.OPENSEARCH_URL || 'https://localhost:9200'; +const PROM_BASE = __ENV.PROMETHEUS_URL || 'http://localhost:9090'; + +import encoding from 'k6/encoding'; +const OS_USER = __ENV.OSD_USER || 'admin'; +const OS_PASS = __ENV.OSD_PASSWORD || 'My_password_123!@#'; +const OS_AUTH_HEADER = `Basic ${encoding.b64encode(`${OS_USER}:${OS_PASS}`)}`; + +const osParams = { + headers: { + 'Content-Type': 'application/json', + 'Authorization': OS_AUTH_HEADER, + }, +}; + +// --- PPL queries (light → heavy) --- +const pplQueries = [ + 'source=otel-v1-apm-span-000001 | head 50', + 'source=otel-v1-apm-span-000001 | stats count() by serviceName', + 'source=otel-v1-apm-span-000001 | where serviceName="frontend" | stats avg(durationInNanos)', + 'source=otel-v1-apm-span-000001 | stats count() by serviceName, kind', + 'source=otel-v1-apm-span-000001 | where durationInNanos > 1000000000 | stats count() by serviceName', + 'source=logs-otel-v1-000001 | head 50', + 'source=logs-otel-v1-000001 | stats count() by severityText', +]; + +// --- PromQL queries (light → heavy) --- +const promQueries = [ + 'up', + 'rate(otelcol_exporter_sent_spans_total[5m])', + 'sum by (service_name) (rate(otelcol_exporter_sent_spans_total[5m]))', + 'histogram_quantile(0.99, rate(prometheus_http_request_duration_seconds_bucket{handler="/api/v1/query"}[5m]))', + 'rate(prometheus_tsdb_head_samples_appended_total[5m])', + 'prometheus_tsdb_head_series', + 'sum by (job) (rate(otelcol_receiver_accepted_spans_total[5m]))', +]; + +export function opensearchLoad() { + const queryIdx = Math.floor(Math.random() * pplQueries.length); + + // PPL query + const pplRes = http.post( + `${OS_BASE}/_plugins/_ppl`, + JSON.stringify({ query: pplQueries[queryIdx] }), + osParams, + ); + check(pplRes, { 'PPL 2xx': (r) => r.status >= 200 && r.status < 300 }); + + // Discover-style _search + const searchRes = http.post( + `${OS_BASE}/otel-v1-apm-span-*/_search`, + JSON.stringify({ + size: 50, + query: { match_all: {} }, + sort: [{ startTime: 'desc' }], + }), + osParams, + ); + check(searchRes, { 'Search 2xx': (r) => r.status >= 200 && r.status < 300 }); + + // Service map + const smRes = http.post( + `${OS_BASE}/otel-v2-apm-service-map-*/_search`, + JSON.stringify({ size: 200, query: { match_all: {} } }), + osParams, + ); + check(smRes, { 'ServiceMap 2xx': (r) => r.status >= 200 && r.status < 300 }); + + sleep(Math.random() * 2 + 1); // 1-3s think time +} + +export function prometheusLoad() { + const queryIdx = Math.floor(Math.random() * promQueries.length); + const now = Math.floor(Date.now() / 1000); + const oneHourAgo = now - 3600; + + // Instant query + const instantRes = http.get( + `${PROM_BASE}/api/v1/query?query=${encodeURIComponent(promQueries[queryIdx])}`, + ); + check(instantRes, { 'PromQL instant 2xx': (r) => r.status === 200 }); + + // Range query (1h window, 60s step) + const rangeRes = http.get( + `${PROM_BASE}/api/v1/query_range?query=${encodeURIComponent(promQueries[queryIdx])}&start=${oneHourAgo}&end=${now}&step=60`, + ); + check(rangeRes, { 'PromQL range 2xx': (r) => r.status === 200 }); + + sleep(Math.random() * 2 + 1); +} diff --git a/load-testing/k6/scenarios/browser-discover.js b/load-testing/k6/scenarios/browser-discover.js new file mode 100644 index 00000000..a0eddaff --- /dev/null +++ b/load-testing/k6/scenarios/browser-discover.js @@ -0,0 +1,104 @@ +// k6 browser test — Discover + PPL flow in OpenSearch Dashboards. +// Simulates a user opening Discover, selecting an index, running PPL queries. +// +// Usage: +// kubectl port-forward -n observability-stack svc/obs-stack-opensearch-dashboards 5601:5601 & +// K6_BROWSER_ENABLED=true k6 run scenarios/browser-discover.js + +import { browser } from 'k6/browser'; +import { check, sleep } from 'k6'; + +const TARGET_BROWSER_VUS = parseInt(__ENV.BROWSER_VUS || '5'); + +export const options = { + scenarios: { + discover_flow: { + executor: 'ramping-vus', + startVUs: 0, + stages: [ + { duration: '1m', target: 2 }, + { duration: '3m', target: TARGET_BROWSER_VUS }, + { duration: '3m', target: TARGET_BROWSER_VUS }, + { duration: '1m', target: 0 }, + ], + exec: 'discoverFlow', + options: { browser: { type: 'chromium' } }, + }, + }, + thresholds: { + browser_web_vital_lcp: ['p(95)<8000'], + }, +}; + +const DASHBOARDS_URL = __ENV.DASHBOARDS_URL || 'http://localhost:5601'; +const USERNAME = __ENV.OSD_USER || 'admin'; +const PASSWORD = __ENV.OSD_PASSWORD || 'My_password_123!@#'; + +async function login(page) { + await page.goto(`${DASHBOARDS_URL}/app/home`); + const userField = await page.locator('[data-test-subj="user-name"]'); + if (await userField.isVisible()) { + await userField.fill(USERNAME); + await page.locator('[data-test-subj="password"]').fill(PASSWORD); + await page.locator('[data-test-subj="submit"]').click(); + await page.waitForNavigation(); + } +} + +const pplQueries = [ + 'source=otel-v1-apm-span-000001 | head 50', + 'source=otel-v1-apm-span-000001 | stats count() by serviceName', + 'source=otel-v1-apm-span-000001 | where durationInNanos > 1000000000 | stats count() by serviceName', + 'source=logs-otel-v1-000001 | stats count() by serviceName', +]; + +export async function discoverFlow() { + const context = await browser.newContext({ ignoreHTTPSErrors: true }); + const page = await context.newPage(); + + try { + await login(page); + + // Navigate to Discover + await page.goto(`${DASHBOARDS_URL}/app/data-explorer/discover`); + await page.waitForTimeout(3000); + + check(page, { + 'Discover page loaded': () => true, + }); + + // Run a PPL query via the query bar + const query = pplQueries[Math.floor(Math.random() * pplQueries.length)]; + const queryInput = await page.locator('[data-test-subj="queryInput"]'); + if (await queryInput.isVisible()) { + await queryInput.fill(query); + // Submit query + const submitBtn = await page.locator('[data-test-subj="querySubmitButton"]'); + if (await submitBtn.isVisible()) { + await submitBtn.click(); + } + await page.waitForTimeout(5000); // wait for results + } + + check(page, { + 'Query executed': () => true, + }); + + // Change time range to last 24h + const timePicker = await page.locator('[data-test-subj="superDatePickerToggleQuickMenuButton"]'); + if (await timePicker.isVisible()) { + await timePicker.click(); + await page.waitForTimeout(1000); + const last24h = await page.locator('text=Last 24 hours'); + if (await last24h.isVisible()) { + await last24h.click(); + await page.waitForTimeout(3000); + } + } + + sleep(2); + } finally { + await page.close(); + await context.close(); + } +} diff --git a/load-testing/k6/scenarios/browser-metrics.js b/load-testing/k6/scenarios/browser-metrics.js new file mode 100644 index 00000000..2ef1af71 --- /dev/null +++ b/load-testing/k6/scenarios/browser-metrics.js @@ -0,0 +1,103 @@ +// k6 browser test — Metrics visualization flow in OpenSearch Dashboards. +// Simulates users viewing metric panels that query Prometheus (single pod). +// This is the scenario most likely to find the Prometheus breaking point. +// +// Usage: +// kubectl port-forward -n observability-stack svc/obs-stack-opensearch-dashboards 5601:5601 & +// K6_BROWSER_ENABLED=true k6 run scenarios/browser-metrics.js + +import { browser } from 'k6/browser'; +import { check, sleep } from 'k6'; + +const TARGET_BROWSER_VUS = parseInt(__ENV.BROWSER_VUS || '5'); + +export const options = { + scenarios: { + metrics_flow: { + executor: 'ramping-vus', + startVUs: 0, + stages: [ + { duration: '1m', target: 2 }, + { duration: '3m', target: TARGET_BROWSER_VUS }, + { duration: '3m', target: TARGET_BROWSER_VUS }, + { duration: '1m', target: 0 }, + ], + exec: 'metricsFlow', + options: { browser: { type: 'chromium' } }, + }, + }, + thresholds: { + browser_web_vital_lcp: ['p(95)<8000'], + }, +}; + +const DASHBOARDS_URL = __ENV.DASHBOARDS_URL || 'http://localhost:5601'; +const USERNAME = __ENV.OSD_USER || 'admin'; +const PASSWORD = __ENV.OSD_PASSWORD || 'My_password_123!@#'; + +async function login(page) { + await page.goto(`${DASHBOARDS_URL}/app/home`); + const userField = await page.locator('[data-test-subj="user-name"]'); + if (await userField.isVisible()) { + await userField.fill(USERNAME); + await page.locator('[data-test-subj="password"]').fill(PASSWORD); + await page.locator('[data-test-subj="submit"]').click(); + await page.waitForNavigation(); + } +} + +export async function metricsFlow() { + const context = await browser.newContext({ ignoreHTTPSErrors: true }); + const page = await context.newPage(); + + try { + await login(page); + + // Navigate to Observability > Metrics + await page.goto(`${DASHBOARDS_URL}/app/observability-metrics`); + await page.waitForTimeout(5000); + + check(page, { + 'Metrics page loaded': () => true, + }); + + // Try opening a saved dashboard (Pipeline Health or similar) + await page.goto(`${DASHBOARDS_URL}/app/dashboards`); + await page.waitForTimeout(3000); + + // Click first available dashboard + const dashboardLink = await page.locator('table tbody tr a').first(); + if (await dashboardLink.isVisible()) { + await dashboardLink.click(); + await page.waitForTimeout(8000); // dashboards with many panels take time + + check(page, { + 'Dashboard loaded': () => true, + }); + + // Change time range to 7d (stresses Prometheus) + const timePicker = await page.locator('[data-test-subj="superDatePickerToggleQuickMenuButton"]'); + if (await timePicker.isVisible()) { + await timePicker.click(); + await page.waitForTimeout(1000); + const last7d = await page.locator('text=Last 7 days'); + if (await last7d.isVisible()) { + await last7d.click(); + await page.waitForTimeout(10000); // 7d queries are expensive + } + } + + // Refresh the dashboard + const refreshBtn = await page.locator('[data-test-subj="querySubmitButton"]'); + if (await refreshBtn.isVisible()) { + await refreshBtn.click(); + await page.waitForTimeout(8000); + } + } + + sleep(2); + } finally { + await page.close(); + await context.close(); + } +} diff --git a/load-testing/k6/scenarios/browser-traces.js b/load-testing/k6/scenarios/browser-traces.js new file mode 100644 index 00000000..3d1c2566 --- /dev/null +++ b/load-testing/k6/scenarios/browser-traces.js @@ -0,0 +1,100 @@ +// k6 browser test — Trace Analytics flow in OpenSearch Dashboards. +// Simulates a user navigating to Traces, clicking into a trace, viewing spans. +// +// Usage: +// kubectl port-forward -n observability-stack svc/obs-stack-opensearch-dashboards 5601:5601 & +// K6_BROWSER_ENABLED=true k6 run scenarios/browser-traces.js + +import { browser } from 'k6/browser'; +import { check, sleep } from 'k6'; + +const TARGET_BROWSER_VUS = parseInt(__ENV.BROWSER_VUS || '5'); + +export const options = { + scenarios: { + traces_flow: { + executor: 'ramping-vus', + startVUs: 0, + stages: [ + { duration: '1m', target: 2 }, + { duration: '3m', target: TARGET_BROWSER_VUS }, + { duration: '3m', target: TARGET_BROWSER_VUS }, + { duration: '1m', target: 0 }, + ], + exec: 'tracesFlow', + options: { browser: { type: 'chromium' } }, + }, + }, + thresholds: { + browser_web_vital_lcp: ['p(95)<8000'], + browser_web_vital_cls: ['p(95)<0.25'], + }, +}; + +const DASHBOARDS_URL = __ENV.DASHBOARDS_URL || 'http://localhost:5601'; +const USERNAME = __ENV.OSD_USER || 'admin'; +const PASSWORD = __ENV.OSD_PASSWORD || 'My_password_123!@#'; + +async function login(page) { + await page.goto(`${DASHBOARDS_URL}/app/home`); + // Check if login page appears + const userField = await page.locator('[data-test-subj="user-name"]'); + if (await userField.isVisible()) { + await userField.fill(USERNAME); + await page.locator('[data-test-subj="password"]').fill(PASSWORD); + await page.locator('[data-test-subj="submit"]').click(); + await page.waitForNavigation(); + } +} + +export async function tracesFlow() { + const context = await browser.newContext({ ignoreHTTPSErrors: true }); + const page = await context.newPage(); + + try { + await login(page); + + // Navigate to Trace Analytics + await page.goto(`${DASHBOARDS_URL}/app/observability-traces#/traces`); + await page.waitForTimeout(3000); + + // Wait for trace table to load + const table = await page.locator('table'); + await table.waitFor({ state: 'visible', timeout: 15000 }); + + check(page, { + 'Traces page loaded': () => true, + }); + + // Click first trace row if available + const firstRow = await page.locator('table tbody tr').first(); + if (await firstRow.isVisible()) { + await firstRow.click(); + await page.waitForTimeout(5000); // wait for span waterfall + + check(page, { + 'Trace detail loaded': () => true, + }); + } + + // Navigate to Services + await page.goto(`${DASHBOARDS_URL}/app/observability-traces#/services`); + await page.waitForTimeout(3000); + + check(page, { + 'Services page loaded': () => true, + }); + + // Click first service if available + const serviceRow = await page.locator('table tbody tr').first(); + if (await serviceRow.isVisible()) { + await serviceRow.click(); + await page.waitForTimeout(5000); + } + + sleep(2); + } finally { + await page.close(); + await context.close(); + } +} diff --git a/load-testing/osb/index-settings.json b/load-testing/osb/index-settings.json new file mode 100644 index 00000000..46c218c5 --- /dev/null +++ b/load-testing/osb/index-settings.json @@ -0,0 +1,25 @@ +{ + "settings": { + "index": { + "number_of_shards": 1, + "number_of_replicas": 0 + } + }, + "mappings": { + "properties": { + "traceId": { "type": "keyword" }, + "spanId": { "type": "keyword" }, + "parentSpanId": { "type": "keyword" }, + "serviceName": { "type": "keyword" }, + "name": { "type": "keyword" }, + "kind": { "type": "keyword" }, + "startTime": { "type": "date_nanos" }, + "endTime": { "type": "date_nanos" }, + "durationInNanos": { "type": "long" }, + "status.code": { "type": "integer" }, + "resource.attributes.service@name": { "type": "keyword" }, + "resource.attributes.gen_ai@agent@name": { "type": "keyword" }, + "resource.attributes.gen_ai@operation@name": { "type": "keyword" } + } + } +} diff --git a/load-testing/osb/run-osb.sh b/load-testing/osb/run-osb.sh new file mode 100755 index 00000000..80f9e8a3 --- /dev/null +++ b/load-testing/osb/run-osb.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +# Run OpenSearch Benchmark against the cluster. +# Prerequisites: pip install opensearch-benchmark +# +# Usage: +# # Port-forward first: +# kubectl port-forward -n observability-stack svc/opensearch-cluster-master 9200:9200 +# +# ./run-osb.sh # standard benchmark +# ./run-osb.sh --redline-test # find breaking point automatically + +set -euo pipefail + +HOST="${OPENSEARCH_HOST:-https://localhost:9200}" +USER="${OPENSEARCH_USER:-admin}" +PASS="${OPENSEARCH_PASSWORD:-My_password_123!@#}" +WORKLOAD_DIR="$(cd "$(dirname "$0")" && pwd)" + +if [[ "${1:-}" == "--redline-test" ]]; then + echo "🔴 Running redline test (auto-ramp to breaking point)..." + opensearch-benchmark execute-test \ + --target-hosts="$HOST" \ + --pipeline=benchmark-only \ + --workload-path="$WORKLOAD_DIR" \ + --client-options="use_ssl:true,verify_certs:false,basic_auth_user:${USER},basic_auth_password:${PASS}" \ + --redline-test +else + echo "📊 Running standard benchmark..." + opensearch-benchmark execute-test \ + --target-hosts="$HOST" \ + --pipeline=benchmark-only \ + --workload-path="$WORKLOAD_DIR" \ + --client-options="use_ssl:true,verify_certs:false,basic_auth_user:${USER},basic_auth_password:${PASS}" +fi diff --git a/load-testing/osb/workload.json b/load-testing/osb/workload.json new file mode 100644 index 00000000..58eaa1a5 --- /dev/null +++ b/load-testing/osb/workload.json @@ -0,0 +1,99 @@ +{ + "short_description": "Observability Stack trace/log workload matching otel-v1-apm-span and logs-otel-v1 index shapes", + "description": "Custom workload for OpenSearch Benchmark that generates documents matching the OTLP trace and log index patterns used by the observability stack.", + "indices": [ + { + "name": "otel-v1-apm-span-loadtest", + "body": "index-settings.json" + } + ], + "operations": [ + { + "name": "bulk-index-traces", + "operation-type": "bulk", + "bulk-size": 500, + "index": "otel-v1-apm-span-loadtest" + }, + { + "name": "search-by-service", + "operation-type": "search", + "index": "otel-v1-apm-span-*", + "body": { + "size": 50, + "query": { + "term": { "serviceName": "load-test-traces" } + }, + "sort": [{ "startTime": "desc" }] + } + }, + { + "name": "agg-by-service", + "operation-type": "search", + "index": "otel-v1-apm-span-*", + "body": { + "size": 0, + "aggs": { + "services": { + "terms": { "field": "serviceName", "size": 50 }, + "aggs": { + "avg_duration": { "avg": { "field": "durationInNanos" } }, + "error_count": { + "filter": { "term": { "status.code": 2 } } + } + } + } + } + } + }, + { + "name": "service-map-query", + "operation-type": "search", + "index": "otel-v2-apm-service-map-*", + "body": { + "size": 200, + "query": { "match_all": {} } + } + }, + { + "name": "search-logs", + "operation-type": "search", + "index": "logs-otel-v1-*", + "body": { + "size": 50, + "query": { "match_all": {} }, + "sort": [{ "time": "desc" }] + } + } + ], + "schedule": [ + { + "operation": "bulk-index-traces", + "warmup-time-period": 60, + "clients": 4 + }, + { + "operation": "search-by-service", + "warmup-iterations": 50, + "iterations": 200, + "clients": 8 + }, + { + "operation": "agg-by-service", + "warmup-iterations": 20, + "iterations": 100, + "clients": 8 + }, + { + "operation": "service-map-query", + "warmup-iterations": 20, + "iterations": 100, + "clients": 4 + }, + { + "operation": "search-logs", + "warmup-iterations": 50, + "iterations": 200, + "clients": 8 + } + ] +} diff --git a/load-testing/pipeline/run-telemetrygen.sh b/load-testing/pipeline/run-telemetrygen.sh new file mode 100755 index 00000000..463d09b1 --- /dev/null +++ b/load-testing/pipeline/run-telemetrygen.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash +# Pipeline throughput test — ramps telemetrygen rate to find breaking point. +# Prerequisites: telemetrygen installed +# go install github.com/open-telemetry/opentelemetry-collector-contrib/cmd/telemetrygen@latest +# +# Usage: +# # Port-forward first: +# kubectl port-forward -n observability-stack svc/obs-stack-opentelemetry-collector 4317:4317 +# +# ./run-telemetrygen.sh # default: traces +# ./run-telemetrygen.sh logs # test log pipeline +# ./run-telemetrygen.sh metrics # test metrics pipeline +# ./run-telemetrygen.sh all # test all three + +set -euo pipefail + +ENDPOINT="${OTEL_ENDPOINT:-localhost:4317}" +DURATION="${DURATION:-3m}" +SIGNAL="${1:-traces}" +RATES=(50 100 250 500 1000 2500 5000) + +run_step() { + local signal="$1" rate="$2" + echo "" + echo "==========================================" + echo " ${signal} @ ${rate}/sec for ${DURATION}" + echo "==========================================" + telemetrygen "$signal" \ + --otlp-endpoint="$ENDPOINT" \ + --otlp-insecure \ + --rate="$rate" \ + --duration="$DURATION" \ + --service="load-test-${signal}" \ + --otlp-attributes='gen_ai.agent.name="load-test"' \ + 2>&1 | tail -5 + echo "--- Sleeping 30s before next step ---" + sleep 30 +} + +run_signal() { + local signal="$1" + echo "" + echo "############################################" + echo " Starting ${signal} ramp test" + echo " Endpoint: ${ENDPOINT}" + echo " Duration per step: ${DURATION}" + echo " Rates: ${RATES[*]}" + echo "############################################" + for rate in "${RATES[@]}"; do + run_step "$signal" "$rate" + done + echo "" + echo "✅ ${signal} ramp complete" +} + +case "$SIGNAL" in + all) + for s in traces logs metrics; do run_signal "$s"; done + ;; + traces|logs|metrics) + run_signal "$SIGNAL" + ;; + *) + echo "Usage: $0 [traces|logs|metrics|all]" + exit 1 + ;; +esac diff --git a/load-testing/results/001-api-queries-auth-bug.md b/load-testing/results/001-api-queries-auth-bug.md new file mode 100644 index 00000000..59524964 --- /dev/null +++ b/load-testing/results/001-api-queries-auth-bug.md @@ -0,0 +1,48 @@ +# Test 001: API Query Load (Auth Bug) + +**Status:** ⚠️ Invalid — OpenSearch auth failure +**Script:** `k6/scenarios/api-queries.js` +**Start:** 2026-03-20 12:04:00 PDT +**End:** 2026-03-20 12:19:01 PDT +**Duration:** 15m01s + +## Parameters +- OpenSearch VUs: 200 (ramping) +- Prometheus VUs: 100 (ramping) +- Total peak VUs: 300 +- Background: OTel Demo load generator active + +## Summary + +| Metric | Value | +|--------|-------| +| Total iterations | 81,422 | +| Total HTTP requests | 217,392 | +| Requests/sec | 241 | +| http_req_duration p(50) | 1.12ms | +| http_req_duration p(90) | 2.47ms | +| http_req_duration p(95) | 3.45ms | +| http_req_duration max | 139.92ms | +| http_req_failed | 75.27% | + +## Per-Check Breakdown + +| Check | Pass | Fail | Rate | Notes | +|-------|------|------|------|-------| +| PPL 2xx | 0 | 54,548 | 0% | Auth failure | +| Search 2xx | 0 | 54,548 | 0% | Auth failure | +| ServiceMap 2xx | 0 | 54,548 | 0% | Auth failure | +| PromQL instant 2xx | 26,874 | 0 | 100% | ✅ | +| PromQL range 2xx | 26,874 | 0 | 100% | ✅ | + +## Root Cause + +k6's `auth: 'basic'` parameter with spread `...OS_AUTH` does not work as expected. OpenSearch returned immediate rejections (avg 1.6ms response = 401/403, not timeout). All OpenSearch data points are invalid. + +## Valid Takeaway + +Prometheus (single pod, no resource limits) handled 100 concurrent VUs doing instant + range PromQL queries with 100% success and p95 of 3.45ms. Not stressed at this level. + +## Fix Applied + +Switched to manual `Authorization: Basic ` header using `k6/encoding` module. diff --git a/load-testing/results/002-api-queries.md b/load-testing/results/002-api-queries.md new file mode 100644 index 00000000..9af6724d --- /dev/null +++ b/load-testing/results/002-api-queries.md @@ -0,0 +1,53 @@ +# Test 002: API Query Load (Auth Fixed) + +**Status:** ✅ Passed — no failures +**Script:** `k6/scenarios/api-queries.js` +**Start:** 2026-03-20 12:42:14 PDT (19:42:14 UTC) +**End:** 2026-03-20 12:57:16 PDT (19:57:16 UTC) +**Duration:** 15m02s + +## Parameters +- OpenSearch VUs: 200 (ramping 0→50→100→200, hold 3m, ramp down) +- Prometheus VUs: 100 (ramping 0→25→50→100, hold 3m, ramp down) +- Total peak VUs: 300 +- Background: OTel Demo load generator active + +## Summary + +| Metric | Value | +|--------|-------| +| Total iterations | 80,879 | +| Total HTTP requests | 215,779 | +| Requests/sec | 239 | +| http_req_duration p(50) | 5.93ms | +| http_req_duration p(90) | 12.34ms | +| http_req_duration p(95) | 16.15ms | +| http_req_duration max | 543.18ms | +| http_req_failed | 0.00% | +| Data received | 11 GB (12 MB/s) | + +## Per-Check Breakdown + +| Check | Pass | Fail | Rate | +|-------|------|------|------| +| PPL 2xx | 54,148 | 0 | 100% ✅ | +| Search 2xx | 54,148 | 0 | 100% ✅ | +| ServiceMap 2xx | 54,148 | 0 | 100% ✅ | +| PromQL instant 2xx | 26,667 | 0 | 100% ✅ | +| PromQL range 2xx | 26,668 | 0 | 100% ✅ | + +## Analysis + +**The stack did not break at 300 concurrent API VUs (200 OpenSearch + 100 Prometheus).** + +- All thresholds passed: p95 latency 16.15ms (well under 5s threshold), 0% error rate +- OpenSearch single node handled 200 concurrent PPL + _search + service map queries without degradation +- Prometheus single pod handled 100 concurrent instant + range PromQL queries at p95 of ~16ms +- Max latency spike was 543ms — a single outlier, not sustained degradation +- Throughput was steady at ~239 req/s throughout the hold period + +**Conclusion:** 300 VUs is not the breaking point. Need to ramp significantly higher (500–1000+ VUs) to find where things start to degrade. + +## Next Steps +- Run Test 003 with TARGET_VUS=500 (750 total VUs) to push harder +- If that holds, jump to TARGET_VUS=1000 diff --git a/load-testing/results/003-api-queries-1500vu.md b/load-testing/results/003-api-queries-1500vu.md new file mode 100644 index 00000000..d1b9595b --- /dev/null +++ b/load-testing/results/003-api-queries-1500vu.md @@ -0,0 +1,53 @@ +# Test 003: API Query Load — 1500 VUs (Finding the Ceiling) + +**Status:** ⚠️ Passed but showing significant latency degradation +**Script:** `k6/scenarios/api-queries.js` +**Start:** 2026-03-20 12:57:50 PDT (19:57:50 UTC) +**End:** 2026-03-20 13:12:53 PDT (20:12:53 UTC) +**Duration:** 15m03s + +## Parameters +- OpenSearch VUs: 1000 (ramping) +- Prometheus VUs: 500 (ramping) +- Total peak VUs: 1500 +- Background: OTel Demo load generator active + +## Summary + +| Metric | Test 002 (300 VUs) | Test 003 (1500 VUs) | Delta | +|--------|-------------------|---------------------|-------| +| Total requests | 215,779 | 771,403 | 3.6x | +| Requests/sec | 239 | 855 | 3.6x | +| http_req_duration p(50) | 5.93ms | 13.67ms | 2.3x ⚠️ | +| http_req_duration p(90) | 12.34ms | 1.04s | 84x 🔴 | +| http_req_duration p(95) | 16.15ms | 2.28s | 141x 🔴 | +| http_req_duration max | 543ms | 5.49s | 10x 🔴 | +| http_req_failed | 0.00% | 0.00% | — | +| Data received | 11 GB | 34 GB | 3x | + +## Analysis + +**No errors, but the system is clearly saturated at 1500 VUs.** + +- p50 only doubled (5.9ms → 13.7ms) — the median request is still fast +- p90 exploded from 12ms to 1.04s — the tail is getting crushed +- p95 hit 2.28s — approaching the 5s threshold +- Max latency hit 5.49s — individual requests are timing out +- Iteration duration p95 hit 5.16s (vs 2.91s at 300 VUs) + +**The breaking point is between 300 and 1500 VUs.** The system handles the load without errors but latency degrades severely. At 1500 VUs, 10% of requests take over 1 second and 5% take over 2.3 seconds. + +**For a dashboard user experience**, p95 > 2s means the UI feels sluggish. A reasonable "usable" threshold would be p95 < 500ms, which was comfortably met at 300 VUs but blown past at 1500. + +## Estimated Capacity + +| User Experience | Estimated Max VUs | p95 Latency | +|----------------|-------------------|-------------| +| Excellent (< 100ms p95) | ~300 | 16ms | +| Good (< 500ms p95) | ~500-700 (estimated) | ~500ms | +| Degraded (< 2s p95) | ~1200-1500 | ~2s | +| Broken (errors appear) | > 1500 (not yet found) | > 5s | + +## Next Steps +- Run Test 004 at TARGET_VUS=500 to find the "good experience" ceiling +- Or jump to TARGET_VUS=2000 to find where errors actually start diff --git a/load-testing/results/004-alb-1000vu-osd-bottleneck.md b/load-testing/results/004-alb-1000vu-osd-bottleneck.md new file mode 100644 index 00000000..baf8a365 --- /dev/null +++ b/load-testing/results/004-alb-1000vu-osd-bottleneck.md @@ -0,0 +1,70 @@ +# Test 004: ALB End-to-End Load Test — 1000 VUs from EC2 + +**Status:** 🔴 Broke immediately — massive latency, multiple error types +**Script:** `k6/scenarios/api-queries-alb.js` +**Start:** 2026-03-20 14:55:00 PDT (21:55:00 UTC) +**End:** 2026-03-20 ~14:59:00 PDT (interrupted — already broken) +**Duration:** ~4 min before manual stop +**Source:** EC2 m5.xlarge in same VPC → ALB → OSD → OpenSearch/Prometheus + +## Parameters +- Target VUs: 1000 (ramping) +- Source: EC2 `i-08f9652631fe73302` in same VPC +- Path: EC2 → ALB (TLS) → OSD → OpenSearch/Prometheus +- Background: OTel Demo load generator active + +## What Broke + +### 1. OpenSearch Dashboards is the bottleneck (100m CPU / 512M memory) + +Every request through OSD took **1.3–3.6 seconds** even for simple operations: +- PPL search: 3,199ms – 3,590ms response times +- Saved objects list: 3,306ms – 3,503ms +- Console proxy: 2,298ms – 2,502ms + +OSD is a Node.js single-threaded server with **100m CPU limit** (0.1 cores). Under 1000 concurrent connections, it's completely CPU-starved. The event loop is blocked processing requests sequentially. + +### 2. Console proxy returns 400 for search/service-map queries + +`POST /api/console/proxy` with `opensearch-endpoint` header returns 400. The console proxy API requires different parameters than what the script sends. These need to be fixed in the script, but the latency issue is the real finding. + +### 3. Prometheus datasource proxy returns 404 + +`GET /api/datasources/proxy/ObservabilityStack_Prometheus/...` returns 404. OSD doesn't expose a datasource proxy at that path — PromQL queries go through a different internal API. Script needs fixing, but again the OSD bottleneck is the headline. + +### 4. OpenSearch itself is fine + +- JVM Heap: 55% (285MB / 512MB) — not stressed +- OS CPU: 8% — barely working +- Thread pool rejections: 0 +- Cluster status: yellow (normal for single-node) +- OS Memory: 99% — high but stable (JVM + OS caches) + +### 5. No pod crashes or OOMs + +All pods stayed running. No restarts. The system degraded gracefully — it didn't crash, it just became unusably slow. + +## Root Cause Analysis + +**The bottleneck is OpenSearch Dashboards, not OpenSearch.** + +| Component | CPU Limit | Memory Limit | Status Under Load | +|-----------|-----------|--------------|-------------------| +| **OSD** | **100m (0.1 cores)** | **512M** | **🔴 Saturated — 3s+ response times** | +| OpenSearch | 500m (no limit) | 2Gi | ✅ Fine — 55% heap, 8% CPU | +| Prometheus | none | none | ✅ Fine (not reached — OSD blocked) | +| Data Prepper | none | none | ✅ Fine | + +OSD is the gateway for all user traffic. With 100m CPU, it can handle roughly **5-10 concurrent requests** before the Node.js event loop saturates. At 1000 VUs, requests queue up and each takes 3+ seconds just waiting for OSD to process them. + +## Recommendations + +1. **Increase OSD CPU limit**: 100m → 1000m (1 core) minimum, 2000m for production +2. **Increase OSD memory**: 512M → 1Gi minimum +3. **Scale OSD replicas**: Add 2-3 replicas behind the ALB for horizontal scaling +4. **Fix k6 script**: Console proxy and Prometheus proxy endpoints need correct API paths +5. **Re-run test** after OSD scaling to find the next bottleneck (likely OpenSearch) + +## Key Insight + +Previous tests via port-forward (Tests 001-003) were testing OpenSearch directly, bypassing OSD entirely. The real user path goes through OSD, which is severely under-resourced at 100m CPU. This is the first thing to fix before any other capacity tuning matters. diff --git a/load-testing/results/005-alb-1000vu-opensearch-bottleneck.md b/load-testing/results/005-alb-1000vu-opensearch-bottleneck.md new file mode 100644 index 00000000..e526c7ea --- /dev/null +++ b/load-testing/results/005-alb-1000vu-opensearch-bottleneck.md @@ -0,0 +1,98 @@ +# Test 005: ALB E2E — 1000 VUs, OSD Scaled to 3 Replicas + +**Status:** ⚠️ 0% errors but p95=14.57s — OpenSearch is now the bottleneck +**Script:** `k6/scenarios/api-queries-alb.js` +**Start:** 2026-03-20 15:08:58 PDT (22:08:58 UTC) +**End:** 2026-03-20 15:24:01 PDT (22:24:01 UTC) +**Duration:** 15m01s +**Source:** EC2 m5.xlarge in same VPC → ALB → OSD (3 replicas) → OpenSearch + +## Configuration Changes (from Test 004) +- OSD: 1 replica (100m CPU, 512M) → **3 replicas (2 CPU, 2Gi each)** + +## k6 Summary + +| Metric | Test 004 (1x OSD 100m) | Test 005 (3x OSD 2CPU) | +|--------|------------------------|------------------------| +| Total requests | ~few hundred (broke immediately) | 93,912 | +| Requests/sec | N/A | 104 | +| http_req_duration p(50) | 3+ seconds | 824ms | +| http_req_duration p(90) | N/A | 13.89s | +| http_req_duration p(95) | N/A | **14.57s** 🔴 | +| http_req_duration max | N/A | 16.95s | +| http_req_failed | immediate failures | **0.00%** ✅ | +| Data received | N/A | 5.4 GB | + +## Per-Check Breakdown + +| Check | Rate | Notes | +|-------|------|-------| +| PPL 2xx | 100% ✅ | Working through OSD | +| PPL logs 2xx | 100% ✅ | Working | +| Search 2xx | 100% ✅ | Console proxy fixed | +| ServiceMap 2xx | 100% ✅ | Console proxy fixed | +| Dashboards list 2xx | 100% ✅ | Saved objects API | + +## OpenSearch Cluster During Test + +| Metric | Value | Notes | +|--------|-------|-------| +| CPU | **99-100%** | Pegged for entire test | +| JVM Heap | 34-78% (oscillating) | GC keeping up but under pressure | +| Search threads | 7 (pool size) | Only 7 concurrent searches possible | +| Search queue peak | **34** | Queries waiting in line | +| Search rejections | 0 | Queue didn't overflow (size=1000) | +| Write threads | 4 active | OTel Demo continuously indexing | +| Write queue | 6 | Steady write backlog | + +## Hot Threads Analysis + +Top CPU consumer: **write thread doing Lucene segment refresh** (`ReferenceManager.maybeRefreshBlocking`). The OTel Demo's continuous indexing forces segment refreshes that contend with search threads for CPU and lock access. + +## Root Cause + +**OpenSearch single node (4 vCPU) is CPU-saturated.** + +- Search thread pool: 7 threads on 4 vCPU — can't parallelize enough +- Write/refresh contention: indexing from OTel Demo competes with search for CPU +- JVM heap at 512MB (50% of 1Gi request) — adequate but tight +- Single node = all shards, all searches, all writes on one box + +## OSD Bottleneck: RESOLVED ✅ + +Scaling OSD from 1×100m to 3×2CPU completely eliminated the OSD bottleneck: +- Median response dropped from 3+ seconds to 824ms +- 0% error rate (was failing immediately before) +- OSD is no longer the constraint + +## Recommendations for Next Test + +1. **Scale OpenSearch horizontally**: Add dedicated search nodes (separate from data/ingest) +2. **Increase OpenSearch JVM heap**: 512MB → 2GB+ for query caching +3. **Consider node roles**: Dedicated cluster-manager, data, and search nodes +4. Follow OpenSearch official scaling guide for search-heavy workloads + +## OpenSearch Scaling Strategy (from official docs) + +Reference: [Separate index and search workloads](https://docs.opensearch.org/3.4/tuning-your-cluster/separate-index-and-search-workloads/) + +### Option A: Simple horizontal scaling (recommended first step) +Add more data nodes to spread shards and search threads across nodes. No architecture change needed. +- Current: 1 node (4 vCPU, 7 search threads, 99% CPU) +- Target: 3 data nodes → 21 search threads, ~33% CPU each + +### Option B: Dedicated search nodes (official OpenSearch approach) +Requires remote store (S3) + segment replication. Provides full isolation between indexing and search. +- Configure nodes with `node.roles: [search]` +- Add `number_of_search_replicas` to indices +- Search replicas are allocated only to search nodes +- Enables independent scaling of search vs ingest capacity +- Can use `_scale` API to turn off write workloads for read-heavy indices + +### Option C: Bigger instance type (vertical scaling) +Switch from m5.xlarge (4 vCPU) to m5.2xlarge (8 vCPU) or r5.2xlarge (8 vCPU, 64GB RAM). +- Doubles search thread pool immediately +- More JVM heap for query caching +- Simplest change but has a ceiling + +### Recommended approach: Start with Option A (3 data nodes), then Option C if needed, then Option B for production. diff --git a/load-testing/results/006-alb-1000vu-3node-opensearch.md b/load-testing/results/006-alb-1000vu-3node-opensearch.md new file mode 100644 index 00000000..5aa01bbf --- /dev/null +++ b/load-testing/results/006-alb-1000vu-3node-opensearch.md @@ -0,0 +1,53 @@ +# Test 006: ALB E2E — 1000 VUs, 3-Node OpenSearch Cluster + +**Status:** ⚠️ Improved but p95 still high — uneven shard distribution +**Script:** `k6/scenarios/api-queries-alb.js` +**Start:** 2026-03-20 15:47:44 PDT (22:47:44 UTC) +**End:** 2026-03-20 16:02:47 PDT (23:02:47 UTC) +**Duration:** 15m01s +**Source:** EC2 m5.xlarge → ALB → 3x OSD → 3x OpenSearch + +## Configuration Changes (from Test 005) +- OpenSearch: 1 node (500m CPU, 2Gi, 1Gi JVM) → **3 nodes (2 CPU, 4Gi, 2Gi JVM each)** +- EKS: 2 nodes → **4 nodes** (m5.xlarge) + +## Comparison + +| Metric | Test 005 (1 OS node) | Test 006 (3 OS nodes) | Delta | +|--------|---------------------|----------------------|-------| +| Total requests | 93,912 | **129,083** | +37% ✅ | +| Requests/sec | 104 | **143** | +37% ✅ | +| p(50) | 824ms | **1.1s** | worse ⚠️ | +| p(90) | 13.89s | **7.09s** | 49% better ✅ | +| p(95) | 14.57s | **10.57s** | 27% better ✅ | +| max | 16.95s | 18.12s | similar | +| Error rate | 0% | **0%** | ✅ | +| Data received | 5.4 GB | **7.3 GB** | +35% | + +## Cluster Observations During Test + +| Node | Heap % | Load 1m | Search Queries | Search Queue Peak | +|------|--------|---------|----------------|-------------------| +| master-0 | 36-67% | **6-8** | 14,422 | 26 | +| master-1 | 47-78% | **1.9-2.8** | 18,886 | 23 | +| master-2 | 38-76% | **1.1-1.9** | 4,188 | 1 | + +**Key finding: Uneven shard distribution.** Node-2 handled only 4,188 searches vs 18,886 on Node-1. The shards from the original single-node cluster are concentrated on Node-0 and Node-1. Node-2 has few shards and is underutilized. + +## Analysis + +- **37% more throughput** (143 vs 104 req/s) — the extra nodes help +- **p90 halved** (7s vs 14s) — significant improvement in tail latency +- **Still too slow** — p95 of 10.57s means 5% of requests take >10 seconds +- **Uneven load** — Node-2 is barely working while Node-0 is overloaded (load_1m=8) +- **Zero rejections** — search thread pools not overflowing + +## Root Cause + +Shard allocation is unbalanced. The original indices were created with 1 primary shard on the single node. With 3 nodes, the primary stays on one node and replicas go to others, but the search routing still favors the primary. + +## Next Steps + +1. **Rebalance shards** — force shard reallocation or increase replica count +2. **Increase shard count** — more shards = better distribution across nodes +3. **Consider dedicated search nodes** — for full isolation (requires remote store) diff --git a/load-testing/results/007-alb-1000vu-balanced-shards.md b/load-testing/results/007-alb-1000vu-balanced-shards.md new file mode 100644 index 00000000..e603b6cf --- /dev/null +++ b/load-testing/results/007-alb-1000vu-balanced-shards.md @@ -0,0 +1,65 @@ +# Test 007: ALB E2E — 1000 VUs, 3-Node OpenSearch, Balanced Shards + +**Status:** ✅ Significant improvement — p95 down 40% from Test 006 +**Script:** `k6/scenarios/api-queries-alb.js` +**Start:** 2026-03-20 16:18:26 PDT (23:18:26 UTC) +**End:** 2026-03-20 16:33:30 PDT (23:33:30 UTC) +**Duration:** 15m02s +**Source:** EC2 m5.xlarge → ALB → 3x OSD → 3x OpenSearch + +## Configuration Change (from Test 006) +- Set `number_of_replicas: 2` on all data indices (was 1) +- Every node now has a copy of every shard (3 copies total) +- No other changes + +## Comparison + +| Metric | Test 005 (1 node) | Test 006 (3 nodes, 1 replica) | Test 007 (3 nodes, 2 replicas) | Delta 006→007 | +|--------|-------------------|-------------------------------|-------------------------------|---------------| +| Total requests | 93,912 | 129,083 | **152,035** | +18% ✅ | +| Requests/sec | 104 | 143 | **168** | +18% ✅ | +| p(50) | 824ms | 1.1s | **1.43s** | worse ⚠️ | +| p(90) | 13.89s | 7.09s | **4.92s** | 31% better ✅ | +| p(95) | 14.57s | 10.57s | **6.32s** | 40% better ✅ | +| max | 16.95s | 18.12s | 60s (1 timeout) | ⚠️ | +| Error rate | 0% | 0% | **0.00%** (1 of 152k) | ✅ | + +## Cumulative Improvement (Test 005 → 007) + +| Metric | Test 005 | Test 007 | Improvement | +|--------|----------|----------|-------------| +| Throughput | 104 req/s | **168 req/s** | **+62%** | +| p(95) | 14.57s | **6.32s** | **57% faster** | +| p(90) | 13.89s | **4.92s** | **65% faster** | + +## Node Distribution During Test + +| Node | Search Queries | Load 1m (peak) | Heap % Range | +|------|---------------|----------------|-------------| +| master-0 (primaries) | 98,771 | **8.0** | 36-78% | +| master-1 | 129,613 | **2.1** | 40-76% | +| master-2 | 52,898 | **5.8** | 35-77% | + +**Improvement over Test 006:** Node-2 went from 4,188 → 52,898 queries (12.6x more). Load is much better distributed but still not perfectly even — Node-0 still gets primary preference. + +## Analysis + +- **40% p95 improvement** from just adding replicas — confirms shard imbalance was a major factor +- **168 req/s** throughput — 62% better than single-node baseline +- **Node-0 still overloaded** (load_1m=8) — it holds all primary shards and gets routing preference +- **1 timeout** (60s max) — likely a single request that hit during a GC pause or segment merge +- **p50 got slightly worse** (1.43s vs 1.1s) — more replication overhead, but tail latency improved significantly + +## Remaining Bottleneck + +Node-0 is still doing disproportionate work because it holds all primary shards. OpenSearch's adaptive replica selection prefers primaries. Options: +1. Force reindex to spread primaries across nodes +2. Set `preference=_replica` on search requests to avoid primaries +3. Move to dedicated search nodes (production path) + +## Next Steps + +1. Try `preference=_replica` search routing to offload Node-0 +2. Consider increasing primary shard count for new indices (ISM template) +3. Run 300 VU test to find the "good experience" threshold +4. Let data accumulate to 7 days and re-test diff --git a/load-testing/run-remote.sh b/load-testing/run-remote.sh new file mode 100755 index 00000000..55f2e7df --- /dev/null +++ b/load-testing/run-remote.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +# Upload k6 scripts to the load generator EC2 and optionally run a test. +# +# Usage: +# ./run-remote.sh # upload scripts only +# ./run-remote.sh 500 # upload + run with 500 VUs +# ./run-remote.sh 1000 api-queries-alb.js # upload + run specific script +# +# Prerequisites: +# - terraform apply in load-testing/terraform/ +# - EC2 key pair configured (or use SSM) + +set -euo pipefail +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" + +# Get EC2 IP from terraform +cd "$SCRIPT_DIR/terraform" +IP=$(terraform output -raw public_ip 2>/dev/null) +KEY_NAME=$(terraform output -raw ssh_command 2>/dev/null | grep -oP '(?<=-i )\S+' || echo "") + +if [[ -z "$IP" ]]; then + echo "❌ No load generator running. Run: cd terraform && terraform apply" + exit 1 +fi + +echo "📤 Uploading k6 scripts to $IP..." +SSH_OPTS="-o StrictHostKeyChecking=no" +[[ -n "$KEY_NAME" ]] && SSH_OPTS="$SSH_OPTS -i $KEY_NAME" + +scp $SSH_OPTS -r "$SCRIPT_DIR/k6/" "ec2-user@${IP}:/home/ec2-user/k6/" +echo "✅ Scripts uploaded" + +TARGET_VUS="${1:-}" +SCENARIO="${2:-api-queries-alb.js}" + +if [[ -n "$TARGET_VUS" ]]; then + TARGET_URL=$(terraform output -raw run_test 2>/dev/null | grep -oP '(?<=DASHBOARDS_URL=)\S+' || echo "") + echo "" + echo "🚀 Running k6 with $TARGET_VUS VUs ($SCENARIO)..." + echo " Target: $TARGET_URL" + echo "" + ssh $SSH_OPTS "ec2-user@${IP}" \ + "cd /home/ec2-user/k6 && source .env 2>/dev/null; k6 run --env TARGET_VUS=$TARGET_VUS scenarios/$SCENARIO" +fi diff --git a/load-testing/terraform/.gitignore b/load-testing/terraform/.gitignore new file mode 100644 index 00000000..41b04302 --- /dev/null +++ b/load-testing/terraform/.gitignore @@ -0,0 +1,4 @@ +.terraform/ +*.tfstate +*.tfstate.backup +.terraform.lock.hcl diff --git a/load-testing/terraform/main.tf b/load-testing/terraform/main.tf new file mode 100644 index 00000000..e5839143 --- /dev/null +++ b/load-testing/terraform/main.tf @@ -0,0 +1,149 @@ +# Load Generator EC2 — same VPC as EKS, hits ALB end-to-end. +# +# Usage: +# terraform init && terraform apply +# # Then from your laptop: +# ../run-remote.sh 1000 + +terraform { + required_providers { + aws = { source = "hashicorp/aws", version = "~> 5.0" } + } +} + +provider "aws" { + region = var.region +} + +variable "region" { + default = "us-west-2" +} + +variable "vpc_id" { + type = string +} + +variable "subnet_id" { + description = "Public subnet in the same VPC" + type = string +} + +variable "target_url" { + description = "ALB URL for OpenSearch Dashboards" + type = string +} + +variable "opensearch_user" { + default = "admin" +} + +variable "opensearch_password" { + default = "My_password_123!@#" +} + +variable "instance_type" { + default = "m5.xlarge" +} + +# --- IAM role for SSM access (no SSH key needed) --- +resource "aws_iam_role" "load_generator" { + name_prefix = "load-test-" + assume_role_policy = jsonencode({ + Version = "2012-10-17" + Statement = [{ + Action = "sts:AssumeRole" + Effect = "Allow" + Principal = { Service = "ec2.amazonaws.com" } + }] + }) +} + +resource "aws_iam_role_policy_attachment" "ssm" { + role = aws_iam_role.load_generator.name + policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore" +} + +resource "aws_iam_instance_profile" "load_generator" { + name_prefix = "load-test-" + role = aws_iam_role.load_generator.name +} + +# --- Security Group --- +resource "aws_security_group" "load_generator" { + name_prefix = "load-test-" + vpc_id = var.vpc_id + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } + + tags = { Name = "load-test-generator" } +} + +# --- Latest AL2023 AMI --- +data "aws_ami" "al2023" { + most_recent = true + owners = ["amazon"] + filter { + name = "name" + values = ["al2023-ami-*-x86_64"] + } + filter { + name = "state" + values = ["available"] + } +} + +# --- EC2 Instance --- +resource "aws_instance" "load_generator" { + ami = data.aws_ami.al2023.id + instance_type = var.instance_type + subnet_id = var.subnet_id + vpc_security_group_ids = [aws_security_group.load_generator.id] + iam_instance_profile = aws_iam_instance_profile.load_generator.name + associate_public_ip_address = true + + user_data = <<-EOF + #!/bin/bash + set -euo pipefail + + # Install k6 + curl -sL https://github.com/grafana/k6/releases/download/v1.0.0/k6-v1.0.0-linux-amd64.tar.gz | tar xz -C /usr/local/bin --strip-components=1 k6-v1.0.0-linux-amd64/k6 + + # Write env config + mkdir -p /home/ec2-user/k6/scenarios /home/ec2-user/k6/results + cat > /home/ec2-user/k6/.env <<'ENVEOF' + export DASHBOARDS_URL="${var.target_url}" + export OSD_USER="${var.opensearch_user}" + export OSD_PASSWORD='${var.opensearch_password}' + ENVEOF + + chown -R ec2-user:ec2-user /home/ec2-user/k6 + echo "✅ Load generator ready" > /home/ec2-user/k6/STATUS + EOF + + root_block_device { + volume_size = 30 + } + + tags = { + Name = "load-test-generator" + Project = "observability-stack" + ManagedBy = "terraform" + } +} + +output "instance_id" { + value = aws_instance.load_generator.id +} + +output "ssm_command" { + value = "aws ssm start-session --target ${aws_instance.load_generator.id} --region ${var.region}" +} + +output "upload_command" { + value = "aws ssm start-session --target ${aws_instance.load_generator.id} --region ${var.region} --document-name AWS-StartInteractiveCommand --parameters command='cat > /home/ec2-user/k6/scenarios/api-queries-alb.js'" +} diff --git a/load-testing/terraform/terraform.tfvars b/load-testing/terraform/terraform.tfvars new file mode 100644 index 00000000..3df83af7 --- /dev/null +++ b/load-testing/terraform/terraform.tfvars @@ -0,0 +1,4 @@ +vpc_id = "vpc-03aefcf5aa0581d7a" +subnet_id = "subnet-0103d5dff6443d113" +target_url = "https://obs-playground-dev-027423573553.kylhouns.people.aws.dev" +# key_name = "your-key-pair" # Uncomment if you have an EC2 key pair for SSH diff --git a/terraform/aws/.gitignore b/terraform/aws/.gitignore new file mode 100644 index 00000000..ca032f95 --- /dev/null +++ b/terraform/aws/.gitignore @@ -0,0 +1,6 @@ +# Terraform state and providers +.terraform/ +.terraform.lock.hcl +*.tfstate +*.tfstate.backup +terraform.tfvars diff --git a/terraform/aws/README.md b/terraform/aws/README.md new file mode 100644 index 00000000..ae83b28c --- /dev/null +++ b/terraform/aws/README.md @@ -0,0 +1,109 @@ +# Observability Stack — AWS EKS Deployment + +Deploy the full observability stack to EKS in one command. Start with plain HTTP, add TLS/DNS when ready. + +## What You Get + +- EKS cluster with managed node group +- OpenSearch + Dashboards + Data Prepper + OTel Collector + Prometheus +- Internet-facing ALB (HTTP by default, HTTPS when domain is configured) +- Auto-generated OpenSearch credentials + +## Prerequisites + +- [Terraform](https://developer.hashicorp.com/terraform/install) >= 1.5 +- [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) configured with credentials +- ~15 minutes for initial deployment + +## Quick Start + +```bash +cd terraform/aws +terraform init +terraform apply +``` + +That's it. No config file needed. When complete (~15 min): + +```bash +# Configure kubectl +eval $(terraform output -raw kubeconfig_command) + +# Get the ALB URL +kubectl get ingress -n observability-stack + +# Get the password +terraform output -raw opensearch_password +``` + +Open the ALB DNS name in your browser. Login: `admin` / ``. + +## Add TLS + Custom Domain + +When the HTTP smoke test passes, add your domain: + +```bash +cp terraform.tfvars.example terraform.tfvars +``` + +Uncomment and set: +```hcl +domain = "obs.example.com" +route53_zone_id = "Z0123456789ABCDEFGHIJ" +``` + +```bash +terraform apply +``` + +This adds: +- ACM certificate (auto-validated via DNS) +- HTTPS listener with SSL redirect +- Route53 DNS record via external-dns + +## Add WAF Rate Limiting + +```hcl +enable_waf = true +``` + +Adds a WAFv2 WebACL: 2000 requests per 5 minutes per IP, 429 response when exceeded. + +## Send Telemetry + +```bash +kubectl port-forward -n observability-stack svc/obs-stack-opentelemetry-collector 4317:4317 4318:4318 & +export OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4317" +``` + +## Add OpenTelemetry Demo + +To deploy the [OTel Demo](https://opentelemetry.io/docs/demo/) microservices app alongside the stack: + +```bash +cd terraform/aws +helm upgrade obs-stack ../../charts/observability-stack -n observability-stack -f values-eks.yaml \ + --set opentelemetry-demo.enabled=true --no-hooks +``` + +Adds 20+ services generating realistic e-commerce telemetry (~2GB additional memory). All demo telemetry flows through the stack's OTel Collector — no duplicate backends. + +## Destroy + +```bash +terraform destroy +``` + +## All Variables + +| Variable | Default | Description | +|---|---|---| +| `region` | `us-west-2` | AWS region | +| `cluster_name` | `observability-stack` | EKS cluster name | +| `node_instance_type` | `m5.xlarge` | Worker node type (4 vCPU, 16GB) | +| `node_count` | `2` | Number of workers | +| `domain` | `""` (disabled) | Custom domain — enables HTTPS | +| `route53_zone_id` | `""` (disabled) | Route53 zone — required with domain | +| `enable_waf` | `false` | WAF rate limiting | +| `anonymous_auth` | `false` | Public read-only access | +| `enable_examples` | `false` | Example agent services | diff --git a/terraform/aws/addons.tf b/terraform/aws/addons.tf new file mode 100644 index 00000000..ace06ee8 --- /dev/null +++ b/terraform/aws/addons.tf @@ -0,0 +1,67 @@ +# ============================================================================ +# EKS Add-ons — AWS Load Balancer Controller, external-dns (conditional) +# ============================================================================ + +# --- AWS Load Balancer Controller --- + +resource "helm_release" "aws_lb_controller" { + name = "aws-load-balancer-controller" + repository = "https://aws.github.io/eks-charts" + chart = "aws-load-balancer-controller" + namespace = "kube-system" + version = "1.12.0" + + set { + name = "clusterName" + value = module.eks.cluster_name + } + set { + name = "serviceAccount.annotations.eks\\.amazonaws\\.com/role-arn" + value = module.lb_controller_irsa.iam_role_arn + } + set { + name = "vpcId" + value = module.vpc.vpc_id + } + set { + name = "region" + value = var.region + } + + depends_on = [module.eks] +} + +# --- external-dns (only when domain is configured) --- + +resource "helm_release" "external_dns" { + count = local.enable_tls ? 1 : 0 + + name = "external-dns" + repository = "https://kubernetes-sigs.github.io/external-dns" + chart = "external-dns" + namespace = "kube-system" + version = "1.16.1" + + set { + name = "provider.name" + value = "aws" + } + set { + name = "serviceAccount.annotations.eks\\.amazonaws\\.com/role-arn" + value = module.external_dns_irsa.iam_role_arn + } + set { + name = "domainFilters[0]" + value = var.domain + } + set { + name = "policy" + value = "sync" + } + set { + name = "txtOwnerId" + value = var.cluster_name + } + + depends_on = [module.eks] +} diff --git a/terraform/aws/main.tf b/terraform/aws/main.tf new file mode 100644 index 00000000..937d07c3 --- /dev/null +++ b/terraform/aws/main.tf @@ -0,0 +1,189 @@ +# ============================================================================ +# Observability Stack — AWS EKS Deployment +# +# Deploys a complete observability stack to EKS: +# VPC → EKS → Add-ons (LB Controller, external-dns) → Helm chart +# +# Usage: +# cp terraform.tfvars.example terraform.tfvars +# # Edit: domain, route53_zone_id +# terraform init +# terraform apply +# ============================================================================ + +terraform { + required_version = ">= 1.5" + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.0" + } + helm = { + source = "hashicorp/helm" + version = "~> 2.0" + } + kubernetes = { + source = "hashicorp/kubernetes" + version = "~> 2.0" + } + } +} + +provider "aws" { + region = var.region + default_tags { + tags = var.tags + } +} + +data "aws_availability_zones" "available" { + state = "available" +} + +# ============================================================================ +# VPC +# ============================================================================ + +module "vpc" { + source = "terraform-aws-modules/vpc/aws" + version = "~> 5.0" + + name = var.cluster_name + cidr = "10.0.0.0/16" + + # 3 AZs for resilience + azs = slice(data.aws_availability_zones.available.names, 0, 3) + # /19 subnets = 8,190 IPs each — room for pod networking at scale + private_subnets = ["10.0.0.0/19", "10.0.32.0/19", "10.0.64.0/19"] + public_subnets = ["10.0.96.0/19", "10.0.128.0/19", "10.0.160.0/19"] + + enable_nat_gateway = true + single_nat_gateway = true # Cost optimization — one NAT vs one per AZ + enable_dns_hostnames = true + enable_dns_support = true + + # Tags required by AWS Load Balancer Controller for auto-discovery + public_subnet_tags = { + "kubernetes.io/role/elb" = 1 + } + private_subnet_tags = { + "kubernetes.io/role/internal-elb" = 1 + } +} + +# ============================================================================ +# EKS Cluster +# ============================================================================ + +module "eks" { + source = "terraform-aws-modules/eks/aws" + version = "~> 20.0" + + cluster_name = var.cluster_name + cluster_version = var.kubernetes_version + + vpc_id = module.vpc.vpc_id + subnet_ids = module.vpc.private_subnets + + # Public endpoint for kubectl access + cluster_endpoint_public_access = true + + # EKS add-ons + cluster_addons = { + coredns = {} + kube-proxy = {} + vpc-cni = {} + aws-ebs-csi-driver = { service_account_role_arn = module.ebs_csi_irsa.iam_role_arn } + eks-pod-identity-agent = {} + } + + eks_managed_node_groups = { + default = { + instance_types = [var.node_instance_type] + subnet_ids = module.vpc.private_subnets + min_size = var.node_count + max_size = var.node_count + 1 + desired_size = var.node_count + } + } + + # Allow current caller full admin access + enable_cluster_creator_admin_permissions = true +} + +# ============================================================================ +# IRSA — IAM Roles for Service Accounts +# ============================================================================ + +module "ebs_csi_irsa" { + source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks" + version = "~> 5.0" + + role_name = "${var.cluster_name}-ebs-csi" + attach_ebs_csi_policy = true + + oidc_providers = { + main = { + provider_arn = module.eks.oidc_provider_arn + namespace_service_accounts = ["kube-system:ebs-csi-controller-sa"] + } + } +} + +module "lb_controller_irsa" { + source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks" + version = "~> 5.0" + + role_name = "${var.cluster_name}-lb-controller" + attach_load_balancer_controller_policy = true + + oidc_providers = { + main = { + provider_arn = module.eks.oidc_provider_arn + namespace_service_accounts = ["kube-system:aws-load-balancer-controller"] + } + } +} + +module "external_dns_irsa" { + source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks" + version = "~> 5.0" + + role_name = "${var.cluster_name}-external-dns" + attach_external_dns_policy = true + + external_dns_hosted_zone_arns = ["arn:aws:route53:::hostedzone/${var.route53_zone_id}"] + + oidc_providers = { + main = { + provider_arn = module.eks.oidc_provider_arn + namespace_service_accounts = ["kube-system:external-dns"] + } + } +} + +# ============================================================================ +# Kubernetes & Helm providers (configured after EKS is created) +# ============================================================================ + +provider "kubernetes" { + host = module.eks.cluster_endpoint + cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data) + exec { + api_version = "client.authentication.k8s.io/v1beta1" + command = "aws" + args = ["eks", "get-token", "--cluster-name", module.eks.cluster_name, "--region", var.region] + } +} + +provider "helm" { + kubernetes { + host = module.eks.cluster_endpoint + cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data) + exec { + api_version = "client.authentication.k8s.io/v1beta1" + command = "aws" + args = ["eks", "get-token", "--cluster-name", module.eks.cluster_name, "--region", var.region] + } + } +} diff --git a/terraform/aws/observability-stack.tf b/terraform/aws/observability-stack.tf new file mode 100644 index 00000000..cc4e20fc --- /dev/null +++ b/terraform/aws/observability-stack.tf @@ -0,0 +1,169 @@ +# ============================================================================ +# TLS — ACM certificate (only when domain is configured) +# ============================================================================ + +resource "aws_acm_certificate" "dashboards" { + count = local.enable_tls ? 1 : 0 + + domain_name = var.domain + validation_method = "DNS" + + lifecycle { + create_before_destroy = true + } +} + +resource "aws_route53_record" "cert_validation" { + for_each = local.enable_tls ? { + for dvo in aws_acm_certificate.dashboards[0].domain_validation_options : dvo.domain_name => { + name = dvo.resource_record_name + record = dvo.resource_record_value + type = dvo.resource_record_type + } + } : {} + + zone_id = var.route53_zone_id + name = each.value.name + type = each.value.type + records = [each.value.record] + ttl = 60 + + allow_overwrite = true +} + +resource "aws_acm_certificate_validation" "dashboards" { + count = local.enable_tls ? 1 : 0 + + certificate_arn = aws_acm_certificate.dashboards[0].arn + validation_record_fqdns = [for record in aws_route53_record.cert_validation : record.fqdn] +} + +# ============================================================================ +# WAF — Rate limiting (opt-in) +# ============================================================================ + +resource "aws_wafv2_web_acl" "rate_limit" { + count = var.enable_waf ? 1 : 0 + + name = "${var.cluster_name}-rate-limit" + scope = "REGIONAL" + + default_action { + allow {} + } + + rule { + name = "rate-limit" + priority = 1 + + action { + block { + custom_response { + response_code = 429 + custom_response_body_key = "rate-limited" + } + } + } + + statement { + rate_based_statement { + limit = 2000 + aggregate_key_type = "IP" + } + } + + visibility_config { + sampled_requests_enabled = true + cloudwatch_metrics_enabled = true + metric_name = "${var.cluster_name}-rate-limit" + } + } + + custom_response_body { + key = "rate-limited" + content = "{\"error\": \"Rate limit exceeded. Try again in 5 minutes.\"}" + content_type = "APPLICATION_JSON" + } + + visibility_config { + sampled_requests_enabled = true + cloudwatch_metrics_enabled = true + metric_name = "${var.cluster_name}-waf" + } +} + +# ============================================================================ +# Observability Stack — Helm release +# ============================================================================ + +resource "kubernetes_namespace" "observability" { + metadata { + name = "observability-stack" + } + + depends_on = [module.eks] +} + +resource "helm_release" "observability_stack" { + name = "obs-stack" + chart = "${path.module}/../../charts/observability-stack" + namespace = kubernetes_namespace.observability.metadata[0].name + + timeout = 900 + wait = true + wait_for_jobs = true + cleanup_on_fail = true + + values = [file("${path.module}/values-eks.yaml")] + + # --- TLS / Domain (conditional) --- + dynamic "set" { + for_each = local.enable_tls ? [1] : [] + content { + name = "opensearch-dashboards.ingress.hosts[0].host" + value = var.domain + } + } + dynamic "set" { + for_each = local.enable_tls ? [1] : [] + content { + name = "opensearch-dashboards.ingress.annotations.alb\\.ingress\\.kubernetes\\.io/listen-ports" + value = "[{\"HTTPS\":443}]" + } + } + dynamic "set" { + for_each = local.enable_tls ? [1] : [] + content { + name = "opensearch-dashboards.ingress.annotations.alb\\.ingress\\.kubernetes\\.io/certificate-arn" + value = aws_acm_certificate.dashboards[0].arn + } + } + dynamic "set" { + for_each = local.enable_tls ? [1] : [] + content { + name = "opensearch-dashboards.ingress.annotations.alb\\.ingress\\.kubernetes\\.io/ssl-redirect" + value = "443" + type = "string" + } + } + dynamic "set" { + for_each = local.enable_tls ? [1] : [] + content { + name = "opensearch-dashboards.ingress.annotations.external-dns\\.alpha\\.kubernetes\\.io/hostname" + value = var.domain + } + } + + # --- WAF (conditional) --- + dynamic "set" { + for_each = var.enable_waf ? [1] : [] + content { + name = "opensearch-dashboards.ingress.annotations.alb\\.ingress\\.kubernetes\\.io/wafv2-acl-arn" + value = aws_wafv2_web_acl.rate_limit[0].arn + } + } + + depends_on = [ + helm_release.aws_lb_controller, + ] +} diff --git a/terraform/aws/outputs.tf b/terraform/aws/outputs.tf new file mode 100644 index 00000000..b68a71b3 --- /dev/null +++ b/terraform/aws/outputs.tf @@ -0,0 +1,33 @@ +# ============================================================================ +# Outputs +# ============================================================================ + +output "dashboards_url" { + description = "OpenSearch Dashboards URL" + value = local.enable_tls ? "https://${var.domain}" : "http:// — run: kubectl get ingress -n observability-stack" +} + +output "credentials" { + description = "OpenSearch Dashboards login" + value = "Username: admin | Password: My_password_123!@#" +} + +output "kubeconfig_command" { + description = "Command to configure kubectl" + value = "aws eks update-kubeconfig --name ${module.eks.cluster_name} --region ${var.region}" +} + +output "cluster_name" { + description = "EKS cluster name" + value = module.eks.cluster_name +} + +output "otlp_endpoint" { + description = "OTLP endpoint (port-forward required)" + value = "kubectl port-forward -n observability-stack svc/obs-stack-opentelemetry-collector 4317:4317 4318:4318" +} + +output "next_steps" { + description = "To add TLS and custom domain" + value = local.enable_tls ? "✅ TLS enabled at https://${var.domain}" : "Add domain and route53_zone_id to terraform.tfvars, then terraform apply" +} diff --git a/terraform/aws/terraform.tfstate.1774071781.backup b/terraform/aws/terraform.tfstate.1774071781.backup new file mode 100644 index 00000000..230125db --- /dev/null +++ b/terraform/aws/terraform.tfstate.1774071781.backup @@ -0,0 +1,8632 @@ +{ + "version": 4, + "terraform_version": "1.5.7", + "serial": 120, + "lineage": "704c9890-077b-244e-fa87-318acab97ff8", + "outputs": { + "cluster_name": { + "value": "observability-stack", + "type": "string" + }, + "credentials": { + "value": "Username: admin | Password: My_password_123!@#", + "type": "string" + }, + "dashboards_url": { + "value": "https://obs-playground-dev-027423573553.kylhouns.people.aws.dev", + "type": "string" + }, + "kubeconfig_command": { + "value": "aws eks update-kubeconfig --name observability-stack --region us-west-2", + "type": "string" + }, + "next_steps": { + "value": "✅ TLS enabled at https://obs-playground-dev-027423573553.kylhouns.people.aws.dev", + "type": "string" + }, + "otlp_endpoint": { + "value": "kubectl port-forward -n observability-stack svc/obs-stack-opentelemetry-collector 4317:4317 4318:4318", + "type": "string" + } + }, + "resources": [ + { + "mode": "data", + "type": "aws_availability_zones", + "name": "available", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "all_availability_zones": null, + "exclude_names": null, + "exclude_zone_ids": null, + "filter": null, + "group_names": [ + "us-west-2-zg-1" + ], + "id": "us-west-2", + "names": [ + "us-west-2a", + "us-west-2b", + "us-west-2c", + "us-west-2d" + ], + "state": "available", + "timeouts": null, + "zone_ids": [ + "usw2-az2", + "usw2-az1", + "usw2-az3", + "usw2-az4" + ] + }, + "sensitive_attributes": [] + } + ] + }, + { + "mode": "managed", + "type": "aws_acm_certificate", + "name": "dashboards", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "arn": "arn:aws:acm:us-west-2:027423573553:certificate/f792348a-14b1-474b-9e46-98e1a1091485", + "certificate_authority_arn": "", + "certificate_body": null, + "certificate_chain": null, + "domain_name": "obs-playground-dev-027423573553.kylhouns.people.aws.dev", + "domain_validation_options": [ + { + "domain_name": "obs-playground-dev-027423573553.kylhouns.people.aws.dev", + "resource_record_name": "_f30b5b31581053b9f97ac519286c87b2.obs-playground-dev-027423573553.kylhouns.people.aws.dev.", + "resource_record_type": "CNAME", + "resource_record_value": "_4ae4baccc596f519b264e75bb6f73d23.jkddzztszm.acm-validations.aws." + } + ], + "early_renewal_duration": "", + "id": "arn:aws:acm:us-west-2:027423573553:certificate/f792348a-14b1-474b-9e46-98e1a1091485", + "key_algorithm": "RSA_2048", + "not_after": "2026-10-04T23:59:59Z", + "not_before": "2026-03-21T00:00:00Z", + "options": [ + { + "certificate_transparency_logging_preference": "ENABLED" + } + ], + "pending_renewal": false, + "private_key": null, + "renewal_eligibility": "INELIGIBLE", + "renewal_summary": [], + "status": "ISSUED", + "subject_alternative_names": [ + "obs-playground-dev-027423573553.kylhouns.people.aws.dev" + ], + "tags": {}, + "tags_all": { + "ManagedBy": "terraform", + "Project": "observability-stack" + }, + "type": "AMAZON_ISSUED", + "validation_emails": [], + "validation_method": "DNS", + "validation_option": [] + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "create_before_destroy": true + } + ] + }, + { + "mode": "managed", + "type": "aws_acm_certificate_validation", + "name": "dashboards", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "certificate_arn": "arn:aws:acm:us-west-2:027423573553:certificate/f792348a-14b1-474b-9e46-98e1a1091485", + "id": "2026-03-21 05:26:13.57 +0000 UTC", + "timeouts": null, + "validation_record_fqdns": [ + "_f30b5b31581053b9f97ac519286c87b2.obs-playground-dev-027423573553.kylhouns.people.aws.dev" + ] + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjo0NTAwMDAwMDAwMDAwfX0=", + "dependencies": [ + "aws_acm_certificate.dashboards", + "aws_route53_record.cert_validation" + ] + } + ] + }, + { + "mode": "managed", + "type": "aws_route53_record", + "name": "cert_validation", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": "obs-playground-dev-027423573553.kylhouns.people.aws.dev", + "schema_version": 2, + "attributes": { + "alias": [], + "allow_overwrite": true, + "cidr_routing_policy": [], + "failover_routing_policy": [], + "fqdn": "_f30b5b31581053b9f97ac519286c87b2.obs-playground-dev-027423573553.kylhouns.people.aws.dev", + "geolocation_routing_policy": [], + "geoproximity_routing_policy": [], + "health_check_id": "", + "id": "Z07457962NTDHS0A6G9LH__f30b5b31581053b9f97ac519286c87b2.obs-playground-dev-027423573553.kylhouns.people.aws.dev._CNAME", + "latency_routing_policy": [], + "multivalue_answer_routing_policy": false, + "name": "_f30b5b31581053b9f97ac519286c87b2.obs-playground-dev-027423573553.kylhouns.people.aws.dev", + "records": [ + "_4ae4baccc596f519b264e75bb6f73d23.jkddzztszm.acm-validations.aws." + ], + "set_identifier": "", + "timeouts": null, + "ttl": 60, + "type": "CNAME", + "weighted_routing_policy": [], + "zone_id": "Z07457962NTDHS0A6G9LH" + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjoxODAwMDAwMDAwMDAwLCJkZWxldGUiOjE4MDAwMDAwMDAwMDAsInVwZGF0ZSI6MTgwMDAwMDAwMDAwMH0sInNjaGVtYV92ZXJzaW9uIjoiMiJ9", + "dependencies": [ + "aws_acm_certificate.dashboards" + ] + } + ] + }, + { + "mode": "managed", + "type": "aws_wafv2_web_acl", + "name": "rate_limit", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "mode": "managed", + "type": "helm_release", + "name": "aws_lb_controller", + "provider": "provider[\"registry.terraform.io/hashicorp/helm\"]", + "instances": [ + { + "schema_version": 1, + "attributes": { + "atomic": false, + "chart": "aws-load-balancer-controller", + "cleanup_on_fail": false, + "create_namespace": false, + "dependency_update": false, + "description": null, + "devel": null, + "disable_crd_hooks": false, + "disable_openapi_validation": false, + "disable_webhooks": false, + "force_update": false, + "id": "aws-load-balancer-controller", + "keyring": null, + "lint": false, + "manifest": null, + "max_history": 0, + "metadata": [ + { + "app_version": "v2.12.0", + "chart": "aws-load-balancer-controller", + "first_deployed": 1773866318, + "last_deployed": 1773866318, + "name": "aws-load-balancer-controller", + "namespace": "kube-system", + "notes": "AWS Load Balancer controller installed!\n", + "revision": 1, + "values": "{\"clusterName\":\"observability-stack\",\"region\":\"us-west-2\",\"serviceAccount\":{\"annotations\":{\"eks.amazonaws.com/role-arn\":\"arn:aws:iam::027423573553:role/observability-stack-lb-controller\"}},\"vpcId\":\"vpc-03aefcf5aa0581d7a\"}", + "version": "1.12.0" + } + ], + "name": "aws-load-balancer-controller", + "namespace": "kube-system", + "pass_credentials": false, + "postrender": [], + "recreate_pods": false, + "render_subchart_notes": true, + "replace": false, + "repository": "https://aws.github.io/eks-charts", + "repository_ca_file": null, + "repository_cert_file": null, + "repository_key_file": null, + "repository_password": null, + "repository_username": null, + "reset_values": false, + "reuse_values": false, + "set": [ + { + "name": "clusterName", + "type": "", + "value": "observability-stack" + }, + { + "name": "region", + "type": "", + "value": "us-west-2" + }, + { + "name": "serviceAccount.annotations.eks\\.amazonaws\\.com/role-arn", + "type": "", + "value": "arn:aws:iam::027423573553:role/observability-stack-lb-controller" + }, + { + "name": "vpcId", + "type": "", + "value": "vpc-03aefcf5aa0581d7a" + } + ], + "set_list": [], + "set_sensitive": [], + "skip_crds": false, + "status": "deployed", + "timeout": 300, + "upgrade_install": null, + "values": null, + "verify": false, + "version": "1.12.0", + "wait": true, + "wait_for_jobs": false + }, + "sensitive_attributes": [], + "private": "eyJzY2hlbWFfdmVyc2lvbiI6IjEifQ==", + "dependencies": [ + "data.aws_availability_zones.available", + "module.ebs_csi_irsa.aws_iam_role.this", + "module.ebs_csi_irsa.data.aws_caller_identity.current", + "module.ebs_csi_irsa.data.aws_iam_policy_document.this", + "module.ebs_csi_irsa.data.aws_partition.current", + "module.eks.aws_cloudwatch_log_group.this", + "module.eks.aws_ec2_tag.cluster_primary_security_group", + "module.eks.aws_eks_access_entry.this", + "module.eks.aws_eks_access_policy_association.this", + "module.eks.aws_eks_addon.before_compute", + "module.eks.aws_eks_addon.this", + "module.eks.aws_eks_cluster.this", + "module.eks.aws_eks_identity_provider_config.this", + "module.eks.aws_iam_openid_connect_provider.oidc_provider", + "module.eks.aws_iam_policy.cluster_encryption", + "module.eks.aws_iam_policy.cni_ipv6_policy", + "module.eks.aws_iam_policy.custom", + "module.eks.aws_iam_role.eks_auto", + "module.eks.aws_iam_role.this", + "module.eks.aws_iam_role_policy_attachment.additional", + "module.eks.aws_iam_role_policy_attachment.cluster_encryption", + "module.eks.aws_iam_role_policy_attachment.custom", + "module.eks.aws_iam_role_policy_attachment.eks_auto", + "module.eks.aws_iam_role_policy_attachment.eks_auto_additional", + "module.eks.aws_iam_role_policy_attachment.this", + "module.eks.aws_security_group.cluster", + "module.eks.aws_security_group.node", + "module.eks.aws_security_group_rule.cluster", + "module.eks.aws_security_group_rule.node", + "module.eks.data.aws_caller_identity.current", + "module.eks.data.aws_eks_addon_version.this", + "module.eks.data.aws_iam_policy_document.assume_role_policy", + "module.eks.data.aws_iam_policy_document.cni_ipv6_policy", + "module.eks.data.aws_iam_policy_document.custom", + "module.eks.data.aws_iam_policy_document.node_assume_role_policy", + "module.eks.data.aws_iam_session_context.current", + "module.eks.data.aws_partition.current", + "module.eks.data.tls_certificate.this", + "module.eks.module.eks_managed_node_group.aws_autoscaling_schedule.this", + "module.eks.module.eks_managed_node_group.aws_eks_node_group.this", + "module.eks.module.eks_managed_node_group.aws_iam_role.this", + "module.eks.module.eks_managed_node_group.aws_iam_role_policy.this", + "module.eks.module.eks_managed_node_group.aws_iam_role_policy_attachment.additional", + "module.eks.module.eks_managed_node_group.aws_iam_role_policy_attachment.this", + "module.eks.module.eks_managed_node_group.aws_launch_template.this", + "module.eks.module.eks_managed_node_group.aws_placement_group.this", + "module.eks.module.eks_managed_node_group.data.aws_caller_identity.current", + "module.eks.module.eks_managed_node_group.data.aws_ec2_instance_type.this", + "module.eks.module.eks_managed_node_group.data.aws_ec2_instance_type_offerings.this", + "module.eks.module.eks_managed_node_group.data.aws_iam_policy_document.assume_role_policy", + "module.eks.module.eks_managed_node_group.data.aws_iam_policy_document.role", + "module.eks.module.eks_managed_node_group.data.aws_partition.current", + "module.eks.module.eks_managed_node_group.data.aws_ssm_parameter.ami", + "module.eks.module.eks_managed_node_group.data.aws_subnets.placement_group", + "module.eks.module.eks_managed_node_group.module.user_data.data.cloudinit_config.al2023_eks_managed_node_group", + "module.eks.module.eks_managed_node_group.module.user_data.data.cloudinit_config.linux_eks_managed_node_group", + "module.eks.module.eks_managed_node_group.module.user_data.null_resource.validate_cluster_service_cidr", + "module.eks.module.fargate_profile.aws_eks_fargate_profile.this", + "module.eks.module.fargate_profile.aws_iam_role.this", + "module.eks.module.fargate_profile.aws_iam_role_policy.this", + "module.eks.module.fargate_profile.aws_iam_role_policy_attachment.additional", + "module.eks.module.fargate_profile.aws_iam_role_policy_attachment.this", + "module.eks.module.fargate_profile.data.aws_caller_identity.current", + "module.eks.module.fargate_profile.data.aws_iam_policy_document.assume_role_policy", + "module.eks.module.fargate_profile.data.aws_iam_policy_document.role", + "module.eks.module.fargate_profile.data.aws_partition.current", + "module.eks.module.fargate_profile.data.aws_region.current", + "module.eks.module.kms.aws_kms_alias.this", + "module.eks.module.kms.aws_kms_external_key.this", + "module.eks.module.kms.aws_kms_grant.this", + "module.eks.module.kms.aws_kms_key.this", + "module.eks.module.kms.aws_kms_replica_external_key.this", + "module.eks.module.kms.aws_kms_replica_key.this", + "module.eks.module.kms.data.aws_caller_identity.current", + "module.eks.module.kms.data.aws_iam_policy_document.this", + "module.eks.module.kms.data.aws_partition.current", + "module.eks.module.self_managed_node_group.aws_autoscaling_group.this", + "module.eks.module.self_managed_node_group.aws_autoscaling_schedule.this", + "module.eks.module.self_managed_node_group.aws_eks_access_entry.this", + "module.eks.module.self_managed_node_group.aws_iam_instance_profile.this", + "module.eks.module.self_managed_node_group.aws_iam_role.this", + "module.eks.module.self_managed_node_group.aws_iam_role_policy.this", + "module.eks.module.self_managed_node_group.aws_iam_role_policy_attachment.additional", + "module.eks.module.self_managed_node_group.aws_iam_role_policy_attachment.this", + "module.eks.module.self_managed_node_group.aws_launch_template.this", + "module.eks.module.self_managed_node_group.aws_placement_group.this", + "module.eks.module.self_managed_node_group.data.aws_caller_identity.current", + "module.eks.module.self_managed_node_group.data.aws_ec2_instance_type.this", + "module.eks.module.self_managed_node_group.data.aws_ec2_instance_type_offerings.this", + "module.eks.module.self_managed_node_group.data.aws_iam_policy_document.assume_role_policy", + "module.eks.module.self_managed_node_group.data.aws_iam_policy_document.role", + "module.eks.module.self_managed_node_group.data.aws_partition.current", + "module.eks.module.self_managed_node_group.data.aws_ssm_parameter.ami", + "module.eks.module.self_managed_node_group.data.aws_subnets.placement_group", + "module.eks.module.self_managed_node_group.module.user_data.data.cloudinit_config.al2023_eks_managed_node_group", + "module.eks.module.self_managed_node_group.module.user_data.data.cloudinit_config.linux_eks_managed_node_group", + "module.eks.module.self_managed_node_group.module.user_data.null_resource.validate_cluster_service_cidr", + "module.eks.time_sleep.this", + "module.lb_controller_irsa.aws_iam_role.this", + "module.lb_controller_irsa.data.aws_caller_identity.current", + "module.lb_controller_irsa.data.aws_iam_policy_document.this", + "module.lb_controller_irsa.data.aws_partition.current", + "module.vpc.aws_subnet.private", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ] + } + ] + }, + { + "mode": "managed", + "type": "helm_release", + "name": "external_dns", + "provider": "provider[\"registry.terraform.io/hashicorp/helm\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 1, + "attributes": { + "atomic": false, + "chart": "external-dns", + "cleanup_on_fail": false, + "create_namespace": false, + "dependency_update": false, + "description": "Install complete", + "devel": null, + "disable_crd_hooks": false, + "disable_openapi_validation": false, + "disable_webhooks": false, + "force_update": false, + "id": "external-dns", + "keyring": null, + "lint": false, + "manifest": null, + "max_history": 0, + "metadata": [ + { + "app_version": "0.16.1", + "chart": "external-dns", + "first_deployed": 1773895745, + "last_deployed": 1774070874, + "name": "external-dns", + "namespace": "kube-system", + "notes": "***********************************************************************\n* External DNS *\n***********************************************************************\n Chart version: 1.16.1\n App version: 0.16.1\n Image tag: registry.k8s.io/external-dns/external-dns:v0.16.1\n***********************************************************************\n", + "revision": 2, + "values": "{\"domainFilters\":[\"obs-playground-dev-027423573553.kylhouns.people.aws.dev\"],\"policy\":\"sync\",\"provider\":{\"name\":\"aws\"},\"serviceAccount\":{\"annotations\":{\"eks.amazonaws.com/role-arn\":\"arn:aws:iam::027423573553:role/observability-stack-external-dns\"}},\"txtOwnerId\":\"observability-stack\"}", + "version": "1.16.1" + } + ], + "name": "external-dns", + "namespace": "kube-system", + "pass_credentials": false, + "postrender": [], + "recreate_pods": false, + "render_subchart_notes": true, + "replace": false, + "repository": "https://kubernetes-sigs.github.io/external-dns", + "repository_ca_file": null, + "repository_cert_file": null, + "repository_key_file": null, + "repository_password": null, + "repository_username": null, + "reset_values": false, + "reuse_values": false, + "set": [ + { + "name": "domainFilters[0]", + "type": "", + "value": "obs-playground-dev-027423573553.kylhouns.people.aws.dev" + }, + { + "name": "policy", + "type": "", + "value": "sync" + }, + { + "name": "provider.name", + "type": "", + "value": "aws" + }, + { + "name": "serviceAccount.annotations.eks\\.amazonaws\\.com/role-arn", + "type": "", + "value": "arn:aws:iam::027423573553:role/observability-stack-external-dns" + }, + { + "name": "txtOwnerId", + "type": "", + "value": "observability-stack" + } + ], + "set_list": [], + "set_sensitive": [], + "skip_crds": false, + "status": "deployed", + "timeout": 300, + "upgrade_install": null, + "values": null, + "verify": false, + "version": "1.16.1", + "wait": true, + "wait_for_jobs": false + }, + "sensitive_attributes": [], + "private": "eyJzY2hlbWFfdmVyc2lvbiI6IjEifQ==", + "dependencies": [ + "module.ebs_csi_irsa.aws_iam_role.this", + "module.eks.aws_cloudwatch_log_group.this", + "module.eks.aws_ec2_tag.cluster_primary_security_group", + "module.eks.aws_eks_access_entry.this", + "module.eks.aws_eks_access_policy_association.this", + "module.eks.aws_eks_addon.before_compute", + "module.eks.aws_eks_addon.this", + "module.eks.aws_eks_cluster.this", + "module.eks.aws_eks_identity_provider_config.this", + "module.eks.aws_iam_openid_connect_provider.oidc_provider", + "module.eks.aws_iam_policy.cluster_encryption", + "module.eks.aws_iam_policy.cni_ipv6_policy", + "module.eks.aws_iam_policy.custom", + "module.eks.aws_iam_role.eks_auto", + "module.eks.aws_iam_role.this", + "module.eks.aws_iam_role_policy_attachment.additional", + "module.eks.aws_iam_role_policy_attachment.cluster_encryption", + "module.eks.aws_iam_role_policy_attachment.custom", + "module.eks.aws_iam_role_policy_attachment.eks_auto", + "module.eks.aws_iam_role_policy_attachment.eks_auto_additional", + "module.eks.aws_iam_role_policy_attachment.this", + "module.eks.aws_security_group.cluster", + "module.eks.aws_security_group.node", + "module.eks.aws_security_group_rule.cluster", + "module.eks.aws_security_group_rule.node", + "module.eks.data.aws_caller_identity.current", + "module.eks.data.aws_eks_addon_version.this", + "module.eks.data.aws_iam_policy_document.assume_role_policy", + "module.eks.data.aws_iam_policy_document.cni_ipv6_policy", + "module.eks.data.aws_iam_policy_document.custom", + "module.eks.data.aws_iam_policy_document.node_assume_role_policy", + "module.eks.data.aws_iam_session_context.current", + "module.eks.data.aws_partition.current", + "module.eks.data.tls_certificate.this", + "module.eks.module.eks_managed_node_group.aws_autoscaling_schedule.this", + "module.eks.module.eks_managed_node_group.aws_eks_node_group.this", + "module.eks.module.eks_managed_node_group.aws_iam_role.this", + "module.eks.module.eks_managed_node_group.aws_iam_role_policy.this", + "module.eks.module.eks_managed_node_group.aws_iam_role_policy_attachment.additional", + "module.eks.module.eks_managed_node_group.aws_iam_role_policy_attachment.this", + "module.eks.module.eks_managed_node_group.aws_launch_template.this", + "module.eks.module.eks_managed_node_group.aws_placement_group.this", + "module.eks.module.eks_managed_node_group.data.aws_caller_identity.current", + "module.eks.module.eks_managed_node_group.data.aws_ec2_instance_type.this", + "module.eks.module.eks_managed_node_group.data.aws_ec2_instance_type_offerings.this", + "module.eks.module.eks_managed_node_group.data.aws_iam_policy_document.assume_role_policy", + "module.eks.module.eks_managed_node_group.data.aws_iam_policy_document.role", + "module.eks.module.eks_managed_node_group.data.aws_partition.current", + "module.eks.module.eks_managed_node_group.data.aws_ssm_parameter.ami", + "module.eks.module.eks_managed_node_group.data.aws_subnets.placement_group", + "module.eks.module.eks_managed_node_group.module.user_data.data.cloudinit_config.al2023_eks_managed_node_group", + "module.eks.module.eks_managed_node_group.module.user_data.data.cloudinit_config.linux_eks_managed_node_group", + "module.eks.module.eks_managed_node_group.module.user_data.null_resource.validate_cluster_service_cidr", + "module.eks.module.fargate_profile.aws_eks_fargate_profile.this", + "module.eks.module.fargate_profile.aws_iam_role.this", + "module.eks.module.fargate_profile.aws_iam_role_policy.this", + "module.eks.module.fargate_profile.aws_iam_role_policy_attachment.additional", + "module.eks.module.fargate_profile.aws_iam_role_policy_attachment.this", + "module.eks.module.fargate_profile.data.aws_caller_identity.current", + "module.eks.module.fargate_profile.data.aws_iam_policy_document.assume_role_policy", + "module.eks.module.fargate_profile.data.aws_iam_policy_document.role", + "module.eks.module.fargate_profile.data.aws_partition.current", + "module.eks.module.fargate_profile.data.aws_region.current", + "module.eks.module.kms.aws_kms_alias.this", + "module.eks.module.kms.aws_kms_external_key.this", + "module.eks.module.kms.aws_kms_grant.this", + "module.eks.module.kms.aws_kms_key.this", + "module.eks.module.kms.aws_kms_replica_external_key.this", + "module.eks.module.kms.aws_kms_replica_key.this", + "module.eks.module.kms.data.aws_caller_identity.current", + "module.eks.module.kms.data.aws_iam_policy_document.this", + "module.eks.module.kms.data.aws_partition.current", + "module.eks.module.self_managed_node_group.aws_autoscaling_group.this", + "module.eks.module.self_managed_node_group.aws_autoscaling_schedule.this", + "module.eks.module.self_managed_node_group.aws_eks_access_entry.this", + "module.eks.module.self_managed_node_group.aws_iam_instance_profile.this", + "module.eks.module.self_managed_node_group.aws_iam_role.this", + "module.eks.module.self_managed_node_group.aws_iam_role_policy.this", + "module.eks.module.self_managed_node_group.aws_iam_role_policy_attachment.additional", + "module.eks.module.self_managed_node_group.aws_iam_role_policy_attachment.this", + "module.eks.module.self_managed_node_group.aws_launch_template.this", + "module.eks.module.self_managed_node_group.aws_placement_group.this", + "module.eks.module.self_managed_node_group.data.aws_caller_identity.current", + "module.eks.module.self_managed_node_group.data.aws_ec2_instance_type.this", + "module.eks.module.self_managed_node_group.data.aws_ec2_instance_type_offerings.this", + "module.eks.module.self_managed_node_group.data.aws_iam_policy_document.assume_role_policy", + "module.eks.module.self_managed_node_group.data.aws_iam_policy_document.role", + "module.eks.module.self_managed_node_group.data.aws_partition.current", + "module.eks.module.self_managed_node_group.data.aws_ssm_parameter.ami", + "module.eks.module.self_managed_node_group.data.aws_subnets.placement_group", + "module.eks.module.self_managed_node_group.module.user_data.data.cloudinit_config.al2023_eks_managed_node_group", + "module.eks.module.self_managed_node_group.module.user_data.data.cloudinit_config.linux_eks_managed_node_group", + "module.eks.module.self_managed_node_group.module.user_data.null_resource.validate_cluster_service_cidr", + "module.eks.time_sleep.this", + "module.external_dns_irsa.aws_iam_role.this", + "module.vpc.aws_subnet.private", + "module.vpc.aws_vpc.this" + ] + } + ] + }, + { + "mode": "managed", + "type": "helm_release", + "name": "observability_stack", + "provider": "provider[\"registry.terraform.io/hashicorp/helm\"]", + "instances": [ + { + "schema_version": 1, + "attributes": { + "atomic": false, + "chart": "./../../charts/observability-stack", + "cleanup_on_fail": true, + "create_namespace": false, + "dependency_update": false, + "description": null, + "devel": null, + "disable_crd_hooks": false, + "disable_openapi_validation": false, + "disable_webhooks": false, + "force_update": false, + "id": "obs-stack", + "keyring": null, + "lint": false, + "manifest": null, + "max_history": 0, + "metadata": [ + { + "app_version": "3.6.0", + "chart": "observability-stack", + "first_deployed": 1773869439, + "last_deployed": 1774071552, + "name": "obs-stack", + "namespace": "observability-stack", + "notes": "🚀 Observability Stack deployed!\n\nAccess OpenSearch Dashboards:\n\n kubectl port-forward -n observability-stack svc/obs-stack-opensearch-dashboards 5601:5601\n\n Then open: http://localhost:5601\n Username: admin\n Password: My_password_123!@#\n\nSend telemetry:\n\n kubectl port-forward -n observability-stack svc/obs-stack-opentelemetry-collector 4317:4317 4318:4318\n\n OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317\n", + "revision": 59, + "values": "{}", + "version": "0.1.0" + } + ], + "name": "obs-stack", + "namespace": "observability-stack", + "pass_credentials": false, + "postrender": [], + "recreate_pods": false, + "render_subchart_notes": true, + "replace": false, + "repository": null, + "repository_ca_file": null, + "repository_cert_file": null, + "repository_key_file": null, + "repository_password": null, + "repository_username": null, + "reset_values": false, + "reuse_values": false, + "set": [ + { + "name": "opensearch-dashboards.ingress.annotations.alb\\.ingress\\.kubernetes\\.io/certificate-arn", + "type": "", + "value": "arn:aws:acm:us-west-2:027423573553:certificate/f792348a-14b1-474b-9e46-98e1a1091485" + }, + { + "name": "opensearch-dashboards.ingress.annotations.alb\\.ingress\\.kubernetes\\.io/listen-ports", + "type": "", + "value": "[{\"HTTPS\":443}]" + }, + { + "name": "opensearch-dashboards.ingress.annotations.alb\\.ingress\\.kubernetes\\.io/ssl-redirect", + "type": "string", + "value": "443" + }, + { + "name": "opensearch-dashboards.ingress.annotations.external-dns\\.alpha\\.kubernetes\\.io/hostname", + "type": "", + "value": "obs-playground-dev-027423573553.kylhouns.people.aws.dev" + }, + { + "name": "opensearch-dashboards.ingress.hosts[0].host", + "type": "", + "value": "obs-playground-dev-027423573553.kylhouns.people.aws.dev" + } + ], + "set_list": [], + "set_sensitive": [], + "skip_crds": false, + "status": "deployed", + "timeout": 900, + "upgrade_install": null, + "values": [ + "opensearch:\n persistence:\n storageClass: gp2\n\nopensearch-dashboards:\n ingress:\n enabled: true\n ingressClassName: alb\n annotations:\n alb.ingress.kubernetes.io/scheme: internet-facing\n alb.ingress.kubernetes.io/target-type: ip\n alb.ingress.kubernetes.io/listen-ports: '[{\"HTTP\":80}]'\n hosts:\n - paths:\n - path: /\n backend:\n servicePort: 5601\n\ngateway:\n enabled: false\n\nexamples:\n enabled: false\n" + ], + "verify": false, + "version": "0.1.0", + "wait": true, + "wait_for_jobs": true + }, + "sensitive_attributes": [], + "private": "eyJzY2hlbWFfdmVyc2lvbiI6IjEifQ==", + "dependencies": [ + "aws_acm_certificate.dashboards", + "aws_wafv2_web_acl.rate_limit", + "helm_release.aws_lb_controller", + "kubernetes_namespace.observability", + "module.eks.aws_eks_access_entry.this", + "module.eks.aws_eks_access_policy_association.this", + "module.eks.aws_eks_cluster.this", + "module.eks.data.aws_iam_session_context.current", + "module.eks.data.aws_partition.current" + ] + } + ] + }, + { + "mode": "managed", + "type": "kubernetes_namespace", + "name": "observability", + "provider": "provider[\"registry.terraform.io/hashicorp/kubernetes\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "id": "observability-stack", + "metadata": [ + { + "annotations": {}, + "generate_name": "", + "generation": 0, + "labels": {}, + "name": "observability-stack", + "resource_version": "3170", + "uid": "56cc0765-b461-4537-9cfc-921846cfdc24" + } + ], + "timeouts": null, + "wait_for_default_service_account": false + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiZGVsZXRlIjozMDAwMDAwMDAwMDB9fQ==", + "dependencies": [ + "data.aws_availability_zones.available", + "module.ebs_csi_irsa.aws_iam_role.this", + "module.ebs_csi_irsa.data.aws_caller_identity.current", + "module.ebs_csi_irsa.data.aws_iam_policy_document.this", + "module.ebs_csi_irsa.data.aws_partition.current", + "module.eks.aws_cloudwatch_log_group.this", + "module.eks.aws_ec2_tag.cluster_primary_security_group", + "module.eks.aws_eks_access_entry.this", + "module.eks.aws_eks_access_policy_association.this", + "module.eks.aws_eks_addon.before_compute", + "module.eks.aws_eks_addon.this", + "module.eks.aws_eks_cluster.this", + "module.eks.aws_eks_identity_provider_config.this", + "module.eks.aws_iam_openid_connect_provider.oidc_provider", + "module.eks.aws_iam_policy.cluster_encryption", + "module.eks.aws_iam_policy.cni_ipv6_policy", + "module.eks.aws_iam_policy.custom", + "module.eks.aws_iam_role.eks_auto", + "module.eks.aws_iam_role.this", + "module.eks.aws_iam_role_policy_attachment.additional", + "module.eks.aws_iam_role_policy_attachment.cluster_encryption", + "module.eks.aws_iam_role_policy_attachment.custom", + "module.eks.aws_iam_role_policy_attachment.eks_auto", + "module.eks.aws_iam_role_policy_attachment.eks_auto_additional", + "module.eks.aws_iam_role_policy_attachment.this", + "module.eks.aws_security_group.cluster", + "module.eks.aws_security_group.node", + "module.eks.aws_security_group_rule.cluster", + "module.eks.aws_security_group_rule.node", + "module.eks.data.aws_caller_identity.current", + "module.eks.data.aws_eks_addon_version.this", + "module.eks.data.aws_iam_policy_document.assume_role_policy", + "module.eks.data.aws_iam_policy_document.cni_ipv6_policy", + "module.eks.data.aws_iam_policy_document.custom", + "module.eks.data.aws_iam_policy_document.node_assume_role_policy", + "module.eks.data.aws_iam_session_context.current", + "module.eks.data.aws_partition.current", + "module.eks.data.tls_certificate.this", + "module.eks.module.eks_managed_node_group.aws_autoscaling_schedule.this", + "module.eks.module.eks_managed_node_group.aws_eks_node_group.this", + "module.eks.module.eks_managed_node_group.aws_iam_role.this", + "module.eks.module.eks_managed_node_group.aws_iam_role_policy.this", + "module.eks.module.eks_managed_node_group.aws_iam_role_policy_attachment.additional", + "module.eks.module.eks_managed_node_group.aws_iam_role_policy_attachment.this", + "module.eks.module.eks_managed_node_group.aws_launch_template.this", + "module.eks.module.eks_managed_node_group.aws_placement_group.this", + "module.eks.module.eks_managed_node_group.data.aws_caller_identity.current", + "module.eks.module.eks_managed_node_group.data.aws_ec2_instance_type.this", + "module.eks.module.eks_managed_node_group.data.aws_ec2_instance_type_offerings.this", + "module.eks.module.eks_managed_node_group.data.aws_iam_policy_document.assume_role_policy", + "module.eks.module.eks_managed_node_group.data.aws_iam_policy_document.role", + "module.eks.module.eks_managed_node_group.data.aws_partition.current", + "module.eks.module.eks_managed_node_group.data.aws_ssm_parameter.ami", + "module.eks.module.eks_managed_node_group.data.aws_subnets.placement_group", + "module.eks.module.eks_managed_node_group.module.user_data.data.cloudinit_config.al2023_eks_managed_node_group", + "module.eks.module.eks_managed_node_group.module.user_data.data.cloudinit_config.linux_eks_managed_node_group", + "module.eks.module.eks_managed_node_group.module.user_data.null_resource.validate_cluster_service_cidr", + "module.eks.module.fargate_profile.aws_eks_fargate_profile.this", + "module.eks.module.fargate_profile.aws_iam_role.this", + "module.eks.module.fargate_profile.aws_iam_role_policy.this", + "module.eks.module.fargate_profile.aws_iam_role_policy_attachment.additional", + "module.eks.module.fargate_profile.aws_iam_role_policy_attachment.this", + "module.eks.module.fargate_profile.data.aws_caller_identity.current", + "module.eks.module.fargate_profile.data.aws_iam_policy_document.assume_role_policy", + "module.eks.module.fargate_profile.data.aws_iam_policy_document.role", + "module.eks.module.fargate_profile.data.aws_partition.current", + "module.eks.module.fargate_profile.data.aws_region.current", + "module.eks.module.kms.aws_kms_alias.this", + "module.eks.module.kms.aws_kms_external_key.this", + "module.eks.module.kms.aws_kms_grant.this", + "module.eks.module.kms.aws_kms_key.this", + "module.eks.module.kms.aws_kms_replica_external_key.this", + "module.eks.module.kms.aws_kms_replica_key.this", + "module.eks.module.kms.data.aws_caller_identity.current", + "module.eks.module.kms.data.aws_iam_policy_document.this", + "module.eks.module.kms.data.aws_partition.current", + "module.eks.module.self_managed_node_group.aws_autoscaling_group.this", + "module.eks.module.self_managed_node_group.aws_autoscaling_schedule.this", + "module.eks.module.self_managed_node_group.aws_eks_access_entry.this", + "module.eks.module.self_managed_node_group.aws_iam_instance_profile.this", + "module.eks.module.self_managed_node_group.aws_iam_role.this", + "module.eks.module.self_managed_node_group.aws_iam_role_policy.this", + "module.eks.module.self_managed_node_group.aws_iam_role_policy_attachment.additional", + "module.eks.module.self_managed_node_group.aws_iam_role_policy_attachment.this", + "module.eks.module.self_managed_node_group.aws_launch_template.this", + "module.eks.module.self_managed_node_group.aws_placement_group.this", + "module.eks.module.self_managed_node_group.data.aws_caller_identity.current", + "module.eks.module.self_managed_node_group.data.aws_ec2_instance_type.this", + "module.eks.module.self_managed_node_group.data.aws_ec2_instance_type_offerings.this", + "module.eks.module.self_managed_node_group.data.aws_iam_policy_document.assume_role_policy", + "module.eks.module.self_managed_node_group.data.aws_iam_policy_document.role", + "module.eks.module.self_managed_node_group.data.aws_partition.current", + "module.eks.module.self_managed_node_group.data.aws_ssm_parameter.ami", + "module.eks.module.self_managed_node_group.data.aws_subnets.placement_group", + "module.eks.module.self_managed_node_group.module.user_data.data.cloudinit_config.al2023_eks_managed_node_group", + "module.eks.module.self_managed_node_group.module.user_data.data.cloudinit_config.linux_eks_managed_node_group", + "module.eks.module.self_managed_node_group.module.user_data.null_resource.validate_cluster_service_cidr", + "module.eks.time_sleep.this", + "module.vpc.aws_subnet.private", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ] + } + ] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "data", + "type": "aws_caller_identity", + "name": "current", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "account_id": "027423573553", + "arn": "arn:aws:sts::027423573553:assumed-role/Admin/kylhouns-Isengard", + "id": "027423573553", + "user_id": "AROAQMYUSQYYXMMZMGMPD:kylhouns-Isengard" + }, + "sensitive_attributes": [] + } + ] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "amazon_managed_service_prometheus", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "appmesh_controller", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "appmesh_envoy_proxy", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "aws_gateway_controller", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "cert_manager", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "cluster_autoscaler", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "ebs_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "id": "4189668531", + "json": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"ec2:DescribeVolumesModifications\",\n \"ec2:DescribeVolumes\",\n \"ec2:DescribeTags\",\n \"ec2:DescribeSnapshots\",\n \"ec2:DescribeInstances\",\n \"ec2:DescribeAvailabilityZones\"\n ],\n \"Resource\": \"*\"\n },\n {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"ec2:ModifyVolume\",\n \"ec2:CreateSnapshot\"\n ],\n \"Resource\": \"arn:aws:ec2:*:*:volume/*\"\n },\n {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"ec2:DetachVolume\",\n \"ec2:AttachVolume\"\n ],\n \"Resource\": [\n \"arn:aws:ec2:*:*:volume/*\",\n \"arn:aws:ec2:*:*:instance/*\"\n ]\n },\n {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"ec2:EnableFastSnapshotRestores\",\n \"ec2:CreateVolume\"\n ],\n \"Resource\": \"arn:aws:ec2:*:*:snapshot/*\"\n },\n {\n \"Effect\": \"Allow\",\n \"Action\": \"ec2:CreateTags\",\n \"Resource\": [\n \"arn:aws:ec2:*:*:volume/*\",\n \"arn:aws:ec2:*:*:snapshot/*\"\n ],\n \"Condition\": {\n \"StringEquals\": {\n \"ec2:CreateAction\": [\n \"CreateVolume\",\n \"CreateSnapshot\"\n ]\n }\n }\n },\n {\n \"Effect\": \"Allow\",\n \"Action\": \"ec2:DeleteTags\",\n \"Resource\": [\n \"arn:aws:ec2:*:*:volume/*\",\n \"arn:aws:ec2:*:*:snapshot/*\"\n ]\n },\n {\n \"Effect\": \"Allow\",\n \"Action\": \"ec2:CreateVolume\",\n \"Resource\": \"arn:aws:ec2:*:*:volume/*\",\n \"Condition\": {\n \"StringLike\": {\n \"aws:RequestTag/ebs.csi.aws.com/cluster\": \"true\"\n }\n }\n },\n {\n \"Effect\": \"Allow\",\n \"Action\": \"ec2:CreateVolume\",\n \"Resource\": \"arn:aws:ec2:*:*:volume/*\",\n \"Condition\": {\n \"StringLike\": {\n \"aws:RequestTag/CSIVolumeName\": \"*\"\n }\n }\n },\n {\n \"Effect\": \"Allow\",\n \"Action\": \"ec2:DeleteVolume\",\n \"Resource\": \"arn:aws:ec2:*:*:volume/*\",\n \"Condition\": {\n \"StringLike\": {\n \"aws:ResourceTag/ebs.csi.aws.com/cluster\": \"true\"\n }\n }\n },\n {\n \"Effect\": \"Allow\",\n \"Action\": \"ec2:DeleteVolume\",\n \"Resource\": \"arn:aws:ec2:*:*:volume/*\",\n \"Condition\": {\n \"StringLike\": {\n \"aws:ResourceTag/CSIVolumeName\": \"*\"\n }\n }\n },\n {\n \"Effect\": \"Allow\",\n \"Action\": \"ec2:DeleteVolume\",\n \"Resource\": \"arn:aws:ec2:*:*:volume/*\",\n \"Condition\": {\n \"StringLike\": {\n \"ec2:ResourceTag/kubernetes.io/created-for/pvc/name\": \"*\"\n }\n }\n },\n {\n \"Effect\": \"Allow\",\n \"Action\": \"ec2:CreateSnapshot\",\n \"Resource\": \"arn:aws:ec2:*:*:snapshot/*\",\n \"Condition\": {\n \"StringLike\": {\n \"aws:RequestTag/CSIVolumeSnapshotName\": \"*\"\n }\n }\n },\n {\n \"Effect\": \"Allow\",\n \"Action\": \"ec2:CreateSnapshot\",\n \"Resource\": \"arn:aws:ec2:*:*:snapshot/*\",\n \"Condition\": {\n \"StringLike\": {\n \"aws:RequestTag/ebs.csi.aws.com/cluster\": \"true\"\n }\n }\n },\n {\n \"Effect\": \"Allow\",\n \"Action\": \"ec2:DeleteSnapshot\",\n \"Resource\": \"arn:aws:ec2:*:*:snapshot/*\",\n \"Condition\": {\n \"StringLike\": {\n \"aws:ResourceTag/CSIVolumeSnapshotName\": \"*\"\n }\n }\n },\n {\n \"Effect\": \"Allow\",\n \"Action\": \"ec2:DeleteSnapshot\",\n \"Resource\": \"arn:aws:ec2:*:*:snapshot/*\",\n \"Condition\": {\n \"StringLike\": {\n \"aws:ResourceTag/ebs.csi.aws.com/cluster\": \"true\"\n }\n }\n }\n ]\n}", + "minified_json": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":[\"ec2:DescribeVolumesModifications\",\"ec2:DescribeVolumes\",\"ec2:DescribeTags\",\"ec2:DescribeSnapshots\",\"ec2:DescribeInstances\",\"ec2:DescribeAvailabilityZones\"],\"Resource\":\"*\"},{\"Effect\":\"Allow\",\"Action\":[\"ec2:ModifyVolume\",\"ec2:CreateSnapshot\"],\"Resource\":\"arn:aws:ec2:*:*:volume/*\"},{\"Effect\":\"Allow\",\"Action\":[\"ec2:DetachVolume\",\"ec2:AttachVolume\"],\"Resource\":[\"arn:aws:ec2:*:*:volume/*\",\"arn:aws:ec2:*:*:instance/*\"]},{\"Effect\":\"Allow\",\"Action\":[\"ec2:EnableFastSnapshotRestores\",\"ec2:CreateVolume\"],\"Resource\":\"arn:aws:ec2:*:*:snapshot/*\"},{\"Effect\":\"Allow\",\"Action\":\"ec2:CreateTags\",\"Resource\":[\"arn:aws:ec2:*:*:volume/*\",\"arn:aws:ec2:*:*:snapshot/*\"],\"Condition\":{\"StringEquals\":{\"ec2:CreateAction\":[\"CreateVolume\",\"CreateSnapshot\"]}}},{\"Effect\":\"Allow\",\"Action\":\"ec2:DeleteTags\",\"Resource\":[\"arn:aws:ec2:*:*:volume/*\",\"arn:aws:ec2:*:*:snapshot/*\"]},{\"Effect\":\"Allow\",\"Action\":\"ec2:CreateVolume\",\"Resource\":\"arn:aws:ec2:*:*:volume/*\",\"Condition\":{\"StringLike\":{\"aws:RequestTag/ebs.csi.aws.com/cluster\":\"true\"}}},{\"Effect\":\"Allow\",\"Action\":\"ec2:CreateVolume\",\"Resource\":\"arn:aws:ec2:*:*:volume/*\",\"Condition\":{\"StringLike\":{\"aws:RequestTag/CSIVolumeName\":\"*\"}}},{\"Effect\":\"Allow\",\"Action\":\"ec2:DeleteVolume\",\"Resource\":\"arn:aws:ec2:*:*:volume/*\",\"Condition\":{\"StringLike\":{\"aws:ResourceTag/ebs.csi.aws.com/cluster\":\"true\"}}},{\"Effect\":\"Allow\",\"Action\":\"ec2:DeleteVolume\",\"Resource\":\"arn:aws:ec2:*:*:volume/*\",\"Condition\":{\"StringLike\":{\"aws:ResourceTag/CSIVolumeName\":\"*\"}}},{\"Effect\":\"Allow\",\"Action\":\"ec2:DeleteVolume\",\"Resource\":\"arn:aws:ec2:*:*:volume/*\",\"Condition\":{\"StringLike\":{\"ec2:ResourceTag/kubernetes.io/created-for/pvc/name\":\"*\"}}},{\"Effect\":\"Allow\",\"Action\":\"ec2:CreateSnapshot\",\"Resource\":\"arn:aws:ec2:*:*:snapshot/*\",\"Condition\":{\"StringLike\":{\"aws:RequestTag/CSIVolumeSnapshotName\":\"*\"}}},{\"Effect\":\"Allow\",\"Action\":\"ec2:CreateSnapshot\",\"Resource\":\"arn:aws:ec2:*:*:snapshot/*\",\"Condition\":{\"StringLike\":{\"aws:RequestTag/ebs.csi.aws.com/cluster\":\"true\"}}},{\"Effect\":\"Allow\",\"Action\":\"ec2:DeleteSnapshot\",\"Resource\":\"arn:aws:ec2:*:*:snapshot/*\",\"Condition\":{\"StringLike\":{\"aws:ResourceTag/CSIVolumeSnapshotName\":\"*\"}}},{\"Effect\":\"Allow\",\"Action\":\"ec2:DeleteSnapshot\",\"Resource\":\"arn:aws:ec2:*:*:snapshot/*\",\"Condition\":{\"StringLike\":{\"aws:ResourceTag/ebs.csi.aws.com/cluster\":\"true\"}}}]}", + "override_json": null, + "override_policy_documents": null, + "policy_id": null, + "source_json": null, + "source_policy_documents": null, + "statement": [ + { + "actions": [ + "ec2:DescribeAvailabilityZones", + "ec2:DescribeInstances", + "ec2:DescribeSnapshots", + "ec2:DescribeTags", + "ec2:DescribeVolumes", + "ec2:DescribeVolumesModifications" + ], + "condition": [], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "*" + ], + "sid": "" + }, + { + "actions": [ + "ec2:CreateSnapshot", + "ec2:ModifyVolume" + ], + "condition": [], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "arn:aws:ec2:*:*:volume/*" + ], + "sid": "" + }, + { + "actions": [ + "ec2:AttachVolume", + "ec2:DetachVolume" + ], + "condition": [], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "arn:aws:ec2:*:*:instance/*", + "arn:aws:ec2:*:*:volume/*" + ], + "sid": "" + }, + { + "actions": [ + "ec2:CreateVolume", + "ec2:EnableFastSnapshotRestores" + ], + "condition": [], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "arn:aws:ec2:*:*:snapshot/*" + ], + "sid": "" + }, + { + "actions": [ + "ec2:CreateTags" + ], + "condition": [ + { + "test": "StringEquals", + "values": [ + "CreateVolume", + "CreateSnapshot" + ], + "variable": "ec2:CreateAction" + } + ], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "arn:aws:ec2:*:*:snapshot/*", + "arn:aws:ec2:*:*:volume/*" + ], + "sid": "" + }, + { + "actions": [ + "ec2:DeleteTags" + ], + "condition": [], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "arn:aws:ec2:*:*:snapshot/*", + "arn:aws:ec2:*:*:volume/*" + ], + "sid": "" + }, + { + "actions": [ + "ec2:CreateVolume" + ], + "condition": [ + { + "test": "StringLike", + "values": [ + "true" + ], + "variable": "aws:RequestTag/ebs.csi.aws.com/cluster" + } + ], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "arn:aws:ec2:*:*:volume/*" + ], + "sid": "" + }, + { + "actions": [ + "ec2:CreateVolume" + ], + "condition": [ + { + "test": "StringLike", + "values": [ + "*" + ], + "variable": "aws:RequestTag/CSIVolumeName" + } + ], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "arn:aws:ec2:*:*:volume/*" + ], + "sid": "" + }, + { + "actions": [ + "ec2:DeleteVolume" + ], + "condition": [ + { + "test": "StringLike", + "values": [ + "true" + ], + "variable": "aws:ResourceTag/ebs.csi.aws.com/cluster" + } + ], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "arn:aws:ec2:*:*:volume/*" + ], + "sid": "" + }, + { + "actions": [ + "ec2:DeleteVolume" + ], + "condition": [ + { + "test": "StringLike", + "values": [ + "*" + ], + "variable": "aws:ResourceTag/CSIVolumeName" + } + ], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "arn:aws:ec2:*:*:volume/*" + ], + "sid": "" + }, + { + "actions": [ + "ec2:DeleteVolume" + ], + "condition": [ + { + "test": "StringLike", + "values": [ + "*" + ], + "variable": "ec2:ResourceTag/kubernetes.io/created-for/pvc/name" + } + ], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "arn:aws:ec2:*:*:volume/*" + ], + "sid": "" + }, + { + "actions": [ + "ec2:CreateSnapshot" + ], + "condition": [ + { + "test": "StringLike", + "values": [ + "*" + ], + "variable": "aws:RequestTag/CSIVolumeSnapshotName" + } + ], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "arn:aws:ec2:*:*:snapshot/*" + ], + "sid": "" + }, + { + "actions": [ + "ec2:CreateSnapshot" + ], + "condition": [ + { + "test": "StringLike", + "values": [ + "true" + ], + "variable": "aws:RequestTag/ebs.csi.aws.com/cluster" + } + ], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "arn:aws:ec2:*:*:snapshot/*" + ], + "sid": "" + }, + { + "actions": [ + "ec2:DeleteSnapshot" + ], + "condition": [ + { + "test": "StringLike", + "values": [ + "*" + ], + "variable": "aws:ResourceTag/CSIVolumeSnapshotName" + } + ], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "arn:aws:ec2:*:*:snapshot/*" + ], + "sid": "" + }, + { + "actions": [ + "ec2:DeleteSnapshot" + ], + "condition": [ + { + "test": "StringLike", + "values": [ + "true" + ], + "variable": "aws:ResourceTag/ebs.csi.aws.com/cluster" + } + ], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "arn:aws:ec2:*:*:snapshot/*" + ], + "sid": "" + } + ], + "version": "2012-10-17" + }, + "sensitive_attributes": [] + } + ] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "efs_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "external_dns", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "external_secrets", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "fsx_lustre_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "fsx_openzfs_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "karpenter_controller", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "load_balancer_controller", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "load_balancer_controller_targetgroup_only", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "mountpoint_s3_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "node_termination_handler", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "id": "214328930", + "json": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Action\": \"sts:AssumeRoleWithWebIdentity\",\n \"Principal\": {\n \"Federated\": \"arn:aws:iam::027423573553:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D\"\n },\n \"Condition\": {\n \"StringEquals\": {\n \"oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D:aud\": \"sts.amazonaws.com\",\n \"oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D:sub\": \"system:serviceaccount:kube-system:ebs-csi-controller-sa\"\n }\n }\n }\n ]\n}", + "minified_json": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"sts:AssumeRoleWithWebIdentity\",\"Principal\":{\"Federated\":\"arn:aws:iam::027423573553:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D\"},\"Condition\":{\"StringEquals\":{\"oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D:aud\":\"sts.amazonaws.com\",\"oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D:sub\":\"system:serviceaccount:kube-system:ebs-csi-controller-sa\"}}}]}", + "override_json": null, + "override_policy_documents": null, + "policy_id": null, + "source_json": null, + "source_policy_documents": null, + "statement": [ + { + "actions": [ + "sts:AssumeRoleWithWebIdentity" + ], + "condition": [ + { + "test": "StringEquals", + "values": [ + "sts.amazonaws.com" + ], + "variable": "oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D:aud" + }, + { + "test": "StringEquals", + "values": [ + "system:serviceaccount:kube-system:ebs-csi-controller-sa" + ], + "variable": "oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D:sub" + } + ], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [ + { + "identifiers": [ + "arn:aws:iam::027423573553:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D" + ], + "type": "Federated" + } + ], + "resources": [], + "sid": "" + } + ], + "version": "2012-10-17" + }, + "sensitive_attributes": [] + } + ] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "velero", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "vpc_cni", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "data", + "type": "aws_partition", + "name": "current", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "dns_suffix": "amazonaws.com", + "id": "aws", + "partition": "aws", + "reverse_dns_prefix": "com.amazonaws" + }, + "sensitive_attributes": [] + } + ] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "data", + "type": "aws_region", + "name": "current", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "description": "US West (Oregon)", + "endpoint": "ec2.us-west-2.amazonaws.com", + "id": "us-west-2", + "name": "us-west-2" + }, + "sensitive_attributes": [] + } + ] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "amazon_managed_service_prometheus", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "appmesh_controller", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "appmesh_envoy_proxy", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "aws_gateway_controller", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "cert_manager", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "cluster_autoscaler", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "ebs_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "arn": "arn:aws:iam::027423573553:policy/AmazonEKS_EBS_CSI_Policy-20260318201827555200000005", + "attachment_count": 1, + "description": "Provides permissions to manage EBS volumes via the container storage interface driver", + "id": "arn:aws:iam::027423573553:policy/AmazonEKS_EBS_CSI_Policy-20260318201827555200000005", + "name": "AmazonEKS_EBS_CSI_Policy-20260318201827555200000005", + "name_prefix": "AmazonEKS_EBS_CSI_Policy-", + "path": "/", + "policy": "{\"Statement\":[{\"Action\":[\"ec2:DescribeVolumesModifications\",\"ec2:DescribeVolumes\",\"ec2:DescribeTags\",\"ec2:DescribeSnapshots\",\"ec2:DescribeInstances\",\"ec2:DescribeAvailabilityZones\"],\"Effect\":\"Allow\",\"Resource\":\"*\"},{\"Action\":[\"ec2:ModifyVolume\",\"ec2:CreateSnapshot\"],\"Effect\":\"Allow\",\"Resource\":\"arn:aws:ec2:*:*:volume/*\"},{\"Action\":[\"ec2:DetachVolume\",\"ec2:AttachVolume\"],\"Effect\":\"Allow\",\"Resource\":[\"arn:aws:ec2:*:*:volume/*\",\"arn:aws:ec2:*:*:instance/*\"]},{\"Action\":[\"ec2:EnableFastSnapshotRestores\",\"ec2:CreateVolume\"],\"Effect\":\"Allow\",\"Resource\":\"arn:aws:ec2:*:*:snapshot/*\"},{\"Action\":\"ec2:CreateTags\",\"Condition\":{\"StringEquals\":{\"ec2:CreateAction\":[\"CreateVolume\",\"CreateSnapshot\"]}},\"Effect\":\"Allow\",\"Resource\":[\"arn:aws:ec2:*:*:volume/*\",\"arn:aws:ec2:*:*:snapshot/*\"]},{\"Action\":\"ec2:DeleteTags\",\"Effect\":\"Allow\",\"Resource\":[\"arn:aws:ec2:*:*:volume/*\",\"arn:aws:ec2:*:*:snapshot/*\"]},{\"Action\":\"ec2:CreateVolume\",\"Condition\":{\"StringLike\":{\"aws:RequestTag/ebs.csi.aws.com/cluster\":\"true\"}},\"Effect\":\"Allow\",\"Resource\":\"arn:aws:ec2:*:*:volume/*\"},{\"Action\":\"ec2:CreateVolume\",\"Condition\":{\"StringLike\":{\"aws:RequestTag/CSIVolumeName\":\"*\"}},\"Effect\":\"Allow\",\"Resource\":\"arn:aws:ec2:*:*:volume/*\"},{\"Action\":\"ec2:DeleteVolume\",\"Condition\":{\"StringLike\":{\"aws:ResourceTag/ebs.csi.aws.com/cluster\":\"true\"}},\"Effect\":\"Allow\",\"Resource\":\"arn:aws:ec2:*:*:volume/*\"},{\"Action\":\"ec2:DeleteVolume\",\"Condition\":{\"StringLike\":{\"aws:ResourceTag/CSIVolumeName\":\"*\"}},\"Effect\":\"Allow\",\"Resource\":\"arn:aws:ec2:*:*:volume/*\"},{\"Action\":\"ec2:DeleteVolume\",\"Condition\":{\"StringLike\":{\"ec2:ResourceTag/kubernetes.io/created-for/pvc/name\":\"*\"}},\"Effect\":\"Allow\",\"Resource\":\"arn:aws:ec2:*:*:volume/*\"},{\"Action\":\"ec2:CreateSnapshot\",\"Condition\":{\"StringLike\":{\"aws:RequestTag/CSIVolumeSnapshotName\":\"*\"}},\"Effect\":\"Allow\",\"Resource\":\"arn:aws:ec2:*:*:snapshot/*\"},{\"Action\":\"ec2:CreateSnapshot\",\"Condition\":{\"StringLike\":{\"aws:RequestTag/ebs.csi.aws.com/cluster\":\"true\"}},\"Effect\":\"Allow\",\"Resource\":\"arn:aws:ec2:*:*:snapshot/*\"},{\"Action\":\"ec2:DeleteSnapshot\",\"Condition\":{\"StringLike\":{\"aws:ResourceTag/CSIVolumeSnapshotName\":\"*\"}},\"Effect\":\"Allow\",\"Resource\":\"arn:aws:ec2:*:*:snapshot/*\"},{\"Action\":\"ec2:DeleteSnapshot\",\"Condition\":{\"StringLike\":{\"aws:ResourceTag/ebs.csi.aws.com/cluster\":\"true\"}},\"Effect\":\"Allow\",\"Resource\":\"arn:aws:ec2:*:*:snapshot/*\"}],\"Version\":\"2012-10-17\"}", + "policy_id": "ANPAQMYUSQYYQZREZBTEK", + "tags": {}, + "tags_all": { + "ManagedBy": "terraform", + "Project": "observability-stack" + } + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "module.ebs_csi_irsa.data.aws_iam_policy_document.ebs_csi", + "module.ebs_csi_irsa.data.aws_partition.current" + ] + } + ] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "efs_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "external_dns", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "external_secrets", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "fsx_lustre_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "fsx_openzfs_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "karpenter_controller", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "load_balancer_controller", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "load_balancer_controller_targetgroup_only", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "mountpoint_s3_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "node_termination_handler", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "velero", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "vpc_cni", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_role", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "arn": "arn:aws:iam::027423573553:role/observability-stack-ebs-csi", + "assume_role_policy": "{\"Statement\":[{\"Action\":\"sts:AssumeRoleWithWebIdentity\",\"Condition\":{\"StringEquals\":{\"oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D:aud\":\"sts.amazonaws.com\",\"oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D:sub\":\"system:serviceaccount:kube-system:ebs-csi-controller-sa\"}},\"Effect\":\"Allow\",\"Principal\":{\"Federated\":\"arn:aws:iam::027423573553:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D\"}}],\"Version\":\"2012-10-17\"}", + "create_date": "2026-03-18T20:28:14Z", + "description": "", + "force_detach_policies": true, + "id": "observability-stack-ebs-csi", + "inline_policy": [], + "managed_policy_arns": [ + "arn:aws:iam::027423573553:policy/AmazonEKS_EBS_CSI_Policy-20260318201827555200000005" + ], + "max_session_duration": 3600, + "name": "observability-stack-ebs-csi", + "name_prefix": "", + "path": "/", + "permissions_boundary": "", + "tags": {}, + "tags_all": { + "ManagedBy": "terraform", + "Project": "observability-stack" + }, + "unique_id": "AROAQMYUSQYY7QHA4MYZO" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "data.aws_availability_zones.available", + "module.ebs_csi_irsa.data.aws_caller_identity.current", + "module.ebs_csi_irsa.data.aws_iam_policy_document.this", + "module.ebs_csi_irsa.data.aws_partition.current", + "module.eks.aws_cloudwatch_log_group.this", + "module.eks.aws_eks_cluster.this", + "module.eks.aws_iam_openid_connect_provider.oidc_provider", + "module.eks.aws_iam_policy.cni_ipv6_policy", + "module.eks.aws_iam_role.eks_auto", + "module.eks.aws_iam_role.this", + "module.eks.aws_iam_role_policy_attachment.this", + "module.eks.aws_security_group.cluster", + "module.eks.aws_security_group.node", + "module.eks.aws_security_group_rule.cluster", + "module.eks.aws_security_group_rule.node", + "module.eks.data.aws_caller_identity.current", + "module.eks.data.aws_iam_policy_document.assume_role_policy", + "module.eks.data.aws_iam_policy_document.cni_ipv6_policy", + "module.eks.data.aws_iam_policy_document.node_assume_role_policy", + "module.eks.data.aws_iam_session_context.current", + "module.eks.data.aws_partition.current", + "module.eks.data.tls_certificate.this", + "module.eks.module.kms.aws_kms_external_key.this", + "module.eks.module.kms.aws_kms_key.this", + "module.eks.module.kms.aws_kms_replica_external_key.this", + "module.eks.module.kms.aws_kms_replica_key.this", + "module.eks.module.kms.data.aws_caller_identity.current", + "module.eks.module.kms.data.aws_iam_policy_document.this", + "module.eks.module.kms.data.aws_partition.current", + "module.vpc.aws_subnet.private", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ] + } + ] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "amazon_cloudwatch_observability", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "amazon_managed_service_prometheus", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "appmesh_controller", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "appmesh_envoy_proxy", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "aws_gateway_controller", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "cert_manager", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "cluster_autoscaler", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "ebs_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "id": "observability-stack-ebs-csi-20260318202815382700000015", + "policy_arn": "arn:aws:iam::027423573553:policy/AmazonEKS_EBS_CSI_Policy-20260318201827555200000005", + "role": "observability-stack-ebs-csi" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "data.aws_availability_zones.available", + "module.ebs_csi_irsa.aws_iam_policy.ebs_csi", + "module.ebs_csi_irsa.aws_iam_role.this", + "module.ebs_csi_irsa.data.aws_caller_identity.current", + "module.ebs_csi_irsa.data.aws_iam_policy_document.ebs_csi", + "module.ebs_csi_irsa.data.aws_iam_policy_document.this", + "module.ebs_csi_irsa.data.aws_partition.current", + "module.eks.aws_cloudwatch_log_group.this", + "module.eks.aws_eks_cluster.this", + "module.eks.aws_iam_openid_connect_provider.oidc_provider", + "module.eks.aws_iam_policy.cni_ipv6_policy", + "module.eks.aws_iam_role.eks_auto", + "module.eks.aws_iam_role.this", + "module.eks.aws_iam_role_policy_attachment.this", + "module.eks.aws_security_group.cluster", + "module.eks.aws_security_group.node", + "module.eks.aws_security_group_rule.cluster", + "module.eks.aws_security_group_rule.node", + "module.eks.data.aws_caller_identity.current", + "module.eks.data.aws_iam_policy_document.assume_role_policy", + "module.eks.data.aws_iam_policy_document.cni_ipv6_policy", + "module.eks.data.aws_iam_policy_document.node_assume_role_policy", + "module.eks.data.aws_iam_session_context.current", + "module.eks.data.aws_partition.current", + "module.eks.data.tls_certificate.this", + "module.eks.module.kms.aws_kms_external_key.this", + "module.eks.module.kms.aws_kms_key.this", + "module.eks.module.kms.aws_kms_replica_external_key.this", + "module.eks.module.kms.aws_kms_replica_key.this", + "module.eks.module.kms.data.aws_caller_identity.current", + "module.eks.module.kms.data.aws_iam_policy_document.this", + "module.eks.module.kms.data.aws_partition.current", + "module.vpc.aws_subnet.private", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ] + } + ] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "efs_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "external_dns", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "external_secrets", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "fsx_lustre_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "fsx_openzfs_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "karpenter_controller", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "load_balancer_controller", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "load_balancer_controller_targetgroup_only", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "mountpoint_s3_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "node_termination_handler", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "velero", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.ebs_csi_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "vpc_cni", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.eks", + "mode": "data", + "type": "aws_caller_identity", + "name": "current", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "account_id": "027423573553", + "arn": "arn:aws:sts::027423573553:assumed-role/Admin/kylhouns-Isengard", + "id": "027423573553", + "user_id": "AROAQMYUSQYYXMMZMGMPD:kylhouns-Isengard" + }, + "sensitive_attributes": [] + } + ] + }, + { + "module": "module.eks", + "mode": "data", + "type": "aws_eks_addon_version", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": "aws-ebs-csi-driver", + "schema_version": 0, + "attributes": { + "addon_name": "aws-ebs-csi-driver", + "id": "aws-ebs-csi-driver", + "kubernetes_version": "1.32", + "most_recent": false, + "version": "v1.56.0-eksbuild.1" + }, + "sensitive_attributes": [] + }, + { + "index_key": "coredns", + "schema_version": 0, + "attributes": { + "addon_name": "coredns", + "id": "coredns", + "kubernetes_version": "1.32", + "most_recent": false, + "version": "v1.11.4-eksbuild.2" + }, + "sensitive_attributes": [] + }, + { + "index_key": "eks-pod-identity-agent", + "schema_version": 0, + "attributes": { + "addon_name": "eks-pod-identity-agent", + "id": "eks-pod-identity-agent", + "kubernetes_version": "1.32", + "most_recent": false, + "version": "v1.3.10-eksbuild.2" + }, + "sensitive_attributes": [] + }, + { + "index_key": "kube-proxy", + "schema_version": 0, + "attributes": { + "addon_name": "kube-proxy", + "id": "kube-proxy", + "kubernetes_version": "1.32", + "most_recent": false, + "version": "v1.32.6-eksbuild.12" + }, + "sensitive_attributes": [] + }, + { + "index_key": "vpc-cni", + "schema_version": 0, + "attributes": { + "addon_name": "vpc-cni", + "id": "vpc-cni", + "kubernetes_version": "1.32", + "most_recent": false, + "version": "v1.20.4-eksbuild.2" + }, + "sensitive_attributes": [] + } + ] + }, + { + "module": "module.eks", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "assume_role_policy", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "id": "2830595799", + "json": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"EKSClusterAssumeRole\",\n \"Effect\": \"Allow\",\n \"Action\": [\n \"sts:TagSession\",\n \"sts:AssumeRole\"\n ],\n \"Principal\": {\n \"Service\": \"eks.amazonaws.com\"\n }\n }\n ]\n}", + "minified_json": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"EKSClusterAssumeRole\",\"Effect\":\"Allow\",\"Action\":[\"sts:TagSession\",\"sts:AssumeRole\"],\"Principal\":{\"Service\":\"eks.amazonaws.com\"}}]}", + "override_json": null, + "override_policy_documents": null, + "policy_id": null, + "source_json": null, + "source_policy_documents": null, + "statement": [ + { + "actions": [ + "sts:AssumeRole", + "sts:TagSession" + ], + "condition": [], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [ + { + "identifiers": [ + "eks.amazonaws.com" + ], + "type": "Service" + } + ], + "resources": [], + "sid": "EKSClusterAssumeRole" + } + ], + "version": "2012-10-17" + }, + "sensitive_attributes": [] + } + ] + }, + { + "module": "module.eks", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "cni_ipv6_policy", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.eks", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "custom", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "id": "513122117", + "json": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"Compute\",\n \"Effect\": \"Allow\",\n \"Action\": [\n \"ec2:RunInstances\",\n \"ec2:CreateLaunchTemplate\",\n \"ec2:CreateFleet\"\n ],\n \"Resource\": \"*\",\n \"Condition\": {\n \"StringEquals\": {\n \"aws:RequestTag/eks:eks-cluster-name\": \"${aws:PrincipalTag/eks:eks-cluster-name}\"\n },\n \"StringLike\": {\n \"aws:RequestTag/eks:kubernetes-node-class-name\": \"*\",\n \"aws:RequestTag/eks:kubernetes-node-pool-name\": \"*\"\n }\n }\n },\n {\n \"Sid\": \"Storage\",\n \"Effect\": \"Allow\",\n \"Action\": [\n \"ec2:CreateVolume\",\n \"ec2:CreateSnapshot\"\n ],\n \"Resource\": [\n \"arn:aws:ec2:*:*:volume/*\",\n \"arn:aws:ec2:*:*:snapshot/*\"\n ],\n \"Condition\": {\n \"StringEquals\": {\n \"aws:RequestTag/eks:eks-cluster-name\": \"${aws:PrincipalTag/eks:eks-cluster-name}\"\n }\n }\n },\n {\n \"Sid\": \"Networking\",\n \"Effect\": \"Allow\",\n \"Action\": \"ec2:CreateNetworkInterface\",\n \"Resource\": \"*\",\n \"Condition\": {\n \"StringEquals\": {\n \"aws:RequestTag/eks:eks-cluster-name\": \"${aws:PrincipalTag/eks:eks-cluster-name}\",\n \"aws:RequestTag/eks:kubernetes-cni-node-name\": \"*\"\n }\n }\n },\n {\n \"Sid\": \"LoadBalancer\",\n \"Effect\": \"Allow\",\n \"Action\": [\n \"elasticloadbalancing:CreateTargetGroup\",\n \"elasticloadbalancing:CreateRule\",\n \"elasticloadbalancing:CreateLoadBalancer\",\n \"elasticloadbalancing:CreateListener\",\n \"ec2:CreateSecurityGroup\"\n ],\n \"Resource\": \"*\",\n \"Condition\": {\n \"StringEquals\": {\n \"aws:RequestTag/eks:eks-cluster-name\": \"${aws:PrincipalTag/eks:eks-cluster-name}\"\n }\n }\n },\n {\n \"Sid\": \"ShieldProtection\",\n \"Effect\": \"Allow\",\n \"Action\": \"shield:CreateProtection\",\n \"Resource\": \"*\",\n \"Condition\": {\n \"StringEquals\": {\n \"aws:RequestTag/eks:eks-cluster-name\": \"${aws:PrincipalTag/eks:eks-cluster-name}\"\n }\n }\n },\n {\n \"Sid\": \"ShieldTagResource\",\n \"Effect\": \"Allow\",\n \"Action\": \"shield:TagResource\",\n \"Resource\": \"arn:aws:shield::*:protection/*\",\n \"Condition\": {\n \"StringEquals\": {\n \"aws:RequestTag/eks:eks-cluster-name\": \"${aws:PrincipalTag/eks:eks-cluster-name}\"\n }\n }\n }\n ]\n}", + "minified_json": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"Compute\",\"Effect\":\"Allow\",\"Action\":[\"ec2:RunInstances\",\"ec2:CreateLaunchTemplate\",\"ec2:CreateFleet\"],\"Resource\":\"*\",\"Condition\":{\"StringEquals\":{\"aws:RequestTag/eks:eks-cluster-name\":\"${aws:PrincipalTag/eks:eks-cluster-name}\"},\"StringLike\":{\"aws:RequestTag/eks:kubernetes-node-class-name\":\"*\",\"aws:RequestTag/eks:kubernetes-node-pool-name\":\"*\"}}},{\"Sid\":\"Storage\",\"Effect\":\"Allow\",\"Action\":[\"ec2:CreateVolume\",\"ec2:CreateSnapshot\"],\"Resource\":[\"arn:aws:ec2:*:*:volume/*\",\"arn:aws:ec2:*:*:snapshot/*\"],\"Condition\":{\"StringEquals\":{\"aws:RequestTag/eks:eks-cluster-name\":\"${aws:PrincipalTag/eks:eks-cluster-name}\"}}},{\"Sid\":\"Networking\",\"Effect\":\"Allow\",\"Action\":\"ec2:CreateNetworkInterface\",\"Resource\":\"*\",\"Condition\":{\"StringEquals\":{\"aws:RequestTag/eks:eks-cluster-name\":\"${aws:PrincipalTag/eks:eks-cluster-name}\",\"aws:RequestTag/eks:kubernetes-cni-node-name\":\"*\"}}},{\"Sid\":\"LoadBalancer\",\"Effect\":\"Allow\",\"Action\":[\"elasticloadbalancing:CreateTargetGroup\",\"elasticloadbalancing:CreateRule\",\"elasticloadbalancing:CreateLoadBalancer\",\"elasticloadbalancing:CreateListener\",\"ec2:CreateSecurityGroup\"],\"Resource\":\"*\",\"Condition\":{\"StringEquals\":{\"aws:RequestTag/eks:eks-cluster-name\":\"${aws:PrincipalTag/eks:eks-cluster-name}\"}}},{\"Sid\":\"ShieldProtection\",\"Effect\":\"Allow\",\"Action\":\"shield:CreateProtection\",\"Resource\":\"*\",\"Condition\":{\"StringEquals\":{\"aws:RequestTag/eks:eks-cluster-name\":\"${aws:PrincipalTag/eks:eks-cluster-name}\"}}},{\"Sid\":\"ShieldTagResource\",\"Effect\":\"Allow\",\"Action\":\"shield:TagResource\",\"Resource\":\"arn:aws:shield::*:protection/*\",\"Condition\":{\"StringEquals\":{\"aws:RequestTag/eks:eks-cluster-name\":\"${aws:PrincipalTag/eks:eks-cluster-name}\"}}}]}", + "override_json": null, + "override_policy_documents": null, + "policy_id": null, + "source_json": null, + "source_policy_documents": null, + "statement": [ + { + "actions": [ + "ec2:CreateFleet", + "ec2:CreateLaunchTemplate", + "ec2:RunInstances" + ], + "condition": [ + { + "test": "StringEquals", + "values": [ + "${aws:PrincipalTag/eks:eks-cluster-name}" + ], + "variable": "aws:RequestTag/eks:eks-cluster-name" + }, + { + "test": "StringLike", + "values": [ + "*" + ], + "variable": "aws:RequestTag/eks:kubernetes-node-class-name" + }, + { + "test": "StringLike", + "values": [ + "*" + ], + "variable": "aws:RequestTag/eks:kubernetes-node-pool-name" + } + ], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "*" + ], + "sid": "Compute" + }, + { + "actions": [ + "ec2:CreateSnapshot", + "ec2:CreateVolume" + ], + "condition": [ + { + "test": "StringEquals", + "values": [ + "${aws:PrincipalTag/eks:eks-cluster-name}" + ], + "variable": "aws:RequestTag/eks:eks-cluster-name" + } + ], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "arn:aws:ec2:*:*:snapshot/*", + "arn:aws:ec2:*:*:volume/*" + ], + "sid": "Storage" + }, + { + "actions": [ + "ec2:CreateNetworkInterface" + ], + "condition": [ + { + "test": "StringEquals", + "values": [ + "${aws:PrincipalTag/eks:eks-cluster-name}" + ], + "variable": "aws:RequestTag/eks:eks-cluster-name" + }, + { + "test": "StringEquals", + "values": [ + "*" + ], + "variable": "aws:RequestTag/eks:kubernetes-cni-node-name" + } + ], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "*" + ], + "sid": "Networking" + }, + { + "actions": [ + "ec2:CreateSecurityGroup", + "elasticloadbalancing:CreateListener", + "elasticloadbalancing:CreateLoadBalancer", + "elasticloadbalancing:CreateRule", + "elasticloadbalancing:CreateTargetGroup" + ], + "condition": [ + { + "test": "StringEquals", + "values": [ + "${aws:PrincipalTag/eks:eks-cluster-name}" + ], + "variable": "aws:RequestTag/eks:eks-cluster-name" + } + ], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "*" + ], + "sid": "LoadBalancer" + }, + { + "actions": [ + "shield:CreateProtection" + ], + "condition": [ + { + "test": "StringEquals", + "values": [ + "${aws:PrincipalTag/eks:eks-cluster-name}" + ], + "variable": "aws:RequestTag/eks:eks-cluster-name" + } + ], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "*" + ], + "sid": "ShieldProtection" + }, + { + "actions": [ + "shield:TagResource" + ], + "condition": [ + { + "test": "StringEquals", + "values": [ + "${aws:PrincipalTag/eks:eks-cluster-name}" + ], + "variable": "aws:RequestTag/eks:eks-cluster-name" + } + ], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "arn:aws:shield::*:protection/*" + ], + "sid": "ShieldTagResource" + } + ], + "version": "2012-10-17" + }, + "sensitive_attributes": [] + } + ] + }, + { + "module": "module.eks", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "node_assume_role_policy", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.eks", + "mode": "data", + "type": "aws_iam_session_context", + "name": "current", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "arn": "arn:aws:sts::027423573553:assumed-role/Admin/kylhouns-Isengard", + "id": "arn:aws:sts::027423573553:assumed-role/Admin/kylhouns-Isengard", + "issuer_arn": "arn:aws:iam::027423573553:role/Admin", + "issuer_id": "AROAQMYUSQYYXMMZMGMPD", + "issuer_name": "Admin", + "session_name": "kylhouns-Isengard" + }, + "sensitive_attributes": [] + } + ] + }, + { + "module": "module.eks", + "mode": "data", + "type": "aws_partition", + "name": "current", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "dns_suffix": "amazonaws.com", + "id": "aws", + "partition": "aws", + "reverse_dns_prefix": "com.amazonaws" + }, + "sensitive_attributes": [] + } + ] + }, + { + "module": "module.eks", + "mode": "data", + "type": "tls_certificate", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/tls\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "certificates": [ + { + "cert_pem": "-----BEGIN CERTIFICATE-----\nMIIEkjCCA3qgAwIBAgITBn+USionzfP6wq4rAfkI7rnExjANBgkqhkiG9w0BAQsF\nADCBmDELMAkGA1UEBhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNj\nb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4x\nOzA5BgNVBAMTMlN0YXJmaWVsZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1\ndGhvcml0eSAtIEcyMB4XDTE1MDUyNTEyMDAwMFoXDTM3MTIzMTAxMDAwMFowOTEL\nMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv\nb3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj\nca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM\n9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw\nIFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6\nVOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L\n93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm\njgSubJrIqg0CAwEAAaOCATEwggEtMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/\nBAQDAgGGMB0GA1UdDgQWBBSEGMyFNOy8DJSULghZnMeyEE4KCDAfBgNVHSMEGDAW\ngBScXwDfqgHXMCs4iKK4bUqc8hGRgzB4BggrBgEFBQcBAQRsMGowLgYIKwYBBQUH\nMAGGImh0dHA6Ly9vY3NwLnJvb3RnMi5hbWF6b250cnVzdC5jb20wOAYIKwYBBQUH\nMAKGLGh0dHA6Ly9jcnQucm9vdGcyLmFtYXpvbnRydXN0LmNvbS9yb290ZzIuY2Vy\nMD0GA1UdHwQ2MDQwMqAwoC6GLGh0dHA6Ly9jcmwucm9vdGcyLmFtYXpvbnRydXN0\nLmNvbS9yb290ZzIuY3JsMBEGA1UdIAQKMAgwBgYEVR0gADANBgkqhkiG9w0BAQsF\nAAOCAQEAYjdCXLwQtT6LLOkMm2xF4gcAevnFWAu5CIw+7bMlPLVvUOTNNWqnkzSW\nMiGpSESrnO09tKpzbeR/FoCJbM8oAxiDR3mjEH4wW6w7sGDgd9QIpuEdfF7Au/ma\neyKdpwAJfqxGF4PcnCZXmTA5YpaP7dreqsXMGz7KQ2hsVxa81Q4gLv7/wmpdLqBK\nbRRYh5TmOTFffHPLkIhqhBGWJ6bt2YFGpn6jcgAKUj6DiAdjd4lpFw85hdKrCEVN\n0FE6/V1dN2RMfjCyVSRCnTawXZwXgWHxyvkQAiSr6w10kY17RSlQOYiypok1JR4U\nakcjMS9cmvqtmg5iUaQqqcT5NJ0hGA==\n-----END CERTIFICATE-----\n", + "is_ca": true, + "issuer": "CN=Starfield Services Root Certificate Authority - G2,O=Starfield Technologies\\, Inc.,L=Scottsdale,ST=Arizona,C=US", + "max_path_length": -1, + "not_after": "2037-12-31T01:00:00Z", + "not_before": "2015-05-25T12:00:00Z", + "public_key_algorithm": "RSA", + "serial_number": "144918191876577076464031512351042010504348870", + "sha1_fingerprint": "06b25927c42a721631c1efd9431e648fa62e1e39", + "signature_algorithm": "SHA256-RSA", + "subject": "CN=Amazon Root CA 1,O=Amazon,C=US", + "version": 3 + }, + { + "cert_pem": "-----BEGIN CERTIFICATE-----\nMIIEXjCCA0agAwIBAgITB3MSTyqVLj7Rili9uF0bwM5fJzANBgkqhkiG9w0BAQsF\nADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6\nb24gUm9vdCBDQSAxMB4XDTIyMDgyMzIyMjYzNVoXDTMwMDgyMzIyMjYzNVowPDEL\nMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEcMBoGA1UEAxMTQW1hem9uIFJT\nQSAyMDQ4IE0wNDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM3pVR6A\nlQOp4xe776FdePXyejgA38mYx1ou9/jrpV6Sfn+/oqBKgwhY6ePsQHHQayWBJdBn\nv4Wz363qRI4XUh9swBFJ11TnZ3LqOMvHmWq2+loA0QPtOfXdJ2fHBLrBrngtJ/GB\n0p5olAVYrSZgvQGP16Rf8ddtNyxEEhYm3HuhmNi+vSeAq1tLYJPAvRCXonTpWdSD\nxY6hvdmxlqTYi82AtBXSfpGQ58HHM0hw0C6aQakghrwWi5fGslLOqzpimNMIsT7c\nqa0GJx6JfKqJqmQQNplO2h8n9ZsFJgBowof01ppdoLAWg6caMOM0om/VILKaa30F\n9W/r8Qjah7ltGVkCAwEAAaOCAVowggFWMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYD\nVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNV\nHQ4EFgQUH1KSYVaCVH+BZtgdPQqqMlyH3QgwHwYDVR0jBBgwFoAUhBjMhTTsvAyU\nlC4IWZzHshBOCggwewYIKwYBBQUHAQEEbzBtMC8GCCsGAQUFBzABhiNodHRwOi8v\nb2NzcC5yb290Y2ExLmFtYXpvbnRydXN0LmNvbTA6BggrBgEFBQcwAoYuaHR0cDov\nL2NydC5yb290Y2ExLmFtYXpvbnRydXN0LmNvbS9yb290Y2ExLmNlcjA/BgNVHR8E\nODA2MDSgMqAwhi5odHRwOi8vY3JsLnJvb3RjYTEuYW1hem9udHJ1c3QuY29tL3Jv\nb3RjYTEuY3JsMBMGA1UdIAQMMAowCAYGZ4EMAQIBMA0GCSqGSIb3DQEBCwUAA4IB\nAQA+1O5UsAaNuW3lHzJtpNGwBnZd9QEYFtxpiAnIaV4qApnGS9OCw5ZPwie7YSlD\nZF5yyFPsFhUC2Q9uJHY/CRV1b5hIiGH0+6+w5PgKiY1MWuWT8VAaJjFxvuhM7a/e\nfN2TIw1Wd6WCl6YRisunjQOrSP+unqC8A540JNyZ1JOE3jVqat3OZBGgMvihdj2w\nY23EpwesrKiQzkHzmvSH67PVW4ycbPy08HVZnBxZ5NrlGG9bwXR3fNTaz+c+Ej6c\n5AnwI3qkOFgSkg3Y75cdFz6pO/olK+e3AqygAcv0WjzmkDPuBjssuZjCHMC56oH3\nGJkV29Di2j5prHJbwZjG1inU\n-----END CERTIFICATE-----\n", + "is_ca": true, + "issuer": "CN=Amazon Root CA 1,O=Amazon,C=US", + "max_path_length": 0, + "not_after": "2030-08-23T22:26:35Z", + "not_before": "2022-08-23T22:26:35Z", + "public_key_algorithm": "RSA", + "serial_number": "166129359584585245282080020727744908546170663", + "sha1_fingerprint": "e7b8b5a6743ce1b2f17b041de59558a41472d70c", + "signature_algorithm": "SHA256-RSA", + "subject": "CN=Amazon RSA 2048 M04,O=Amazon,C=US", + "version": 3 + }, + { + "cert_pem": "-----BEGIN CERTIFICATE-----\nMIIF3DCCBMSgAwIBAgIQDQV9d1Pckakw9/avbXdLkzANBgkqhkiG9w0BAQsFADA8\nMQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRwwGgYDVQQDExNBbWF6b24g\nUlNBIDIwNDggTTA0MB4XDTI2MDIwMTAwMDAwMFoXDTI3MDMwMjIzNTk1OVowKDEm\nMCQGA1UEAwwdKi5la3MudXMtd2VzdC0yLmFtYXpvbmF3cy5jb20wggEiMA0GCSqG\nSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDUrtybLxNh6kicFXKyZ80JadVMf81AAUe7\n+uNNPUoirB6E/eJOMYFcpOMRegRr1+Bj5GkIllgpQkblG5FML0JpoV0U7KKJ/KLq\nXcaoMso2Z1enLUrXsp09jWaLC0JAvWVfQ1zywX7l7gDv1VYQUjEMnHjtmIRBDOvI\n6yfIeQ/vamYC4wBUTgYuNDt2M1W6dHlWFSckQj1gAoQJeTF7MFvTxNphD/UuJ+/z\ngVCg5EX5zY4J1m0WdYNYHBO1k86FgkBwPpfl3CoTk+dr/HtNtecEoyXVcar3kGdP\n6XaEQjTpSmnLMwiUdXeaO6y/ycjucTlEdCJymTlQi7oCrrFQkb89AgMBAAGjggLs\nMIIC6DAfBgNVHSMEGDAWgBQfUpJhVoJUf4Fm2B09CqoyXIfdCDAdBgNVHQ4EFgQU\nS6cIgvI3+EyOstSdOMBsAFpq+PAwKAYDVR0RBCEwH4IdKi5la3MudXMtd2VzdC0y\nLmFtYXpvbmF3cy5jb20wEwYDVR0gBAwwCjAIBgZngQwBAgEwDgYDVR0PAQH/BAQD\nAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMDsGA1UdHwQ0MDIwMKAuoCyGKmh0dHA6\nLy9jcmwucjJtMDQuYW1hem9udHJ1c3QuY29tL3IybTA0LmNybDB1BggrBgEFBQcB\nAQRpMGcwLQYIKwYBBQUHMAGGIWh0dHA6Ly9vY3NwLnIybTA0LmFtYXpvbnRydXN0\nLmNvbTA2BggrBgEFBQcwAoYqaHR0cDovL2NydC5yMm0wNC5hbWF6b250cnVzdC5j\nb20vcjJtMDQuY2VyMAwGA1UdEwEB/wQCMAAwggF+BgorBgEEAdZ5AgQCBIIBbgSC\nAWoBaAB2AExj3JjlnB2riPYeij3ero+rRKM3e1+blMP7oZz8wb4mAAABnBadJOkA\nAAQDAEcwRQIhAMefEVRWmXr8K/0vkj+gjXXQTbRXw9CQqnmdz1aetKPiAiBzBfYw\nh9vz9Qhgsn1IUqNClM6X0+0X6ewSuA3gbbFVpAB3AByfaCzp+vBFaVD4G5aKh93b\nMhDYTObIsuOCUkrEz1mfAAABnBadJOgAAAQDAEgwRgIhAJuTj3hURPwYbgM5Ws/z\ngyzFrm6zqJhNm/9URF9ChtSeAiEAzMZR7unXCg/JwSBEztJvfTHX6kmG8E8WPpr1\niaOxvHcAdQBgTJqven93XwHUBvySDciZ6wscffjJUhv6+hd3O5eLyQAAAZwWnSXI\nAAAEAwBGMEQCIFP2mgbUhpxZWXI00D4UfkBddoqj4KYmlFKI3yO7OvEeAiA72WEB\n0YRrnqH9RiMQCRPmpx0Jeb9W0meF5XD3XhuqljANBgkqhkiG9w0BAQsFAAOCAQEA\nyU9ItZOuE69q8N2HTgB3Mn6KVOTbFjvHEAXZg9j+wxLBzvpUmQmkvtg/bw5coOYZ\nkLtI4Lwl0qPMgVB5jWjVMq2CR2wpebMUxfTektNV+831n1Nd0v/J0k1Pw9IX7BNz\nstV5kMcw1UmcWZjRK4DFqiv5hHLl/+Pm/Kkszk80ljNihZhlTRUWA0iQPHrkiwMe\nj1NbGk5QWJUCI9X0OfmfvwKILD383irwt+b78J78clcg4GjixGz8MU4v8GzQwc6x\nGMzH9ui7E7TktJ4XwjAS6ST4Qm+zmZdpnYwnTpSmbF2PztIF2G7zW0Bm1RyjXnun\nCEEHt64OMliW3oLkjdFKbg==\n-----END CERTIFICATE-----\n", + "is_ca": false, + "issuer": "CN=Amazon RSA 2048 M04,O=Amazon,C=US", + "max_path_length": -1, + "not_after": "2027-03-02T23:59:59Z", + "not_before": "2026-02-01T00:00:00Z", + "public_key_algorithm": "RSA", + "serial_number": "17308470184802283501806495047878134675", + "sha1_fingerprint": "a84554e91b2f69f6035a36b183074726b12ffa9c", + "signature_algorithm": "SHA256-RSA", + "subject": "CN=*.eks.us-west-2.amazonaws.com", + "version": 3 + } + ], + "content": null, + "id": "f97f646c2cd14cc0db0f757f0fccc96abbbe2af5", + "url": "https://oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D", + "verify_chain": true + }, + "sensitive_attributes": [] + } + ] + }, + { + "module": "module.eks", + "mode": "managed", + "type": "aws_cloudwatch_log_group", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "arn": "arn:aws:logs:us-west-2:027423573553:log-group:/aws/eks/observability-stack/cluster", + "id": "/aws/eks/observability-stack/cluster", + "kms_key_id": "", + "log_group_class": "STANDARD", + "name": "/aws/eks/observability-stack/cluster", + "name_prefix": "", + "retention_in_days": 90, + "skip_destroy": false, + "tags": { + "Name": "/aws/eks/observability-stack/cluster" + }, + "tags_all": { + "ManagedBy": "terraform", + "Name": "/aws/eks/observability-stack/cluster", + "Project": "observability-stack" + } + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "create_before_destroy": true + } + ] + }, + { + "module": "module.eks", + "mode": "managed", + "type": "aws_ec2_tag", + "name": "cluster_primary_security_group", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.eks", + "mode": "managed", + "type": "aws_eks_access_entry", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": "cluster_creator", + "schema_version": 0, + "attributes": { + "access_entry_arn": "arn:aws:eks:us-west-2:027423573553:access-entry/observability-stack/role/027423573553/Admin/9ece8151-38a7-c96c-85de-6283191ef290", + "cluster_name": "observability-stack", + "created_at": "2026-03-18T20:28:13Z", + "id": "observability-stack:arn:aws:iam::027423573553:role/Admin", + "kubernetes_groups": [], + "modified_at": "2026-03-18T20:28:13Z", + "principal_arn": "arn:aws:iam::027423573553:role/Admin", + "tags": {}, + "tags_all": { + "ManagedBy": "terraform", + "Project": "observability-stack" + }, + "timeouts": null, + "type": "STANDARD", + "user_name": "arn:aws:sts::027423573553:assumed-role/Admin/{{SessionName}}" + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjo2MDAwMDAwMDAwMDAsImRlbGV0ZSI6NjAwMDAwMDAwMDAwfX0=", + "dependencies": [ + "data.aws_availability_zones.available", + "module.eks.aws_cloudwatch_log_group.this", + "module.eks.aws_eks_cluster.this", + "module.eks.aws_iam_policy.cni_ipv6_policy", + "module.eks.aws_iam_role.eks_auto", + "module.eks.aws_iam_role.this", + "module.eks.aws_iam_role_policy_attachment.this", + "module.eks.aws_security_group.cluster", + "module.eks.aws_security_group.node", + "module.eks.aws_security_group_rule.cluster", + "module.eks.aws_security_group_rule.node", + "module.eks.data.aws_caller_identity.current", + "module.eks.data.aws_iam_policy_document.assume_role_policy", + "module.eks.data.aws_iam_policy_document.cni_ipv6_policy", + "module.eks.data.aws_iam_policy_document.node_assume_role_policy", + "module.eks.data.aws_iam_session_context.current", + "module.eks.data.aws_partition.current", + "module.eks.module.kms.aws_kms_external_key.this", + "module.eks.module.kms.aws_kms_key.this", + "module.eks.module.kms.aws_kms_replica_external_key.this", + "module.eks.module.kms.aws_kms_replica_key.this", + "module.eks.module.kms.data.aws_caller_identity.current", + "module.eks.module.kms.data.aws_iam_policy_document.this", + "module.eks.module.kms.data.aws_partition.current", + "module.vpc.aws_subnet.private", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ] + } + ] + }, + { + "module": "module.eks", + "mode": "managed", + "type": "aws_eks_access_policy_association", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": "cluster_creator_admin", + "schema_version": 0, + "attributes": { + "access_scope": [ + { + "namespaces": [], + "type": "cluster" + } + ], + "associated_at": "2026-03-18 20:28:14.487 +0000 UTC", + "cluster_name": "observability-stack", + "id": "observability-stack#arn:aws:iam::027423573553:role/Admin#arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy", + "modified_at": "2026-03-18 20:28:14.487 +0000 UTC", + "policy_arn": "arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy", + "principal_arn": "arn:aws:iam::027423573553:role/Admin", + "timeouts": null + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjo2MDAwMDAwMDAwMDAsImRlbGV0ZSI6NjAwMDAwMDAwMDAwfX0=", + "dependencies": [ + "data.aws_availability_zones.available", + "module.eks.aws_cloudwatch_log_group.this", + "module.eks.aws_eks_access_entry.this", + "module.eks.aws_eks_cluster.this", + "module.eks.aws_iam_policy.cni_ipv6_policy", + "module.eks.aws_iam_role.eks_auto", + "module.eks.aws_iam_role.this", + "module.eks.aws_iam_role_policy_attachment.this", + "module.eks.aws_security_group.cluster", + "module.eks.aws_security_group.node", + "module.eks.aws_security_group_rule.cluster", + "module.eks.aws_security_group_rule.node", + "module.eks.data.aws_caller_identity.current", + "module.eks.data.aws_iam_policy_document.assume_role_policy", + "module.eks.data.aws_iam_policy_document.cni_ipv6_policy", + "module.eks.data.aws_iam_policy_document.node_assume_role_policy", + "module.eks.data.aws_iam_session_context.current", + "module.eks.data.aws_partition.current", + "module.eks.module.kms.aws_kms_external_key.this", + "module.eks.module.kms.aws_kms_key.this", + "module.eks.module.kms.aws_kms_replica_external_key.this", + "module.eks.module.kms.aws_kms_replica_key.this", + "module.eks.module.kms.data.aws_caller_identity.current", + "module.eks.module.kms.data.aws_iam_policy_document.this", + "module.eks.module.kms.data.aws_partition.current", + "module.vpc.aws_subnet.private", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ] + } + ] + }, + { + "module": "module.eks", + "mode": "managed", + "type": "aws_eks_addon", + "name": "before_compute", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.eks", + "mode": "managed", + "type": "aws_eks_addon", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": "aws-ebs-csi-driver", + "schema_version": 0, + "attributes": { + "addon_name": "aws-ebs-csi-driver", + "addon_version": "v1.56.0-eksbuild.1", + "arn": "arn:aws:eks:us-west-2:027423573553:addon/observability-stack/aws-ebs-csi-driver/1cce8155-62e0-1e46-d21c-1448c01c8528", + "cluster_name": "observability-stack", + "configuration_values": "", + "created_at": "2026-03-18T20:37:19Z", + "id": "observability-stack:aws-ebs-csi-driver", + "modified_at": "2026-03-18T20:38:26Z", + "pod_identity_association": [], + "preserve": true, + "resolve_conflicts": null, + "resolve_conflicts_on_create": "OVERWRITE", + "resolve_conflicts_on_update": "OVERWRITE", + "service_account_role_arn": "arn:aws:iam::027423573553:role/observability-stack-ebs-csi", + "tags": {}, + "tags_all": { + "ManagedBy": "terraform", + "Project": "observability-stack" + }, + "timeouts": { + "create": null, + "delete": null, + "update": null + } + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjoxMjAwMDAwMDAwMDAwLCJkZWxldGUiOjI0MDAwMDAwMDAwMDAsInVwZGF0ZSI6MTIwMDAwMDAwMDAwMH19", + "dependencies": [ + "data.aws_availability_zones.available", + "module.ebs_csi_irsa.aws_iam_role.this", + "module.ebs_csi_irsa.data.aws_caller_identity.current", + "module.ebs_csi_irsa.data.aws_iam_policy_document.this", + "module.ebs_csi_irsa.data.aws_partition.current", + "module.eks.aws_cloudwatch_log_group.this", + "module.eks.aws_eks_cluster.this", + "module.eks.aws_iam_openid_connect_provider.oidc_provider", + "module.eks.aws_iam_policy.cni_ipv6_policy", + "module.eks.aws_iam_role.eks_auto", + "module.eks.aws_iam_role.this", + "module.eks.aws_iam_role_policy_attachment.this", + "module.eks.aws_security_group.cluster", + "module.eks.aws_security_group.node", + "module.eks.aws_security_group_rule.cluster", + "module.eks.aws_security_group_rule.node", + "module.eks.data.aws_caller_identity.current", + "module.eks.data.aws_eks_addon_version.this", + "module.eks.data.aws_iam_policy_document.assume_role_policy", + "module.eks.data.aws_iam_policy_document.cni_ipv6_policy", + "module.eks.data.aws_iam_policy_document.node_assume_role_policy", + "module.eks.data.aws_iam_session_context.current", + "module.eks.data.aws_partition.current", + "module.eks.data.tls_certificate.this", + "module.eks.module.eks_managed_node_group.aws_autoscaling_schedule.this", + "module.eks.module.eks_managed_node_group.aws_eks_node_group.this", + "module.eks.module.eks_managed_node_group.aws_iam_role.this", + "module.eks.module.eks_managed_node_group.aws_iam_role_policy.this", + "module.eks.module.eks_managed_node_group.aws_iam_role_policy_attachment.additional", + "module.eks.module.eks_managed_node_group.aws_iam_role_policy_attachment.this", + "module.eks.module.eks_managed_node_group.aws_launch_template.this", + "module.eks.module.eks_managed_node_group.aws_placement_group.this", + "module.eks.module.eks_managed_node_group.data.aws_caller_identity.current", + "module.eks.module.eks_managed_node_group.data.aws_ec2_instance_type.this", + "module.eks.module.eks_managed_node_group.data.aws_ec2_instance_type_offerings.this", + "module.eks.module.eks_managed_node_group.data.aws_iam_policy_document.assume_role_policy", + "module.eks.module.eks_managed_node_group.data.aws_iam_policy_document.role", + "module.eks.module.eks_managed_node_group.data.aws_partition.current", + "module.eks.module.eks_managed_node_group.data.aws_ssm_parameter.ami", + "module.eks.module.eks_managed_node_group.data.aws_subnets.placement_group", + "module.eks.module.eks_managed_node_group.module.user_data.data.cloudinit_config.al2023_eks_managed_node_group", + "module.eks.module.eks_managed_node_group.module.user_data.data.cloudinit_config.linux_eks_managed_node_group", + "module.eks.module.eks_managed_node_group.module.user_data.null_resource.validate_cluster_service_cidr", + "module.eks.module.fargate_profile.aws_eks_fargate_profile.this", + "module.eks.module.fargate_profile.aws_iam_role.this", + "module.eks.module.fargate_profile.aws_iam_role_policy.this", + "module.eks.module.fargate_profile.aws_iam_role_policy_attachment.additional", + "module.eks.module.fargate_profile.aws_iam_role_policy_attachment.this", + "module.eks.module.fargate_profile.data.aws_caller_identity.current", + "module.eks.module.fargate_profile.data.aws_iam_policy_document.assume_role_policy", + "module.eks.module.fargate_profile.data.aws_iam_policy_document.role", + "module.eks.module.fargate_profile.data.aws_partition.current", + "module.eks.module.fargate_profile.data.aws_region.current", + "module.eks.module.kms.aws_kms_external_key.this", + "module.eks.module.kms.aws_kms_key.this", + "module.eks.module.kms.aws_kms_replica_external_key.this", + "module.eks.module.kms.aws_kms_replica_key.this", + "module.eks.module.kms.data.aws_caller_identity.current", + "module.eks.module.kms.data.aws_iam_policy_document.this", + "module.eks.module.kms.data.aws_partition.current", + "module.eks.module.self_managed_node_group.aws_autoscaling_group.this", + "module.eks.module.self_managed_node_group.aws_autoscaling_schedule.this", + "module.eks.module.self_managed_node_group.aws_eks_access_entry.this", + "module.eks.module.self_managed_node_group.aws_iam_instance_profile.this", + "module.eks.module.self_managed_node_group.aws_iam_role.this", + "module.eks.module.self_managed_node_group.aws_iam_role_policy.this", + "module.eks.module.self_managed_node_group.aws_iam_role_policy_attachment.additional", + "module.eks.module.self_managed_node_group.aws_iam_role_policy_attachment.this", + "module.eks.module.self_managed_node_group.aws_launch_template.this", + "module.eks.module.self_managed_node_group.aws_placement_group.this", + "module.eks.module.self_managed_node_group.data.aws_caller_identity.current", + "module.eks.module.self_managed_node_group.data.aws_ec2_instance_type.this", + "module.eks.module.self_managed_node_group.data.aws_ec2_instance_type_offerings.this", + "module.eks.module.self_managed_node_group.data.aws_iam_policy_document.assume_role_policy", + "module.eks.module.self_managed_node_group.data.aws_iam_policy_document.role", + "module.eks.module.self_managed_node_group.data.aws_partition.current", + "module.eks.module.self_managed_node_group.data.aws_ssm_parameter.ami", + "module.eks.module.self_managed_node_group.data.aws_subnets.placement_group", + "module.eks.module.self_managed_node_group.module.user_data.data.cloudinit_config.al2023_eks_managed_node_group", + "module.eks.module.self_managed_node_group.module.user_data.data.cloudinit_config.linux_eks_managed_node_group", + "module.eks.module.self_managed_node_group.module.user_data.null_resource.validate_cluster_service_cidr", + "module.eks.time_sleep.this", + "module.vpc.aws_subnet.private", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ] + }, + { + "index_key": "coredns", + "schema_version": 0, + "attributes": { + "addon_name": "coredns", + "addon_version": "v1.11.4-eksbuild.2", + "arn": "arn:aws:eks:us-west-2:027423573553:addon/observability-stack/coredns/d6ce8155-62e5-5137-dfcc-62867816d439", + "cluster_name": "observability-stack", + "configuration_values": "", + "created_at": "2026-03-18T20:37:19Z", + "id": "observability-stack:coredns", + "modified_at": "2026-03-18T20:37:31Z", + "pod_identity_association": [], + "preserve": true, + "resolve_conflicts": null, + "resolve_conflicts_on_create": "OVERWRITE", + "resolve_conflicts_on_update": "OVERWRITE", + "service_account_role_arn": "", + "tags": {}, + "tags_all": { + "ManagedBy": "terraform", + "Project": "observability-stack" + }, + "timeouts": { + "create": null, + "delete": null, + "update": null + } + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjoxMjAwMDAwMDAwMDAwLCJkZWxldGUiOjI0MDAwMDAwMDAwMDAsInVwZGF0ZSI6MTIwMDAwMDAwMDAwMH19", + "dependencies": [ + "data.aws_availability_zones.available", + "module.ebs_csi_irsa.aws_iam_role.this", + "module.ebs_csi_irsa.data.aws_caller_identity.current", + "module.ebs_csi_irsa.data.aws_iam_policy_document.this", + "module.ebs_csi_irsa.data.aws_partition.current", + "module.eks.aws_cloudwatch_log_group.this", + "module.eks.aws_eks_cluster.this", + "module.eks.aws_iam_openid_connect_provider.oidc_provider", + "module.eks.aws_iam_policy.cni_ipv6_policy", + "module.eks.aws_iam_role.eks_auto", + "module.eks.aws_iam_role.this", + "module.eks.aws_iam_role_policy_attachment.this", + "module.eks.aws_security_group.cluster", + "module.eks.aws_security_group.node", + "module.eks.aws_security_group_rule.cluster", + "module.eks.aws_security_group_rule.node", + "module.eks.data.aws_caller_identity.current", + "module.eks.data.aws_eks_addon_version.this", + "module.eks.data.aws_iam_policy_document.assume_role_policy", + "module.eks.data.aws_iam_policy_document.cni_ipv6_policy", + "module.eks.data.aws_iam_policy_document.node_assume_role_policy", + "module.eks.data.aws_iam_session_context.current", + "module.eks.data.aws_partition.current", + "module.eks.data.tls_certificate.this", + "module.eks.module.eks_managed_node_group.aws_autoscaling_schedule.this", + "module.eks.module.eks_managed_node_group.aws_eks_node_group.this", + "module.eks.module.eks_managed_node_group.aws_iam_role.this", + "module.eks.module.eks_managed_node_group.aws_iam_role_policy.this", + "module.eks.module.eks_managed_node_group.aws_iam_role_policy_attachment.additional", + "module.eks.module.eks_managed_node_group.aws_iam_role_policy_attachment.this", + "module.eks.module.eks_managed_node_group.aws_launch_template.this", + "module.eks.module.eks_managed_node_group.aws_placement_group.this", + "module.eks.module.eks_managed_node_group.data.aws_caller_identity.current", + "module.eks.module.eks_managed_node_group.data.aws_ec2_instance_type.this", + "module.eks.module.eks_managed_node_group.data.aws_ec2_instance_type_offerings.this", + "module.eks.module.eks_managed_node_group.data.aws_iam_policy_document.assume_role_policy", + "module.eks.module.eks_managed_node_group.data.aws_iam_policy_document.role", + "module.eks.module.eks_managed_node_group.data.aws_partition.current", + "module.eks.module.eks_managed_node_group.data.aws_ssm_parameter.ami", + "module.eks.module.eks_managed_node_group.data.aws_subnets.placement_group", + "module.eks.module.eks_managed_node_group.module.user_data.data.cloudinit_config.al2023_eks_managed_node_group", + "module.eks.module.eks_managed_node_group.module.user_data.data.cloudinit_config.linux_eks_managed_node_group", + "module.eks.module.eks_managed_node_group.module.user_data.null_resource.validate_cluster_service_cidr", + "module.eks.module.fargate_profile.aws_eks_fargate_profile.this", + "module.eks.module.fargate_profile.aws_iam_role.this", + "module.eks.module.fargate_profile.aws_iam_role_policy.this", + "module.eks.module.fargate_profile.aws_iam_role_policy_attachment.additional", + "module.eks.module.fargate_profile.aws_iam_role_policy_attachment.this", + "module.eks.module.fargate_profile.data.aws_caller_identity.current", + "module.eks.module.fargate_profile.data.aws_iam_policy_document.assume_role_policy", + "module.eks.module.fargate_profile.data.aws_iam_policy_document.role", + "module.eks.module.fargate_profile.data.aws_partition.current", + "module.eks.module.fargate_profile.data.aws_region.current", + "module.eks.module.kms.aws_kms_external_key.this", + "module.eks.module.kms.aws_kms_key.this", + "module.eks.module.kms.aws_kms_replica_external_key.this", + "module.eks.module.kms.aws_kms_replica_key.this", + "module.eks.module.kms.data.aws_caller_identity.current", + "module.eks.module.kms.data.aws_iam_policy_document.this", + "module.eks.module.kms.data.aws_partition.current", + "module.eks.module.self_managed_node_group.aws_autoscaling_group.this", + "module.eks.module.self_managed_node_group.aws_autoscaling_schedule.this", + "module.eks.module.self_managed_node_group.aws_eks_access_entry.this", + "module.eks.module.self_managed_node_group.aws_iam_instance_profile.this", + "module.eks.module.self_managed_node_group.aws_iam_role.this", + "module.eks.module.self_managed_node_group.aws_iam_role_policy.this", + "module.eks.module.self_managed_node_group.aws_iam_role_policy_attachment.additional", + "module.eks.module.self_managed_node_group.aws_iam_role_policy_attachment.this", + "module.eks.module.self_managed_node_group.aws_launch_template.this", + "module.eks.module.self_managed_node_group.aws_placement_group.this", + "module.eks.module.self_managed_node_group.data.aws_caller_identity.current", + "module.eks.module.self_managed_node_group.data.aws_ec2_instance_type.this", + "module.eks.module.self_managed_node_group.data.aws_ec2_instance_type_offerings.this", + "module.eks.module.self_managed_node_group.data.aws_iam_policy_document.assume_role_policy", + "module.eks.module.self_managed_node_group.data.aws_iam_policy_document.role", + "module.eks.module.self_managed_node_group.data.aws_partition.current", + "module.eks.module.self_managed_node_group.data.aws_ssm_parameter.ami", + "module.eks.module.self_managed_node_group.data.aws_subnets.placement_group", + "module.eks.module.self_managed_node_group.module.user_data.data.cloudinit_config.al2023_eks_managed_node_group", + "module.eks.module.self_managed_node_group.module.user_data.data.cloudinit_config.linux_eks_managed_node_group", + "module.eks.module.self_managed_node_group.module.user_data.null_resource.validate_cluster_service_cidr", + "module.eks.time_sleep.this", + "module.vpc.aws_subnet.private", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ] + }, + { + "index_key": "eks-pod-identity-agent", + "schema_version": 0, + "attributes": { + "addon_name": "eks-pod-identity-agent", + "addon_version": "v1.3.10-eksbuild.2", + "arn": "arn:aws:eks:us-west-2:027423573553:addon/observability-stack/eks-pod-identity-agent/96ce8155-62df-5974-2a55-aef2242ebd35", + "cluster_name": "observability-stack", + "configuration_values": "", + "created_at": "2026-03-18T20:37:19Z", + "id": "observability-stack:eks-pod-identity-agent", + "modified_at": "2026-03-18T20:37:55Z", + "pod_identity_association": [], + "preserve": true, + "resolve_conflicts": null, + "resolve_conflicts_on_create": "OVERWRITE", + "resolve_conflicts_on_update": "OVERWRITE", + "service_account_role_arn": "", + "tags": {}, + "tags_all": { + "ManagedBy": "terraform", + "Project": "observability-stack" + }, + "timeouts": { + "create": null, + "delete": null, + "update": null + } + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjoxMjAwMDAwMDAwMDAwLCJkZWxldGUiOjI0MDAwMDAwMDAwMDAsInVwZGF0ZSI6MTIwMDAwMDAwMDAwMH19", + "dependencies": [ + "data.aws_availability_zones.available", + "module.ebs_csi_irsa.aws_iam_role.this", + "module.ebs_csi_irsa.data.aws_caller_identity.current", + "module.ebs_csi_irsa.data.aws_iam_policy_document.this", + "module.ebs_csi_irsa.data.aws_partition.current", + "module.eks.aws_cloudwatch_log_group.this", + "module.eks.aws_eks_cluster.this", + "module.eks.aws_iam_openid_connect_provider.oidc_provider", + "module.eks.aws_iam_policy.cni_ipv6_policy", + "module.eks.aws_iam_role.eks_auto", + "module.eks.aws_iam_role.this", + "module.eks.aws_iam_role_policy_attachment.this", + "module.eks.aws_security_group.cluster", + "module.eks.aws_security_group.node", + "module.eks.aws_security_group_rule.cluster", + "module.eks.aws_security_group_rule.node", + "module.eks.data.aws_caller_identity.current", + "module.eks.data.aws_eks_addon_version.this", + "module.eks.data.aws_iam_policy_document.assume_role_policy", + "module.eks.data.aws_iam_policy_document.cni_ipv6_policy", + "module.eks.data.aws_iam_policy_document.node_assume_role_policy", + "module.eks.data.aws_iam_session_context.current", + "module.eks.data.aws_partition.current", + "module.eks.data.tls_certificate.this", + "module.eks.module.eks_managed_node_group.aws_autoscaling_schedule.this", + "module.eks.module.eks_managed_node_group.aws_eks_node_group.this", + "module.eks.module.eks_managed_node_group.aws_iam_role.this", + "module.eks.module.eks_managed_node_group.aws_iam_role_policy.this", + "module.eks.module.eks_managed_node_group.aws_iam_role_policy_attachment.additional", + "module.eks.module.eks_managed_node_group.aws_iam_role_policy_attachment.this", + "module.eks.module.eks_managed_node_group.aws_launch_template.this", + "module.eks.module.eks_managed_node_group.aws_placement_group.this", + "module.eks.module.eks_managed_node_group.data.aws_caller_identity.current", + "module.eks.module.eks_managed_node_group.data.aws_ec2_instance_type.this", + "module.eks.module.eks_managed_node_group.data.aws_ec2_instance_type_offerings.this", + "module.eks.module.eks_managed_node_group.data.aws_iam_policy_document.assume_role_policy", + "module.eks.module.eks_managed_node_group.data.aws_iam_policy_document.role", + "module.eks.module.eks_managed_node_group.data.aws_partition.current", + "module.eks.module.eks_managed_node_group.data.aws_ssm_parameter.ami", + "module.eks.module.eks_managed_node_group.data.aws_subnets.placement_group", + "module.eks.module.eks_managed_node_group.module.user_data.data.cloudinit_config.al2023_eks_managed_node_group", + "module.eks.module.eks_managed_node_group.module.user_data.data.cloudinit_config.linux_eks_managed_node_group", + "module.eks.module.eks_managed_node_group.module.user_data.null_resource.validate_cluster_service_cidr", + "module.eks.module.fargate_profile.aws_eks_fargate_profile.this", + "module.eks.module.fargate_profile.aws_iam_role.this", + "module.eks.module.fargate_profile.aws_iam_role_policy.this", + "module.eks.module.fargate_profile.aws_iam_role_policy_attachment.additional", + "module.eks.module.fargate_profile.aws_iam_role_policy_attachment.this", + "module.eks.module.fargate_profile.data.aws_caller_identity.current", + "module.eks.module.fargate_profile.data.aws_iam_policy_document.assume_role_policy", + "module.eks.module.fargate_profile.data.aws_iam_policy_document.role", + "module.eks.module.fargate_profile.data.aws_partition.current", + "module.eks.module.fargate_profile.data.aws_region.current", + "module.eks.module.kms.aws_kms_external_key.this", + "module.eks.module.kms.aws_kms_key.this", + "module.eks.module.kms.aws_kms_replica_external_key.this", + "module.eks.module.kms.aws_kms_replica_key.this", + "module.eks.module.kms.data.aws_caller_identity.current", + "module.eks.module.kms.data.aws_iam_policy_document.this", + "module.eks.module.kms.data.aws_partition.current", + "module.eks.module.self_managed_node_group.aws_autoscaling_group.this", + "module.eks.module.self_managed_node_group.aws_autoscaling_schedule.this", + "module.eks.module.self_managed_node_group.aws_eks_access_entry.this", + "module.eks.module.self_managed_node_group.aws_iam_instance_profile.this", + "module.eks.module.self_managed_node_group.aws_iam_role.this", + "module.eks.module.self_managed_node_group.aws_iam_role_policy.this", + "module.eks.module.self_managed_node_group.aws_iam_role_policy_attachment.additional", + "module.eks.module.self_managed_node_group.aws_iam_role_policy_attachment.this", + "module.eks.module.self_managed_node_group.aws_launch_template.this", + "module.eks.module.self_managed_node_group.aws_placement_group.this", + "module.eks.module.self_managed_node_group.data.aws_caller_identity.current", + "module.eks.module.self_managed_node_group.data.aws_ec2_instance_type.this", + "module.eks.module.self_managed_node_group.data.aws_ec2_instance_type_offerings.this", + "module.eks.module.self_managed_node_group.data.aws_iam_policy_document.assume_role_policy", + "module.eks.module.self_managed_node_group.data.aws_iam_policy_document.role", + "module.eks.module.self_managed_node_group.data.aws_partition.current", + "module.eks.module.self_managed_node_group.data.aws_ssm_parameter.ami", + "module.eks.module.self_managed_node_group.data.aws_subnets.placement_group", + "module.eks.module.self_managed_node_group.module.user_data.data.cloudinit_config.al2023_eks_managed_node_group", + "module.eks.module.self_managed_node_group.module.user_data.data.cloudinit_config.linux_eks_managed_node_group", + "module.eks.module.self_managed_node_group.module.user_data.null_resource.validate_cluster_service_cidr", + "module.eks.time_sleep.this", + "module.vpc.aws_subnet.private", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ] + }, + { + "index_key": "kube-proxy", + "schema_version": 0, + "attributes": { + "addon_name": "kube-proxy", + "addon_version": "v1.32.6-eksbuild.12", + "arn": "arn:aws:eks:us-west-2:027423573553:addon/observability-stack/kube-proxy/0cce8155-62dd-23e7-cb36-895daa5ca9b6", + "cluster_name": "observability-stack", + "configuration_values": "", + "created_at": "2026-03-18T20:37:19Z", + "id": "observability-stack:kube-proxy", + "modified_at": "2026-03-18T20:37:55Z", + "pod_identity_association": [], + "preserve": true, + "resolve_conflicts": null, + "resolve_conflicts_on_create": "OVERWRITE", + "resolve_conflicts_on_update": "OVERWRITE", + "service_account_role_arn": "", + "tags": {}, + "tags_all": { + "ManagedBy": "terraform", + "Project": "observability-stack" + }, + "timeouts": { + "create": null, + "delete": null, + "update": null + } + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjoxMjAwMDAwMDAwMDAwLCJkZWxldGUiOjI0MDAwMDAwMDAwMDAsInVwZGF0ZSI6MTIwMDAwMDAwMDAwMH19", + "dependencies": [ + "data.aws_availability_zones.available", + "module.ebs_csi_irsa.aws_iam_role.this", + "module.ebs_csi_irsa.data.aws_caller_identity.current", + "module.ebs_csi_irsa.data.aws_iam_policy_document.this", + "module.ebs_csi_irsa.data.aws_partition.current", + "module.eks.aws_cloudwatch_log_group.this", + "module.eks.aws_eks_cluster.this", + "module.eks.aws_iam_openid_connect_provider.oidc_provider", + "module.eks.aws_iam_policy.cni_ipv6_policy", + "module.eks.aws_iam_role.eks_auto", + "module.eks.aws_iam_role.this", + "module.eks.aws_iam_role_policy_attachment.this", + "module.eks.aws_security_group.cluster", + "module.eks.aws_security_group.node", + "module.eks.aws_security_group_rule.cluster", + "module.eks.aws_security_group_rule.node", + "module.eks.data.aws_caller_identity.current", + "module.eks.data.aws_eks_addon_version.this", + "module.eks.data.aws_iam_policy_document.assume_role_policy", + "module.eks.data.aws_iam_policy_document.cni_ipv6_policy", + "module.eks.data.aws_iam_policy_document.node_assume_role_policy", + "module.eks.data.aws_iam_session_context.current", + "module.eks.data.aws_partition.current", + "module.eks.data.tls_certificate.this", + "module.eks.module.eks_managed_node_group.aws_autoscaling_schedule.this", + "module.eks.module.eks_managed_node_group.aws_eks_node_group.this", + "module.eks.module.eks_managed_node_group.aws_iam_role.this", + "module.eks.module.eks_managed_node_group.aws_iam_role_policy.this", + "module.eks.module.eks_managed_node_group.aws_iam_role_policy_attachment.additional", + "module.eks.module.eks_managed_node_group.aws_iam_role_policy_attachment.this", + "module.eks.module.eks_managed_node_group.aws_launch_template.this", + "module.eks.module.eks_managed_node_group.aws_placement_group.this", + "module.eks.module.eks_managed_node_group.data.aws_caller_identity.current", + "module.eks.module.eks_managed_node_group.data.aws_ec2_instance_type.this", + "module.eks.module.eks_managed_node_group.data.aws_ec2_instance_type_offerings.this", + "module.eks.module.eks_managed_node_group.data.aws_iam_policy_document.assume_role_policy", + "module.eks.module.eks_managed_node_group.data.aws_iam_policy_document.role", + "module.eks.module.eks_managed_node_group.data.aws_partition.current", + "module.eks.module.eks_managed_node_group.data.aws_ssm_parameter.ami", + "module.eks.module.eks_managed_node_group.data.aws_subnets.placement_group", + "module.eks.module.eks_managed_node_group.module.user_data.data.cloudinit_config.al2023_eks_managed_node_group", + "module.eks.module.eks_managed_node_group.module.user_data.data.cloudinit_config.linux_eks_managed_node_group", + "module.eks.module.eks_managed_node_group.module.user_data.null_resource.validate_cluster_service_cidr", + "module.eks.module.fargate_profile.aws_eks_fargate_profile.this", + "module.eks.module.fargate_profile.aws_iam_role.this", + "module.eks.module.fargate_profile.aws_iam_role_policy.this", + "module.eks.module.fargate_profile.aws_iam_role_policy_attachment.additional", + "module.eks.module.fargate_profile.aws_iam_role_policy_attachment.this", + "module.eks.module.fargate_profile.data.aws_caller_identity.current", + "module.eks.module.fargate_profile.data.aws_iam_policy_document.assume_role_policy", + "module.eks.module.fargate_profile.data.aws_iam_policy_document.role", + "module.eks.module.fargate_profile.data.aws_partition.current", + "module.eks.module.fargate_profile.data.aws_region.current", + "module.eks.module.kms.aws_kms_external_key.this", + "module.eks.module.kms.aws_kms_key.this", + "module.eks.module.kms.aws_kms_replica_external_key.this", + "module.eks.module.kms.aws_kms_replica_key.this", + "module.eks.module.kms.data.aws_caller_identity.current", + "module.eks.module.kms.data.aws_iam_policy_document.this", + "module.eks.module.kms.data.aws_partition.current", + "module.eks.module.self_managed_node_group.aws_autoscaling_group.this", + "module.eks.module.self_managed_node_group.aws_autoscaling_schedule.this", + "module.eks.module.self_managed_node_group.aws_eks_access_entry.this", + "module.eks.module.self_managed_node_group.aws_iam_instance_profile.this", + "module.eks.module.self_managed_node_group.aws_iam_role.this", + "module.eks.module.self_managed_node_group.aws_iam_role_policy.this", + "module.eks.module.self_managed_node_group.aws_iam_role_policy_attachment.additional", + "module.eks.module.self_managed_node_group.aws_iam_role_policy_attachment.this", + "module.eks.module.self_managed_node_group.aws_launch_template.this", + "module.eks.module.self_managed_node_group.aws_placement_group.this", + "module.eks.module.self_managed_node_group.data.aws_caller_identity.current", + "module.eks.module.self_managed_node_group.data.aws_ec2_instance_type.this", + "module.eks.module.self_managed_node_group.data.aws_ec2_instance_type_offerings.this", + "module.eks.module.self_managed_node_group.data.aws_iam_policy_document.assume_role_policy", + "module.eks.module.self_managed_node_group.data.aws_iam_policy_document.role", + "module.eks.module.self_managed_node_group.data.aws_partition.current", + "module.eks.module.self_managed_node_group.data.aws_ssm_parameter.ami", + "module.eks.module.self_managed_node_group.data.aws_subnets.placement_group", + "module.eks.module.self_managed_node_group.module.user_data.data.cloudinit_config.al2023_eks_managed_node_group", + "module.eks.module.self_managed_node_group.module.user_data.data.cloudinit_config.linux_eks_managed_node_group", + "module.eks.module.self_managed_node_group.module.user_data.null_resource.validate_cluster_service_cidr", + "module.eks.time_sleep.this", + "module.vpc.aws_subnet.private", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ] + }, + { + "index_key": "vpc-cni", + "schema_version": 0, + "attributes": { + "addon_name": "vpc-cni", + "addon_version": "v1.20.4-eksbuild.2", + "arn": "arn:aws:eks:us-west-2:027423573553:addon/observability-stack/vpc-cni/16ce8155-62df-b015-0f55-9d22607b5bf1", + "cluster_name": "observability-stack", + "configuration_values": "", + "created_at": "2026-03-18T20:37:19Z", + "id": "observability-stack:vpc-cni", + "modified_at": "2026-03-18T20:37:56Z", + "pod_identity_association": [], + "preserve": true, + "resolve_conflicts": null, + "resolve_conflicts_on_create": "OVERWRITE", + "resolve_conflicts_on_update": "OVERWRITE", + "service_account_role_arn": "", + "tags": {}, + "tags_all": { + "ManagedBy": "terraform", + "Project": "observability-stack" + }, + "timeouts": { + "create": null, + "delete": null, + "update": null + } + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjoxMjAwMDAwMDAwMDAwLCJkZWxldGUiOjI0MDAwMDAwMDAwMDAsInVwZGF0ZSI6MTIwMDAwMDAwMDAwMH19", + "dependencies": [ + "data.aws_availability_zones.available", + "module.ebs_csi_irsa.aws_iam_role.this", + "module.ebs_csi_irsa.data.aws_caller_identity.current", + "module.ebs_csi_irsa.data.aws_iam_policy_document.this", + "module.ebs_csi_irsa.data.aws_partition.current", + "module.eks.aws_cloudwatch_log_group.this", + "module.eks.aws_eks_cluster.this", + "module.eks.aws_iam_openid_connect_provider.oidc_provider", + "module.eks.aws_iam_policy.cni_ipv6_policy", + "module.eks.aws_iam_role.eks_auto", + "module.eks.aws_iam_role.this", + "module.eks.aws_iam_role_policy_attachment.this", + "module.eks.aws_security_group.cluster", + "module.eks.aws_security_group.node", + "module.eks.aws_security_group_rule.cluster", + "module.eks.aws_security_group_rule.node", + "module.eks.data.aws_caller_identity.current", + "module.eks.data.aws_eks_addon_version.this", + "module.eks.data.aws_iam_policy_document.assume_role_policy", + "module.eks.data.aws_iam_policy_document.cni_ipv6_policy", + "module.eks.data.aws_iam_policy_document.node_assume_role_policy", + "module.eks.data.aws_iam_session_context.current", + "module.eks.data.aws_partition.current", + "module.eks.data.tls_certificate.this", + "module.eks.module.eks_managed_node_group.aws_autoscaling_schedule.this", + "module.eks.module.eks_managed_node_group.aws_eks_node_group.this", + "module.eks.module.eks_managed_node_group.aws_iam_role.this", + "module.eks.module.eks_managed_node_group.aws_iam_role_policy.this", + "module.eks.module.eks_managed_node_group.aws_iam_role_policy_attachment.additional", + "module.eks.module.eks_managed_node_group.aws_iam_role_policy_attachment.this", + "module.eks.module.eks_managed_node_group.aws_launch_template.this", + "module.eks.module.eks_managed_node_group.aws_placement_group.this", + "module.eks.module.eks_managed_node_group.data.aws_caller_identity.current", + "module.eks.module.eks_managed_node_group.data.aws_ec2_instance_type.this", + "module.eks.module.eks_managed_node_group.data.aws_ec2_instance_type_offerings.this", + "module.eks.module.eks_managed_node_group.data.aws_iam_policy_document.assume_role_policy", + "module.eks.module.eks_managed_node_group.data.aws_iam_policy_document.role", + "module.eks.module.eks_managed_node_group.data.aws_partition.current", + "module.eks.module.eks_managed_node_group.data.aws_ssm_parameter.ami", + "module.eks.module.eks_managed_node_group.data.aws_subnets.placement_group", + "module.eks.module.eks_managed_node_group.module.user_data.data.cloudinit_config.al2023_eks_managed_node_group", + "module.eks.module.eks_managed_node_group.module.user_data.data.cloudinit_config.linux_eks_managed_node_group", + "module.eks.module.eks_managed_node_group.module.user_data.null_resource.validate_cluster_service_cidr", + "module.eks.module.fargate_profile.aws_eks_fargate_profile.this", + "module.eks.module.fargate_profile.aws_iam_role.this", + "module.eks.module.fargate_profile.aws_iam_role_policy.this", + "module.eks.module.fargate_profile.aws_iam_role_policy_attachment.additional", + "module.eks.module.fargate_profile.aws_iam_role_policy_attachment.this", + "module.eks.module.fargate_profile.data.aws_caller_identity.current", + "module.eks.module.fargate_profile.data.aws_iam_policy_document.assume_role_policy", + "module.eks.module.fargate_profile.data.aws_iam_policy_document.role", + "module.eks.module.fargate_profile.data.aws_partition.current", + "module.eks.module.fargate_profile.data.aws_region.current", + "module.eks.module.kms.aws_kms_external_key.this", + "module.eks.module.kms.aws_kms_key.this", + "module.eks.module.kms.aws_kms_replica_external_key.this", + "module.eks.module.kms.aws_kms_replica_key.this", + "module.eks.module.kms.data.aws_caller_identity.current", + "module.eks.module.kms.data.aws_iam_policy_document.this", + "module.eks.module.kms.data.aws_partition.current", + "module.eks.module.self_managed_node_group.aws_autoscaling_group.this", + "module.eks.module.self_managed_node_group.aws_autoscaling_schedule.this", + "module.eks.module.self_managed_node_group.aws_eks_access_entry.this", + "module.eks.module.self_managed_node_group.aws_iam_instance_profile.this", + "module.eks.module.self_managed_node_group.aws_iam_role.this", + "module.eks.module.self_managed_node_group.aws_iam_role_policy.this", + "module.eks.module.self_managed_node_group.aws_iam_role_policy_attachment.additional", + "module.eks.module.self_managed_node_group.aws_iam_role_policy_attachment.this", + "module.eks.module.self_managed_node_group.aws_launch_template.this", + "module.eks.module.self_managed_node_group.aws_placement_group.this", + "module.eks.module.self_managed_node_group.data.aws_caller_identity.current", + "module.eks.module.self_managed_node_group.data.aws_ec2_instance_type.this", + "module.eks.module.self_managed_node_group.data.aws_ec2_instance_type_offerings.this", + "module.eks.module.self_managed_node_group.data.aws_iam_policy_document.assume_role_policy", + "module.eks.module.self_managed_node_group.data.aws_iam_policy_document.role", + "module.eks.module.self_managed_node_group.data.aws_partition.current", + "module.eks.module.self_managed_node_group.data.aws_ssm_parameter.ami", + "module.eks.module.self_managed_node_group.data.aws_subnets.placement_group", + "module.eks.module.self_managed_node_group.module.user_data.data.cloudinit_config.al2023_eks_managed_node_group", + "module.eks.module.self_managed_node_group.module.user_data.data.cloudinit_config.linux_eks_managed_node_group", + "module.eks.module.self_managed_node_group.module.user_data.null_resource.validate_cluster_service_cidr", + "module.eks.time_sleep.this", + "module.vpc.aws_subnet.private", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ] + } + ] + }, + { + "module": "module.eks", + "mode": "managed", + "type": "aws_eks_cluster", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 1, + "attributes": { + "access_config": [ + { + "authentication_mode": "API_AND_CONFIG_MAP", + "bootstrap_cluster_creator_admin_permissions": false + } + ], + "arn": "arn:aws:eks:us-west-2:027423573553:cluster/observability-stack", + "bootstrap_self_managed_addons": true, + "certificate_authority": [ + { + "data": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURCVENDQWUyZ0F3SUJBZ0lJWUw3U21MRHdoQ1F3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB5TmpBek1UZ3lNREU1TURsYUZ3MHpOakF6TVRVeU1ESTBNRGxhTUJVeApFekFSQmdOVkJBTVRDbXQxWW1WeWJtVjBaWE13Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLCkFvSUJBUURoYjF3aHBHSVlpa3U5TUV6Mnl3ck5DMnNHNUVnL3M3Tkd1Q1BaYzREOWxaclk0dE9ldmhyZFcvTWoKTHp3T21POXBTMnVxd2FFWnBDTmxMVWdDMXV6Z3JJRi9abFRqU2x6c0VJaldYbFRUQWE1N05FWmpLR28xeFJKTwpBbFovZy9TaHVXcFd2NFU1UHNLN2NlK3lwbDI0NVIzRzVrVnFWbkkwdkRwMjU1YVg1V0N6bnpSUm5yNU9WVE5QCndmMGh3bC9QUEpvYVRLYkhKcGk5QWRmMVIrbFdWZlFEdmhKckcwN2JBSGNncWhGYnNLd0JkWVlaK2JWYzdCVmQKd0dnb2NqYU4xMkI1SnlnKzBjUmFHN3NEdmdibk9zQ2hMbVdJeWRwL0tEVldSOGwwWU54dkdBR1c4R1I3S3AyUApLTHV1R290bVRyZ2xMN1pZZkJVRjQxU1o0VVBOQWdNQkFBR2pXVEJYTUE0R0ExVWREd0VCL3dRRUF3SUNwREFQCkJnTlZIUk1CQWY4RUJUQURBUUgvTUIwR0ExVWREZ1FXQkJRQlc3RG1rSGpQUmkycWpLR01uM2I2cnRWTThqQVYKQmdOVkhSRUVEakFNZ2dwcmRXSmxjbTVsZEdWek1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQlBBS3NwcjFCdwo4Tk9qTWVGTTZ6NEpsQ0pSaVRBNWVxd01XdDZpcGk0a2xnT0l0WDEwV2M4S25IeEpIME9uNG9CdVo5d1NsQmRTCmxocHk4elpmSXkreVVKVFRuMC9SdWlmbVdtd2NpNXlFZzZjWmpzclh1TVA2Nm5aektZNzdVVitVb05INzlKNlYKdlBOeVBQaVo4N1ZIdzJ2SVFGWFFjczIyQ09LQnB1YUNpWGZONUROdnpiaHJLWGQ3d3NaMTRLY1NEaTVBK3hrTwpGWHRTRFVHS09IdXNZcEQ5L3R3NkZ1d0lMYWY4WFFBb2toK0Z3aHc5OWltU0hzVlkrKys2dGQycVhKT0J6TjVNCnlVUi9lWGhTZGdpazFTSTFNZVZ5c1d2RDFJejlhNFNsUFJlZG1jSGRxdC9tejRLUFFaMjBGUmVsN0NWQVEyOHEKaDlTeXV3UFRPcWc2Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K" + } + ], + "cluster_id": null, + "compute_config": [], + "created_at": "2026-03-18T20:18:51Z", + "enabled_cluster_log_types": [ + "api", + "audit", + "authenticator" + ], + "encryption_config": [ + { + "provider": [ + { + "key_arn": "arn:aws:kms:us-west-2:027423573553:key/12030f91-64b4-40e3-b7ad-77340e0391c7" + } + ], + "resources": [ + "secrets" + ] + } + ], + "endpoint": "https://91D986DCB52447A7F312838B02FCD62D.gr7.us-west-2.eks.amazonaws.com", + "force_update_version": null, + "id": "observability-stack", + "identity": [ + { + "oidc": [ + { + "issuer": "https://oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D" + } + ] + } + ], + "kubernetes_network_config": [ + { + "elastic_load_balancing": [ + { + "enabled": false + } + ], + "ip_family": "ipv4", + "service_ipv4_cidr": "172.20.0.0/16", + "service_ipv6_cidr": "" + } + ], + "name": "observability-stack", + "outpost_config": [], + "platform_version": "eks.39", + "remote_network_config": [], + "role_arn": "arn:aws:iam::027423573553:role/observability-stack-cluster-20260318201827553600000003", + "status": "ACTIVE", + "storage_config": [], + "tags": { + "terraform-aws-modules": "eks" + }, + "tags_all": { + "ManagedBy": "terraform", + "Project": "observability-stack", + "terraform-aws-modules": "eks" + }, + "timeouts": { + "create": null, + "delete": null, + "update": null + }, + "upgrade_policy": [ + { + "support_type": "EXTENDED" + } + ], + "version": "1.32", + "vpc_config": [ + { + "cluster_security_group_id": "sg-03c8bf9784bd7274e", + "endpoint_private_access": true, + "endpoint_public_access": true, + "public_access_cidrs": [ + "0.0.0.0/0" + ], + "security_group_ids": [ + "sg-0a09a2f98bc2b809b" + ], + "subnet_ids": [ + "subnet-00bc6b6598ab09efb", + "subnet-06f8647c688701ae4", + "subnet-0862c3b38b530fd97" + ], + "vpc_id": "vpc-03aefcf5aa0581d7a" + } + ], + "zonal_shift_config": [] + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjoxODAwMDAwMDAwMDAwLCJkZWxldGUiOjkwMDAwMDAwMDAwMCwidXBkYXRlIjozNjAwMDAwMDAwMDAwfSwic2NoZW1hX3ZlcnNpb24iOiIxIn0=", + "dependencies": [ + "data.aws_availability_zones.available", + "module.eks.aws_cloudwatch_log_group.this", + "module.eks.aws_iam_policy.cni_ipv6_policy", + "module.eks.aws_iam_role.eks_auto", + "module.eks.aws_iam_role.this", + "module.eks.aws_iam_role_policy_attachment.this", + "module.eks.aws_security_group.cluster", + "module.eks.aws_security_group.node", + "module.eks.aws_security_group_rule.cluster", + "module.eks.aws_security_group_rule.node", + "module.eks.data.aws_caller_identity.current", + "module.eks.data.aws_iam_policy_document.assume_role_policy", + "module.eks.data.aws_iam_policy_document.cni_ipv6_policy", + "module.eks.data.aws_iam_policy_document.node_assume_role_policy", + "module.eks.data.aws_iam_session_context.current", + "module.eks.data.aws_partition.current", + "module.eks.module.kms.aws_kms_external_key.this", + "module.eks.module.kms.aws_kms_key.this", + "module.eks.module.kms.aws_kms_replica_external_key.this", + "module.eks.module.kms.aws_kms_replica_key.this", + "module.eks.module.kms.data.aws_caller_identity.current", + "module.eks.module.kms.data.aws_iam_policy_document.this", + "module.eks.module.kms.data.aws_partition.current", + "module.vpc.aws_subnet.private", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ], + "create_before_destroy": true + } + ] + }, + { + "module": "module.eks", + "mode": "managed", + "type": "aws_eks_identity_provider_config", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.eks", + "mode": "managed", + "type": "aws_iam_openid_connect_provider", + "name": "oidc_provider", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "arn": "arn:aws:iam::027423573553:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D", + "client_id_list": [ + "sts.amazonaws.com" + ], + "id": "arn:aws:iam::027423573553:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D", + "tags": { + "Name": "observability-stack-eks-irsa" + }, + "tags_all": { + "ManagedBy": "terraform", + "Name": "observability-stack-eks-irsa", + "Project": "observability-stack" + }, + "thumbprint_list": [ + "06b25927c42a721631c1efd9431e648fa62e1e39" + ], + "url": "oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "data.aws_availability_zones.available", + "module.eks.aws_cloudwatch_log_group.this", + "module.eks.aws_eks_cluster.this", + "module.eks.aws_iam_policy.cni_ipv6_policy", + "module.eks.aws_iam_role.eks_auto", + "module.eks.aws_iam_role.this", + "module.eks.aws_iam_role_policy_attachment.this", + "module.eks.aws_security_group.cluster", + "module.eks.aws_security_group.node", + "module.eks.aws_security_group_rule.cluster", + "module.eks.aws_security_group_rule.node", + "module.eks.data.aws_caller_identity.current", + "module.eks.data.aws_iam_policy_document.assume_role_policy", + "module.eks.data.aws_iam_policy_document.cni_ipv6_policy", + "module.eks.data.aws_iam_policy_document.node_assume_role_policy", + "module.eks.data.aws_iam_session_context.current", + "module.eks.data.aws_partition.current", + "module.eks.data.tls_certificate.this", + "module.eks.module.kms.aws_kms_external_key.this", + "module.eks.module.kms.aws_kms_key.this", + "module.eks.module.kms.aws_kms_replica_external_key.this", + "module.eks.module.kms.aws_kms_replica_key.this", + "module.eks.module.kms.data.aws_caller_identity.current", + "module.eks.module.kms.data.aws_iam_policy_document.this", + "module.eks.module.kms.data.aws_partition.current", + "module.vpc.aws_subnet.private", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ] + } + ] + }, + { + "module": "module.eks", + "mode": "managed", + "type": "aws_iam_policy", + "name": "cluster_encryption", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "arn": "arn:aws:iam::027423573553:policy/observability-stack-cluster-ClusterEncryption20260318201849029100000012", + "attachment_count": 1, + "description": "Cluster encryption policy to allow cluster role to utilize CMK provided", + "id": "arn:aws:iam::027423573553:policy/observability-stack-cluster-ClusterEncryption20260318201849029100000012", + "name": "observability-stack-cluster-ClusterEncryption20260318201849029100000012", + "name_prefix": "observability-stack-cluster-ClusterEncryption", + "path": "/", + "policy": "{\"Statement\":[{\"Action\":[\"kms:Encrypt\",\"kms:Decrypt\",\"kms:ListGrants\",\"kms:DescribeKey\"],\"Effect\":\"Allow\",\"Resource\":\"arn:aws:kms:us-west-2:027423573553:key/12030f91-64b4-40e3-b7ad-77340e0391c7\"}],\"Version\":\"2012-10-17\"}", + "policy_id": "ANPAQMYUSQYYRD4S5DT4O", + "tags": {}, + "tags_all": { + "ManagedBy": "terraform", + "Project": "observability-stack" + } + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "module.eks.aws_iam_role.this", + "module.eks.data.aws_caller_identity.current", + "module.eks.data.aws_iam_policy_document.assume_role_policy", + "module.eks.data.aws_iam_session_context.current", + "module.eks.module.kms.aws_kms_external_key.this", + "module.eks.module.kms.aws_kms_key.this", + "module.eks.module.kms.aws_kms_replica_external_key.this", + "module.eks.module.kms.aws_kms_replica_key.this", + "module.eks.module.kms.data.aws_caller_identity.current", + "module.eks.module.kms.data.aws_iam_policy_document.this", + "module.eks.module.kms.data.aws_partition.current" + ] + } + ] + }, + { + "module": "module.eks", + "mode": "managed", + "type": "aws_iam_policy", + "name": "cni_ipv6_policy", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.eks", + "mode": "managed", + "type": "aws_iam_policy", + "name": "custom", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "arn": "arn:aws:iam::027423573553:policy/observability-stack-cluster-20260318201827554500000004", + "attachment_count": 1, + "description": "", + "id": "arn:aws:iam::027423573553:policy/observability-stack-cluster-20260318201827554500000004", + "name": "observability-stack-cluster-20260318201827554500000004", + "name_prefix": "observability-stack-cluster-", + "path": "/", + "policy": "{\"Statement\":[{\"Action\":[\"ec2:RunInstances\",\"ec2:CreateLaunchTemplate\",\"ec2:CreateFleet\"],\"Condition\":{\"StringEquals\":{\"aws:RequestTag/eks:eks-cluster-name\":\"${aws:PrincipalTag/eks:eks-cluster-name}\"},\"StringLike\":{\"aws:RequestTag/eks:kubernetes-node-class-name\":\"*\",\"aws:RequestTag/eks:kubernetes-node-pool-name\":\"*\"}},\"Effect\":\"Allow\",\"Resource\":\"*\",\"Sid\":\"Compute\"},{\"Action\":[\"ec2:CreateVolume\",\"ec2:CreateSnapshot\"],\"Condition\":{\"StringEquals\":{\"aws:RequestTag/eks:eks-cluster-name\":\"${aws:PrincipalTag/eks:eks-cluster-name}\"}},\"Effect\":\"Allow\",\"Resource\":[\"arn:aws:ec2:*:*:volume/*\",\"arn:aws:ec2:*:*:snapshot/*\"],\"Sid\":\"Storage\"},{\"Action\":\"ec2:CreateNetworkInterface\",\"Condition\":{\"StringEquals\":{\"aws:RequestTag/eks:eks-cluster-name\":\"${aws:PrincipalTag/eks:eks-cluster-name}\",\"aws:RequestTag/eks:kubernetes-cni-node-name\":\"*\"}},\"Effect\":\"Allow\",\"Resource\":\"*\",\"Sid\":\"Networking\"},{\"Action\":[\"elasticloadbalancing:CreateTargetGroup\",\"elasticloadbalancing:CreateRule\",\"elasticloadbalancing:CreateLoadBalancer\",\"elasticloadbalancing:CreateListener\",\"ec2:CreateSecurityGroup\"],\"Condition\":{\"StringEquals\":{\"aws:RequestTag/eks:eks-cluster-name\":\"${aws:PrincipalTag/eks:eks-cluster-name}\"}},\"Effect\":\"Allow\",\"Resource\":\"*\",\"Sid\":\"LoadBalancer\"},{\"Action\":\"shield:CreateProtection\",\"Condition\":{\"StringEquals\":{\"aws:RequestTag/eks:eks-cluster-name\":\"${aws:PrincipalTag/eks:eks-cluster-name}\"}},\"Effect\":\"Allow\",\"Resource\":\"*\",\"Sid\":\"ShieldProtection\"},{\"Action\":\"shield:TagResource\",\"Condition\":{\"StringEquals\":{\"aws:RequestTag/eks:eks-cluster-name\":\"${aws:PrincipalTag/eks:eks-cluster-name}\"}},\"Effect\":\"Allow\",\"Resource\":\"arn:aws:shield::*:protection/*\",\"Sid\":\"ShieldTagResource\"}],\"Version\":\"2012-10-17\"}", + "policy_id": "ANPAQMYUSQYYXYGTCPHVU", + "tags": {}, + "tags_all": { + "ManagedBy": "terraform", + "Project": "observability-stack" + } + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "module.eks.data.aws_iam_policy_document.custom", + "module.eks.data.aws_partition.current" + ] + } + ] + }, + { + "module": "module.eks", + "mode": "managed", + "type": "aws_iam_role", + "name": "eks_auto", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.eks", + "mode": "managed", + "type": "aws_iam_role", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "arn": "arn:aws:iam::027423573553:role/observability-stack-cluster-20260318201827553600000003", + "assume_role_policy": "{\"Statement\":[{\"Action\":[\"sts:TagSession\",\"sts:AssumeRole\"],\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"eks.amazonaws.com\"},\"Sid\":\"EKSClusterAssumeRole\"}],\"Version\":\"2012-10-17\"}", + "create_date": "2026-03-18T20:18:27Z", + "description": "", + "force_detach_policies": true, + "id": "observability-stack-cluster-20260318201827553600000003", + "inline_policy": [], + "managed_policy_arns": [ + "arn:aws:iam::027423573553:policy/observability-stack-cluster-20260318201827554500000004", + "arn:aws:iam::027423573553:policy/observability-stack-cluster-ClusterEncryption20260318201849029100000012", + "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy", + "arn:aws:iam::aws:policy/AmazonEKSVPCResourceController" + ], + "max_session_duration": 3600, + "name": "observability-stack-cluster-20260318201827553600000003", + "name_prefix": "observability-stack-cluster-", + "path": "/", + "permissions_boundary": "", + "tags": {}, + "tags_all": { + "ManagedBy": "terraform", + "Project": "observability-stack" + }, + "unique_id": "AROAQMYUSQYY2A3WUUJBE" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "module.eks.data.aws_iam_policy_document.assume_role_policy" + ], + "create_before_destroy": true + } + ] + }, + { + "module": "module.eks", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "additional", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.eks", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "cluster_encryption", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "id": "observability-stack-cluster-20260318201827553600000003-20260318201849597300000013", + "policy_arn": "arn:aws:iam::027423573553:policy/observability-stack-cluster-ClusterEncryption20260318201849029100000012", + "role": "observability-stack-cluster-20260318201827553600000003" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "module.eks.aws_iam_policy.cluster_encryption", + "module.eks.aws_iam_role.this", + "module.eks.data.aws_caller_identity.current", + "module.eks.data.aws_iam_policy_document.assume_role_policy", + "module.eks.data.aws_iam_session_context.current", + "module.eks.module.kms.aws_kms_external_key.this", + "module.eks.module.kms.aws_kms_key.this", + "module.eks.module.kms.aws_kms_replica_external_key.this", + "module.eks.module.kms.aws_kms_replica_key.this", + "module.eks.module.kms.data.aws_caller_identity.current", + "module.eks.module.kms.data.aws_iam_policy_document.this", + "module.eks.module.kms.data.aws_partition.current" + ] + } + ] + }, + { + "module": "module.eks", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "custom", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "id": "observability-stack-cluster-20260318201827553600000003-20260318201828429000000008", + "policy_arn": "arn:aws:iam::027423573553:policy/observability-stack-cluster-20260318201827554500000004", + "role": "observability-stack-cluster-20260318201827553600000003" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "module.eks.aws_iam_policy.custom", + "module.eks.aws_iam_role.this", + "module.eks.data.aws_iam_policy_document.assume_role_policy", + "module.eks.data.aws_iam_policy_document.custom", + "module.eks.data.aws_partition.current" + ] + } + ] + }, + { + "module": "module.eks", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "eks_auto", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.eks", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "eks_auto_additional", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.eks", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": "AmazonEKSClusterPolicy", + "schema_version": 0, + "attributes": { + "id": "observability-stack-cluster-20260318201827553600000003-2026031820182842940000000a", + "policy_arn": "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy", + "role": "observability-stack-cluster-20260318201827553600000003" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "module.eks.aws_iam_role.this", + "module.eks.data.aws_iam_policy_document.assume_role_policy", + "module.eks.data.aws_partition.current" + ], + "create_before_destroy": true + }, + { + "index_key": "AmazonEKSVPCResourceController", + "schema_version": 0, + "attributes": { + "id": "observability-stack-cluster-20260318201827553600000003-2026031820182843710000000c", + "policy_arn": "arn:aws:iam::aws:policy/AmazonEKSVPCResourceController", + "role": "observability-stack-cluster-20260318201827553600000003" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "module.eks.aws_iam_role.this", + "module.eks.data.aws_iam_policy_document.assume_role_policy", + "module.eks.data.aws_partition.current" + ], + "create_before_destroy": true + } + ] + }, + { + "module": "module.eks", + "mode": "managed", + "type": "aws_security_group", + "name": "cluster", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 1, + "attributes": { + "arn": "arn:aws:ec2:us-west-2:027423573553:security-group/sg-0a09a2f98bc2b809b", + "description": "EKS cluster security group", + "egress": [], + "id": "sg-0a09a2f98bc2b809b", + "ingress": [ + { + "cidr_blocks": [], + "description": "Node groups to cluster API", + "from_port": 443, + "ipv6_cidr_blocks": [], + "prefix_list_ids": [], + "protocol": "tcp", + "security_groups": [ + "sg-039c64dc512590a29" + ], + "self": false, + "to_port": 443 + } + ], + "name": "observability-stack-cluster-2026031820184013550000000f", + "name_prefix": "observability-stack-cluster-", + "owner_id": "027423573553", + "revoke_rules_on_delete": false, + "tags": { + "Name": "observability-stack-cluster" + }, + "tags_all": { + "ManagedBy": "terraform", + "Name": "observability-stack-cluster", + "Project": "observability-stack" + }, + "timeouts": null, + "vpc_id": "vpc-03aefcf5aa0581d7a" + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjo2MDAwMDAwMDAwMDAsImRlbGV0ZSI6OTAwMDAwMDAwMDAwfSwic2NoZW1hX3ZlcnNpb24iOiIxIn0=", + "dependencies": [ + "module.vpc.aws_vpc.this" + ], + "create_before_destroy": true + } + ] + }, + { + "module": "module.eks", + "mode": "managed", + "type": "aws_security_group", + "name": "node", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 1, + "attributes": { + "arn": "arn:aws:ec2:us-west-2:027423573553:security-group/sg-039c64dc512590a29", + "description": "EKS node shared security group", + "egress": [ + { + "cidr_blocks": [ + "0.0.0.0/0" + ], + "description": "Allow all egress", + "from_port": 0, + "ipv6_cidr_blocks": [], + "prefix_list_ids": [], + "protocol": "-1", + "security_groups": [], + "self": false, + "to_port": 0 + } + ], + "id": "sg-039c64dc512590a29", + "ingress": [ + { + "cidr_blocks": [], + "description": "Cluster API to node 4443/tcp webhook", + "from_port": 4443, + "ipv6_cidr_blocks": [], + "prefix_list_ids": [], + "protocol": "tcp", + "security_groups": [ + "sg-0a09a2f98bc2b809b" + ], + "self": false, + "to_port": 4443 + }, + { + "cidr_blocks": [], + "description": "Cluster API to node 6443/tcp webhook", + "from_port": 6443, + "ipv6_cidr_blocks": [], + "prefix_list_ids": [], + "protocol": "tcp", + "security_groups": [ + "sg-0a09a2f98bc2b809b" + ], + "self": false, + "to_port": 6443 + }, + { + "cidr_blocks": [], + "description": "Cluster API to node 8443/tcp webhook", + "from_port": 8443, + "ipv6_cidr_blocks": [], + "prefix_list_ids": [], + "protocol": "tcp", + "security_groups": [ + "sg-0a09a2f98bc2b809b" + ], + "self": false, + "to_port": 8443 + }, + { + "cidr_blocks": [], + "description": "Cluster API to node 9443/tcp webhook", + "from_port": 9443, + "ipv6_cidr_blocks": [], + "prefix_list_ids": [], + "protocol": "tcp", + "security_groups": [ + "sg-0a09a2f98bc2b809b" + ], + "self": false, + "to_port": 9443 + }, + { + "cidr_blocks": [], + "description": "Cluster API to node groups", + "from_port": 443, + "ipv6_cidr_blocks": [], + "prefix_list_ids": [], + "protocol": "tcp", + "security_groups": [ + "sg-0a09a2f98bc2b809b" + ], + "self": false, + "to_port": 443 + }, + { + "cidr_blocks": [], + "description": "Cluster API to node kubelets", + "from_port": 10250, + "ipv6_cidr_blocks": [], + "prefix_list_ids": [], + "protocol": "tcp", + "security_groups": [ + "sg-0a09a2f98bc2b809b" + ], + "self": false, + "to_port": 10250 + }, + { + "cidr_blocks": [], + "description": "Node to node CoreDNS UDP", + "from_port": 53, + "ipv6_cidr_blocks": [], + "prefix_list_ids": [], + "protocol": "udp", + "security_groups": [], + "self": true, + "to_port": 53 + }, + { + "cidr_blocks": [], + "description": "Node to node CoreDNS", + "from_port": 53, + "ipv6_cidr_blocks": [], + "prefix_list_ids": [], + "protocol": "tcp", + "security_groups": [], + "self": true, + "to_port": 53 + }, + { + "cidr_blocks": [], + "description": "Node to node ingress on ephemeral ports", + "from_port": 1025, + "ipv6_cidr_blocks": [], + "prefix_list_ids": [], + "protocol": "tcp", + "security_groups": [], + "self": true, + "to_port": 65535 + }, + { + "cidr_blocks": [], + "description": "elbv2.k8s.aws/targetGroupBinding=shared", + "from_port": 5601, + "ipv6_cidr_blocks": [], + "prefix_list_ids": [], + "protocol": "tcp", + "security_groups": [ + "sg-0ec86f6fd3561da11" + ], + "self": false, + "to_port": 5601 + } + ], + "name": "observability-stack-node-20260318201840542000000010", + "name_prefix": "observability-stack-node-", + "owner_id": "027423573553", + "revoke_rules_on_delete": false, + "tags": { + "Name": "observability-stack-node", + "kubernetes.io/cluster/observability-stack": "owned" + }, + "tags_all": { + "ManagedBy": "terraform", + "Name": "observability-stack-node", + "Project": "observability-stack", + "kubernetes.io/cluster/observability-stack": "owned" + }, + "timeouts": null, + "vpc_id": "vpc-03aefcf5aa0581d7a" + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjo2MDAwMDAwMDAwMDAsImRlbGV0ZSI6OTAwMDAwMDAwMDAwfSwic2NoZW1hX3ZlcnNpb24iOiIxIn0=", + "dependencies": [ + "module.vpc.aws_vpc.this" + ], + "create_before_destroy": true + } + ] + }, + { + "module": "module.eks", + "mode": "managed", + "type": "aws_security_group_rule", + "name": "cluster", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": "ingress_nodes_443", + "schema_version": 2, + "attributes": { + "cidr_blocks": null, + "description": "Node groups to cluster API", + "from_port": 443, + "id": "sgrule-1181540205", + "ipv6_cidr_blocks": null, + "prefix_list_ids": null, + "protocol": "tcp", + "security_group_id": "sg-0a09a2f98bc2b809b", + "security_group_rule_id": "sgr-077f102466a349635", + "self": false, + "source_security_group_id": "sg-039c64dc512590a29", + "timeouts": null, + "to_port": 443, + "type": "ingress" + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjozMDAwMDAwMDAwMDB9LCJzY2hlbWFfdmVyc2lvbiI6IjIifQ==", + "dependencies": [ + "module.eks.aws_security_group.cluster", + "module.eks.aws_security_group.node", + "module.vpc.aws_vpc.this" + ], + "create_before_destroy": true + } + ] + }, + { + "module": "module.eks", + "mode": "managed", + "type": "aws_security_group_rule", + "name": "node", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": "egress_all", + "schema_version": 2, + "attributes": { + "cidr_blocks": [ + "0.0.0.0/0" + ], + "description": "Allow all egress", + "from_port": 0, + "id": "sgrule-2475787203", + "ipv6_cidr_blocks": null, + "prefix_list_ids": [], + "protocol": "-1", + "security_group_id": "sg-039c64dc512590a29", + "security_group_rule_id": "sgr-0f66e35b51a2a9856", + "self": false, + "source_security_group_id": null, + "timeouts": null, + "to_port": 0, + "type": "egress" + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjozMDAwMDAwMDAwMDB9LCJzY2hlbWFfdmVyc2lvbiI6IjIifQ==", + "dependencies": [ + "module.eks.aws_security_group.cluster", + "module.eks.aws_security_group.node", + "module.vpc.aws_vpc.this" + ], + "create_before_destroy": true + }, + { + "index_key": "ingress_cluster_443", + "schema_version": 2, + "attributes": { + "cidr_blocks": null, + "description": "Cluster API to node groups", + "from_port": 443, + "id": "sgrule-1462776238", + "ipv6_cidr_blocks": null, + "prefix_list_ids": [], + "protocol": "tcp", + "security_group_id": "sg-039c64dc512590a29", + "security_group_rule_id": "sgr-092cf55f6b375a4e1", + "self": false, + "source_security_group_id": "sg-0a09a2f98bc2b809b", + "timeouts": null, + "to_port": 443, + "type": "ingress" + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjozMDAwMDAwMDAwMDB9LCJzY2hlbWFfdmVyc2lvbiI6IjIifQ==", + "dependencies": [ + "module.eks.aws_security_group.cluster", + "module.eks.aws_security_group.node", + "module.vpc.aws_vpc.this" + ], + "create_before_destroy": true + }, + { + "index_key": "ingress_cluster_4443_webhook", + "schema_version": 2, + "attributes": { + "cidr_blocks": null, + "description": "Cluster API to node 4443/tcp webhook", + "from_port": 4443, + "id": "sgrule-2443875299", + "ipv6_cidr_blocks": null, + "prefix_list_ids": [], + "protocol": "tcp", + "security_group_id": "sg-039c64dc512590a29", + "security_group_rule_id": "sgr-008e3e3dfb3bfde5c", + "self": false, + "source_security_group_id": "sg-0a09a2f98bc2b809b", + "timeouts": null, + "to_port": 4443, + "type": "ingress" + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjozMDAwMDAwMDAwMDB9LCJzY2hlbWFfdmVyc2lvbiI6IjIifQ==", + "dependencies": [ + "module.eks.aws_security_group.cluster", + "module.eks.aws_security_group.node", + "module.vpc.aws_vpc.this" + ], + "create_before_destroy": true + }, + { + "index_key": "ingress_cluster_6443_webhook", + "schema_version": 2, + "attributes": { + "cidr_blocks": null, + "description": "Cluster API to node 6443/tcp webhook", + "from_port": 6443, + "id": "sgrule-1491661941", + "ipv6_cidr_blocks": null, + "prefix_list_ids": [], + "protocol": "tcp", + "security_group_id": "sg-039c64dc512590a29", + "security_group_rule_id": "sgr-05878181195aef7de", + "self": false, + "source_security_group_id": "sg-0a09a2f98bc2b809b", + "timeouts": null, + "to_port": 6443, + "type": "ingress" + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjozMDAwMDAwMDAwMDB9LCJzY2hlbWFfdmVyc2lvbiI6IjIifQ==", + "dependencies": [ + "module.eks.aws_security_group.cluster", + "module.eks.aws_security_group.node", + "module.vpc.aws_vpc.this" + ], + "create_before_destroy": true + }, + { + "index_key": "ingress_cluster_8443_webhook", + "schema_version": 2, + "attributes": { + "cidr_blocks": null, + "description": "Cluster API to node 8443/tcp webhook", + "from_port": 8443, + "id": "sgrule-1270138964", + "ipv6_cidr_blocks": null, + "prefix_list_ids": [], + "protocol": "tcp", + "security_group_id": "sg-039c64dc512590a29", + "security_group_rule_id": "sgr-0af67159d3876a1de", + "self": false, + "source_security_group_id": "sg-0a09a2f98bc2b809b", + "timeouts": null, + "to_port": 8443, + "type": "ingress" + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjozMDAwMDAwMDAwMDB9LCJzY2hlbWFfdmVyc2lvbiI6IjIifQ==", + "dependencies": [ + "module.eks.aws_security_group.cluster", + "module.eks.aws_security_group.node", + "module.vpc.aws_vpc.this" + ], + "create_before_destroy": true + }, + { + "index_key": "ingress_cluster_9443_webhook", + "schema_version": 2, + "attributes": { + "cidr_blocks": null, + "description": "Cluster API to node 9443/tcp webhook", + "from_port": 9443, + "id": "sgrule-789969823", + "ipv6_cidr_blocks": null, + "prefix_list_ids": [], + "protocol": "tcp", + "security_group_id": "sg-039c64dc512590a29", + "security_group_rule_id": "sgr-05c24769847b5b659", + "self": false, + "source_security_group_id": "sg-0a09a2f98bc2b809b", + "timeouts": null, + "to_port": 9443, + "type": "ingress" + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjozMDAwMDAwMDAwMDB9LCJzY2hlbWFfdmVyc2lvbiI6IjIifQ==", + "dependencies": [ + "module.eks.aws_security_group.cluster", + "module.eks.aws_security_group.node", + "module.vpc.aws_vpc.this" + ], + "create_before_destroy": true + }, + { + "index_key": "ingress_cluster_kubelet", + "schema_version": 2, + "attributes": { + "cidr_blocks": null, + "description": "Cluster API to node kubelets", + "from_port": 10250, + "id": "sgrule-1472426363", + "ipv6_cidr_blocks": null, + "prefix_list_ids": [], + "protocol": "tcp", + "security_group_id": "sg-039c64dc512590a29", + "security_group_rule_id": "sgr-0ffdd1c8be8659dce", + "self": false, + "source_security_group_id": "sg-0a09a2f98bc2b809b", + "timeouts": null, + "to_port": 10250, + "type": "ingress" + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjozMDAwMDAwMDAwMDB9LCJzY2hlbWFfdmVyc2lvbiI6IjIifQ==", + "dependencies": [ + "module.eks.aws_security_group.cluster", + "module.eks.aws_security_group.node", + "module.vpc.aws_vpc.this" + ], + "create_before_destroy": true + }, + { + "index_key": "ingress_nodes_ephemeral", + "schema_version": 2, + "attributes": { + "cidr_blocks": null, + "description": "Node to node ingress on ephemeral ports", + "from_port": 1025, + "id": "sgrule-1052607575", + "ipv6_cidr_blocks": null, + "prefix_list_ids": [], + "protocol": "tcp", + "security_group_id": "sg-039c64dc512590a29", + "security_group_rule_id": "sgr-0357697388ca61651", + "self": true, + "source_security_group_id": null, + "timeouts": null, + "to_port": 65535, + "type": "ingress" + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjozMDAwMDAwMDAwMDB9LCJzY2hlbWFfdmVyc2lvbiI6IjIifQ==", + "dependencies": [ + "module.eks.aws_security_group.cluster", + "module.eks.aws_security_group.node", + "module.vpc.aws_vpc.this" + ], + "create_before_destroy": true + }, + { + "index_key": "ingress_self_coredns_tcp", + "schema_version": 2, + "attributes": { + "cidr_blocks": null, + "description": "Node to node CoreDNS", + "from_port": 53, + "id": "sgrule-2727722642", + "ipv6_cidr_blocks": null, + "prefix_list_ids": [], + "protocol": "tcp", + "security_group_id": "sg-039c64dc512590a29", + "security_group_rule_id": "sgr-079d67d71e8513449", + "self": true, + "source_security_group_id": null, + "timeouts": null, + "to_port": 53, + "type": "ingress" + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjozMDAwMDAwMDAwMDB9LCJzY2hlbWFfdmVyc2lvbiI6IjIifQ==", + "dependencies": [ + "module.eks.aws_security_group.cluster", + "module.eks.aws_security_group.node", + "module.vpc.aws_vpc.this" + ], + "create_before_destroy": true + }, + { + "index_key": "ingress_self_coredns_udp", + "schema_version": 2, + "attributes": { + "cidr_blocks": null, + "description": "Node to node CoreDNS UDP", + "from_port": 53, + "id": "sgrule-113909117", + "ipv6_cidr_blocks": null, + "prefix_list_ids": [], + "protocol": "udp", + "security_group_id": "sg-039c64dc512590a29", + "security_group_rule_id": "sgr-03497585c3ae5e8b8", + "self": true, + "source_security_group_id": null, + "timeouts": null, + "to_port": 53, + "type": "ingress" + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjozMDAwMDAwMDAwMDB9LCJzY2hlbWFfdmVyc2lvbiI6IjIifQ==", + "dependencies": [ + "module.eks.aws_security_group.cluster", + "module.eks.aws_security_group.node", + "module.vpc.aws_vpc.this" + ], + "create_before_destroy": true + } + ] + }, + { + "module": "module.eks", + "mode": "managed", + "type": "time_sleep", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/time\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "create_duration": "30s", + "destroy_duration": null, + "id": "2026-03-18T20:28:43Z", + "triggers": { + "cluster_certificate_authority_data": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURCVENDQWUyZ0F3SUJBZ0lJWUw3U21MRHdoQ1F3RFFZSktvWklodmNOQVFFTEJRQXdGVEVUTUJFR0ExVUUKQXhNS2EzVmlaWEp1WlhSbGN6QWVGdzB5TmpBek1UZ3lNREU1TURsYUZ3MHpOakF6TVRVeU1ESTBNRGxhTUJVeApFekFSQmdOVkJBTVRDbXQxWW1WeWJtVjBaWE13Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLCkFvSUJBUURoYjF3aHBHSVlpa3U5TUV6Mnl3ck5DMnNHNUVnL3M3Tkd1Q1BaYzREOWxaclk0dE9ldmhyZFcvTWoKTHp3T21POXBTMnVxd2FFWnBDTmxMVWdDMXV6Z3JJRi9abFRqU2x6c0VJaldYbFRUQWE1N05FWmpLR28xeFJKTwpBbFovZy9TaHVXcFd2NFU1UHNLN2NlK3lwbDI0NVIzRzVrVnFWbkkwdkRwMjU1YVg1V0N6bnpSUm5yNU9WVE5QCndmMGh3bC9QUEpvYVRLYkhKcGk5QWRmMVIrbFdWZlFEdmhKckcwN2JBSGNncWhGYnNLd0JkWVlaK2JWYzdCVmQKd0dnb2NqYU4xMkI1SnlnKzBjUmFHN3NEdmdibk9zQ2hMbVdJeWRwL0tEVldSOGwwWU54dkdBR1c4R1I3S3AyUApLTHV1R290bVRyZ2xMN1pZZkJVRjQxU1o0VVBOQWdNQkFBR2pXVEJYTUE0R0ExVWREd0VCL3dRRUF3SUNwREFQCkJnTlZIUk1CQWY4RUJUQURBUUgvTUIwR0ExVWREZ1FXQkJRQlc3RG1rSGpQUmkycWpLR01uM2I2cnRWTThqQVYKQmdOVkhSRUVEakFNZ2dwcmRXSmxjbTVsZEdWek1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQlBBS3NwcjFCdwo4Tk9qTWVGTTZ6NEpsQ0pSaVRBNWVxd01XdDZpcGk0a2xnT0l0WDEwV2M4S25IeEpIME9uNG9CdVo5d1NsQmRTCmxocHk4elpmSXkreVVKVFRuMC9SdWlmbVdtd2NpNXlFZzZjWmpzclh1TVA2Nm5aektZNzdVVitVb05INzlKNlYKdlBOeVBQaVo4N1ZIdzJ2SVFGWFFjczIyQ09LQnB1YUNpWGZONUROdnpiaHJLWGQ3d3NaMTRLY1NEaTVBK3hrTwpGWHRTRFVHS09IdXNZcEQ5L3R3NkZ1d0lMYWY4WFFBb2toK0Z3aHc5OWltU0hzVlkrKys2dGQycVhKT0J6TjVNCnlVUi9lWGhTZGdpazFTSTFNZVZ5c1d2RDFJejlhNFNsUFJlZG1jSGRxdC9tejRLUFFaMjBGUmVsN0NWQVEyOHEKaDlTeXV3UFRPcWc2Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K", + "cluster_endpoint": "https://91D986DCB52447A7F312838B02FCD62D.gr7.us-west-2.eks.amazonaws.com", + "cluster_name": "observability-stack", + "cluster_service_cidr": "172.20.0.0/16", + "cluster_version": "1.32" + } + }, + "sensitive_attributes": [], + "dependencies": [ + "data.aws_availability_zones.available", + "module.eks.aws_cloudwatch_log_group.this", + "module.eks.aws_eks_cluster.this", + "module.eks.aws_iam_policy.cni_ipv6_policy", + "module.eks.aws_iam_role.eks_auto", + "module.eks.aws_iam_role.this", + "module.eks.aws_iam_role_policy_attachment.this", + "module.eks.aws_security_group.cluster", + "module.eks.aws_security_group.node", + "module.eks.aws_security_group_rule.cluster", + "module.eks.aws_security_group_rule.node", + "module.eks.data.aws_caller_identity.current", + "module.eks.data.aws_iam_policy_document.assume_role_policy", + "module.eks.data.aws_iam_policy_document.cni_ipv6_policy", + "module.eks.data.aws_iam_policy_document.node_assume_role_policy", + "module.eks.data.aws_iam_session_context.current", + "module.eks.data.aws_partition.current", + "module.eks.module.kms.aws_kms_external_key.this", + "module.eks.module.kms.aws_kms_key.this", + "module.eks.module.kms.aws_kms_replica_external_key.this", + "module.eks.module.kms.aws_kms_replica_key.this", + "module.eks.module.kms.data.aws_caller_identity.current", + "module.eks.module.kms.data.aws_iam_policy_document.this", + "module.eks.module.kms.data.aws_partition.current", + "module.vpc.aws_subnet.private", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ], + "create_before_destroy": true + } + ] + }, + { + "module": "module.eks.module.eks_managed_node_group[\"default\"]", + "mode": "data", + "type": "aws_caller_identity", + "name": "current", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "account_id": "027423573553", + "arn": "arn:aws:sts::027423573553:assumed-role/Admin/kylhouns-Isengard", + "id": "027423573553", + "user_id": "AROAQMYUSQYYXMMZMGMPD:kylhouns-Isengard" + }, + "sensitive_attributes": [] + } + ] + }, + { + "module": "module.eks.module.eks_managed_node_group[\"default\"]", + "mode": "data", + "type": "aws_ec2_instance_type", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.eks.module.eks_managed_node_group[\"default\"]", + "mode": "data", + "type": "aws_ec2_instance_type_offerings", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.eks.module.eks_managed_node_group[\"default\"]", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "assume_role_policy", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "id": "2560088296", + "json": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"EKSNodeAssumeRole\",\n \"Effect\": \"Allow\",\n \"Action\": \"sts:AssumeRole\",\n \"Principal\": {\n \"Service\": \"ec2.amazonaws.com\"\n }\n }\n ]\n}", + "minified_json": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"EKSNodeAssumeRole\",\"Effect\":\"Allow\",\"Action\":\"sts:AssumeRole\",\"Principal\":{\"Service\":\"ec2.amazonaws.com\"}}]}", + "override_json": null, + "override_policy_documents": null, + "policy_id": null, + "source_json": null, + "source_policy_documents": null, + "statement": [ + { + "actions": [ + "sts:AssumeRole" + ], + "condition": [], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [ + { + "identifiers": [ + "ec2.amazonaws.com" + ], + "type": "Service" + } + ], + "resources": [], + "sid": "EKSNodeAssumeRole" + } + ], + "version": "2012-10-17" + }, + "sensitive_attributes": [] + } + ] + }, + { + "module": "module.eks.module.eks_managed_node_group[\"default\"]", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "role", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.eks.module.eks_managed_node_group[\"default\"]", + "mode": "data", + "type": "aws_partition", + "name": "current", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "dns_suffix": "amazonaws.com", + "id": "aws", + "partition": "aws", + "reverse_dns_prefix": "com.amazonaws" + }, + "sensitive_attributes": [] + } + ] + }, + { + "module": "module.eks.module.eks_managed_node_group[\"default\"]", + "mode": "data", + "type": "aws_ssm_parameter", + "name": "ami", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.eks.module.eks_managed_node_group[\"default\"]", + "mode": "data", + "type": "aws_subnets", + "name": "placement_group", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.eks.module.eks_managed_node_group[\"default\"]", + "mode": "managed", + "type": "aws_autoscaling_schedule", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.eks.module.eks_managed_node_group[\"default\"]", + "mode": "managed", + "type": "aws_eks_node_group", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "ami_type": "AL2023_x86_64_STANDARD", + "arn": "arn:aws:eks:us-west-2:027423573553:nodegroup/observability-stack/default-20260318202959387700000001/f6ce8152-07c7-695e-68a7-64098e591426", + "capacity_type": "ON_DEMAND", + "cluster_name": "observability-stack", + "disk_size": 0, + "force_update_version": null, + "id": "observability-stack:default-20260318202959387700000001", + "instance_types": [ + "m5.xlarge" + ], + "labels": {}, + "launch_template": [ + { + "id": "lt-0fde2bc540de7fc87", + "name": "default-20260318202843435600000017", + "version": "1" + } + ], + "node_group_name": "default-20260318202959387700000001", + "node_group_name_prefix": "default-", + "node_repair_config": [], + "node_role_arn": "arn:aws:iam::027423573553:role/default-eks-node-group-20260318201827553200000002", + "release_version": "1.32.12-20260304", + "remote_access": [], + "resources": [ + { + "autoscaling_groups": [ + { + "name": "eks-default-20260318202959387700000001-f6ce8152-07c7-695e-68a7-64098e591426" + } + ], + "remote_access_security_group_id": "" + } + ], + "scaling_config": [ + { + "desired_size": 4, + "max_size": 5, + "min_size": 4 + } + ], + "status": "ACTIVE", + "subnet_ids": [ + "subnet-00bc6b6598ab09efb", + "subnet-06f8647c688701ae4", + "subnet-0862c3b38b530fd97" + ], + "tags": { + "Name": "default" + }, + "tags_all": { + "ManagedBy": "terraform", + "Name": "default", + "Project": "observability-stack" + }, + "taint": [], + "timeouts": { + "create": null, + "delete": null, + "update": null + }, + "update_config": [ + { + "max_unavailable": 0, + "max_unavailable_percentage": 33 + } + ], + "version": "1.32" + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjozNjAwMDAwMDAwMDAwLCJkZWxldGUiOjM2MDAwMDAwMDAwMDAsInVwZGF0ZSI6MzYwMDAwMDAwMDAwMH19", + "dependencies": [ + "data.aws_availability_zones.available", + "module.eks.aws_cloudwatch_log_group.this", + "module.eks.aws_eks_cluster.this", + "module.eks.aws_iam_policy.cni_ipv6_policy", + "module.eks.aws_iam_role.eks_auto", + "module.eks.aws_iam_role.this", + "module.eks.aws_iam_role_policy_attachment.this", + "module.eks.aws_security_group.cluster", + "module.eks.aws_security_group.node", + "module.eks.aws_security_group_rule.cluster", + "module.eks.aws_security_group_rule.node", + "module.eks.data.aws_caller_identity.current", + "module.eks.data.aws_iam_policy_document.assume_role_policy", + "module.eks.data.aws_iam_policy_document.cni_ipv6_policy", + "module.eks.data.aws_iam_policy_document.node_assume_role_policy", + "module.eks.data.aws_iam_session_context.current", + "module.eks.data.aws_partition.current", + "module.eks.module.eks_managed_node_group.aws_iam_role.this", + "module.eks.module.eks_managed_node_group.aws_iam_role_policy_attachment.additional", + "module.eks.module.eks_managed_node_group.aws_iam_role_policy_attachment.this", + "module.eks.module.eks_managed_node_group.aws_launch_template.this", + "module.eks.module.eks_managed_node_group.aws_placement_group.this", + "module.eks.module.eks_managed_node_group.data.aws_caller_identity.current", + "module.eks.module.eks_managed_node_group.data.aws_ec2_instance_type.this", + "module.eks.module.eks_managed_node_group.data.aws_ec2_instance_type_offerings.this", + "module.eks.module.eks_managed_node_group.data.aws_iam_policy_document.assume_role_policy", + "module.eks.module.eks_managed_node_group.data.aws_partition.current", + "module.eks.module.eks_managed_node_group.data.aws_ssm_parameter.ami", + "module.eks.module.eks_managed_node_group.data.aws_subnets.placement_group", + "module.eks.module.eks_managed_node_group.module.user_data.data.cloudinit_config.al2023_eks_managed_node_group", + "module.eks.module.eks_managed_node_group.module.user_data.data.cloudinit_config.linux_eks_managed_node_group", + "module.eks.module.kms.aws_kms_external_key.this", + "module.eks.module.kms.aws_kms_key.this", + "module.eks.module.kms.aws_kms_replica_external_key.this", + "module.eks.module.kms.aws_kms_replica_key.this", + "module.eks.module.kms.data.aws_caller_identity.current", + "module.eks.module.kms.data.aws_iam_policy_document.this", + "module.eks.module.kms.data.aws_partition.current", + "module.eks.time_sleep.this", + "module.vpc.aws_subnet.private", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ], + "create_before_destroy": true + } + ] + }, + { + "module": "module.eks.module.eks_managed_node_group[\"default\"]", + "mode": "managed", + "type": "aws_iam_role", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "arn": "arn:aws:iam::027423573553:role/default-eks-node-group-20260318201827553200000002", + "assume_role_policy": "{\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"ec2.amazonaws.com\"},\"Sid\":\"EKSNodeAssumeRole\"}],\"Version\":\"2012-10-17\"}", + "create_date": "2026-03-18T20:18:27Z", + "description": "EKS managed node group IAM role", + "force_detach_policies": true, + "id": "default-eks-node-group-20260318201827553200000002", + "inline_policy": [], + "managed_policy_arns": [ + "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly", + "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy", + "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy" + ], + "max_session_duration": 3600, + "name": "default-eks-node-group-20260318201827553200000002", + "name_prefix": "default-eks-node-group-", + "path": "/", + "permissions_boundary": "", + "tags": {}, + "tags_all": { + "ManagedBy": "terraform", + "Project": "observability-stack" + }, + "unique_id": "AROAQMYUSQYYRLTLVDS3L" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "data.aws_availability_zones.available", + "module.eks.module.eks_managed_node_group.data.aws_iam_policy_document.assume_role_policy", + "module.vpc.aws_subnet.private", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ], + "create_before_destroy": true + } + ] + }, + { + "module": "module.eks.module.eks_managed_node_group[\"default\"]", + "mode": "managed", + "type": "aws_iam_role_policy", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.eks.module.eks_managed_node_group[\"default\"]", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "additional", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.eks.module.eks_managed_node_group[\"default\"]", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": "AmazonEC2ContainerRegistryReadOnly", + "schema_version": 0, + "attributes": { + "id": "default-eks-node-group-20260318201827553200000002-20260318201828420400000007", + "policy_arn": "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly", + "role": "default-eks-node-group-20260318201827553200000002" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "data.aws_availability_zones.available", + "module.eks.module.eks_managed_node_group.aws_iam_role.this", + "module.eks.module.eks_managed_node_group.data.aws_caller_identity.current", + "module.eks.module.eks_managed_node_group.data.aws_iam_policy_document.assume_role_policy", + "module.eks.module.eks_managed_node_group.data.aws_partition.current", + "module.vpc.aws_subnet.private", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ], + "create_before_destroy": true + }, + { + "index_key": "AmazonEKSWorkerNodePolicy", + "schema_version": 0, + "attributes": { + "id": "default-eks-node-group-20260318201827553200000002-20260318201828429000000009", + "policy_arn": "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy", + "role": "default-eks-node-group-20260318201827553200000002" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "data.aws_availability_zones.available", + "module.eks.module.eks_managed_node_group.aws_iam_role.this", + "module.eks.module.eks_managed_node_group.data.aws_caller_identity.current", + "module.eks.module.eks_managed_node_group.data.aws_iam_policy_document.assume_role_policy", + "module.eks.module.eks_managed_node_group.data.aws_partition.current", + "module.vpc.aws_subnet.private", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ], + "create_before_destroy": true + }, + { + "index_key": "AmazonEKS_CNI_Policy", + "schema_version": 0, + "attributes": { + "id": "default-eks-node-group-20260318201827553200000002-2026031820182843710000000b", + "policy_arn": "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy", + "role": "default-eks-node-group-20260318201827553200000002" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "data.aws_availability_zones.available", + "module.eks.module.eks_managed_node_group.aws_iam_role.this", + "module.eks.module.eks_managed_node_group.data.aws_caller_identity.current", + "module.eks.module.eks_managed_node_group.data.aws_iam_policy_document.assume_role_policy", + "module.eks.module.eks_managed_node_group.data.aws_partition.current", + "module.vpc.aws_subnet.private", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ], + "create_before_destroy": true + } + ] + }, + { + "module": "module.eks.module.eks_managed_node_group[\"default\"]", + "mode": "managed", + "type": "aws_launch_template", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "arn": "arn:aws:ec2:us-west-2:027423573553:launch-template/lt-0fde2bc540de7fc87", + "block_device_mappings": [], + "capacity_reservation_specification": [], + "cpu_options": [], + "credit_specification": [], + "default_version": 1, + "description": "Custom launch template for default EKS managed node group", + "disable_api_stop": false, + "disable_api_termination": false, + "ebs_optimized": "", + "elastic_gpu_specifications": [], + "elastic_inference_accelerator": [], + "enclave_options": [], + "hibernation_options": [], + "iam_instance_profile": [], + "id": "lt-0fde2bc540de7fc87", + "image_id": "", + "instance_initiated_shutdown_behavior": "", + "instance_market_options": [], + "instance_requirements": [], + "instance_type": "", + "kernel_id": "", + "key_name": "", + "latest_version": 1, + "license_specification": [], + "maintenance_options": [], + "metadata_options": [ + { + "http_endpoint": "enabled", + "http_protocol_ipv6": "", + "http_put_response_hop_limit": 2, + "http_tokens": "required", + "instance_metadata_tags": "" + } + ], + "monitoring": [ + { + "enabled": true + } + ], + "name": "default-20260318202843435600000017", + "name_prefix": "default-", + "network_interfaces": [], + "placement": [], + "private_dns_name_options": [], + "ram_disk_id": "", + "security_group_names": [], + "tag_specifications": [ + { + "resource_type": "instance", + "tags": { + "Name": "default" + } + }, + { + "resource_type": "network-interface", + "tags": { + "Name": "default" + } + }, + { + "resource_type": "volume", + "tags": { + "Name": "default" + } + } + ], + "tags": {}, + "tags_all": { + "ManagedBy": "terraform", + "Project": "observability-stack" + }, + "update_default_version": true, + "user_data": "", + "vpc_security_group_ids": [ + "sg-039c64dc512590a29" + ] + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "data.aws_availability_zones.available", + "module.eks.aws_cloudwatch_log_group.this", + "module.eks.aws_eks_cluster.this", + "module.eks.aws_iam_policy.cni_ipv6_policy", + "module.eks.aws_iam_role.eks_auto", + "module.eks.aws_iam_role.this", + "module.eks.aws_iam_role_policy_attachment.this", + "module.eks.aws_security_group.cluster", + "module.eks.aws_security_group.node", + "module.eks.aws_security_group_rule.cluster", + "module.eks.aws_security_group_rule.node", + "module.eks.data.aws_caller_identity.current", + "module.eks.data.aws_iam_policy_document.assume_role_policy", + "module.eks.data.aws_iam_policy_document.cni_ipv6_policy", + "module.eks.data.aws_iam_policy_document.node_assume_role_policy", + "module.eks.data.aws_iam_session_context.current", + "module.eks.data.aws_partition.current", + "module.eks.module.eks_managed_node_group.aws_iam_role.this", + "module.eks.module.eks_managed_node_group.aws_iam_role_policy_attachment.additional", + "module.eks.module.eks_managed_node_group.aws_iam_role_policy_attachment.this", + "module.eks.module.eks_managed_node_group.aws_placement_group.this", + "module.eks.module.eks_managed_node_group.data.aws_caller_identity.current", + "module.eks.module.eks_managed_node_group.data.aws_ec2_instance_type.this", + "module.eks.module.eks_managed_node_group.data.aws_iam_policy_document.assume_role_policy", + "module.eks.module.eks_managed_node_group.data.aws_partition.current", + "module.eks.module.eks_managed_node_group.module.user_data.data.cloudinit_config.al2023_eks_managed_node_group", + "module.eks.module.eks_managed_node_group.module.user_data.data.cloudinit_config.linux_eks_managed_node_group", + "module.eks.module.kms.aws_kms_external_key.this", + "module.eks.module.kms.aws_kms_key.this", + "module.eks.module.kms.aws_kms_replica_external_key.this", + "module.eks.module.kms.aws_kms_replica_key.this", + "module.eks.module.kms.data.aws_caller_identity.current", + "module.eks.module.kms.data.aws_iam_policy_document.this", + "module.eks.module.kms.data.aws_partition.current", + "module.eks.time_sleep.this", + "module.vpc.aws_subnet.private", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ], + "create_before_destroy": true + } + ] + }, + { + "module": "module.eks.module.eks_managed_node_group[\"default\"]", + "mode": "managed", + "type": "aws_placement_group", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.eks.module.eks_managed_node_group[\"default\"].module.user_data", + "mode": "data", + "type": "cloudinit_config", + "name": "al2023_eks_managed_node_group", + "provider": "provider[\"registry.terraform.io/hashicorp/cloudinit\"]", + "instances": [] + }, + { + "module": "module.eks.module.eks_managed_node_group[\"default\"].module.user_data", + "mode": "data", + "type": "cloudinit_config", + "name": "linux_eks_managed_node_group", + "provider": "provider[\"registry.terraform.io/hashicorp/cloudinit\"]", + "instances": [] + }, + { + "module": "module.eks.module.eks_managed_node_group[\"default\"].module.user_data", + "mode": "managed", + "type": "null_resource", + "name": "validate_cluster_service_cidr", + "provider": "provider[\"registry.terraform.io/hashicorp/null\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "id": "6383338662689565081", + "triggers": null + }, + "sensitive_attributes": [], + "dependencies": [ + "data.aws_availability_zones.available", + "module.eks.aws_cloudwatch_log_group.this", + "module.eks.aws_eks_cluster.this", + "module.eks.aws_iam_policy.cni_ipv6_policy", + "module.eks.aws_iam_role.eks_auto", + "module.eks.aws_iam_role.this", + "module.eks.aws_iam_role_policy_attachment.this", + "module.eks.aws_security_group.cluster", + "module.eks.aws_security_group.node", + "module.eks.aws_security_group_rule.cluster", + "module.eks.aws_security_group_rule.node", + "module.eks.data.aws_caller_identity.current", + "module.eks.data.aws_iam_policy_document.assume_role_policy", + "module.eks.data.aws_iam_policy_document.cni_ipv6_policy", + "module.eks.data.aws_iam_policy_document.node_assume_role_policy", + "module.eks.data.aws_iam_session_context.current", + "module.eks.data.aws_partition.current", + "module.eks.module.kms.aws_kms_external_key.this", + "module.eks.module.kms.aws_kms_key.this", + "module.eks.module.kms.aws_kms_replica_external_key.this", + "module.eks.module.kms.aws_kms_replica_key.this", + "module.eks.module.kms.data.aws_caller_identity.current", + "module.eks.module.kms.data.aws_iam_policy_document.this", + "module.eks.module.kms.data.aws_partition.current", + "module.eks.time_sleep.this", + "module.vpc.aws_subnet.private", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ] + } + ] + }, + { + "module": "module.eks.module.kms", + "mode": "data", + "type": "aws_caller_identity", + "name": "current", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "account_id": "027423573553", + "arn": "arn:aws:sts::027423573553:assumed-role/Admin/kylhouns-Isengard", + "id": "027423573553", + "user_id": "AROAQMYUSQYYXMMZMGMPD:kylhouns-Isengard" + }, + "sensitive_attributes": [] + } + ] + }, + { + "module": "module.eks.module.kms", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "id": "1923360655", + "json": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"Default\",\n \"Effect\": \"Allow\",\n \"Action\": \"kms:*\",\n \"Resource\": \"*\",\n \"Principal\": {\n \"AWS\": \"arn:aws:iam::027423573553:root\"\n }\n },\n {\n \"Sid\": \"KeyAdministration\",\n \"Effect\": \"Allow\",\n \"Action\": [\n \"kms:Update*\",\n \"kms:UntagResource\",\n \"kms:TagResource\",\n \"kms:ScheduleKeyDeletion\",\n \"kms:Revoke*\",\n \"kms:ReplicateKey\",\n \"kms:Put*\",\n \"kms:List*\",\n \"kms:ImportKeyMaterial\",\n \"kms:Get*\",\n \"kms:Enable*\",\n \"kms:Disable*\",\n \"kms:Describe*\",\n \"kms:Delete*\",\n \"kms:Create*\",\n \"kms:CancelKeyDeletion\"\n ],\n \"Resource\": \"*\",\n \"Principal\": {\n \"AWS\": \"arn:aws:iam::027423573553:role/Admin\"\n }\n },\n {\n \"Sid\": \"KeyUsage\",\n \"Effect\": \"Allow\",\n \"Action\": [\n \"kms:ReEncrypt*\",\n \"kms:GenerateDataKey*\",\n \"kms:Encrypt\",\n \"kms:DescribeKey\",\n \"kms:Decrypt\"\n ],\n \"Resource\": \"*\",\n \"Principal\": {\n \"AWS\": \"arn:aws:iam::027423573553:role/observability-stack-cluster-20260318201827553600000003\"\n }\n }\n ]\n}", + "minified_json": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"Default\",\"Effect\":\"Allow\",\"Action\":\"kms:*\",\"Resource\":\"*\",\"Principal\":{\"AWS\":\"arn:aws:iam::027423573553:root\"}},{\"Sid\":\"KeyAdministration\",\"Effect\":\"Allow\",\"Action\":[\"kms:Update*\",\"kms:UntagResource\",\"kms:TagResource\",\"kms:ScheduleKeyDeletion\",\"kms:Revoke*\",\"kms:ReplicateKey\",\"kms:Put*\",\"kms:List*\",\"kms:ImportKeyMaterial\",\"kms:Get*\",\"kms:Enable*\",\"kms:Disable*\",\"kms:Describe*\",\"kms:Delete*\",\"kms:Create*\",\"kms:CancelKeyDeletion\"],\"Resource\":\"*\",\"Principal\":{\"AWS\":\"arn:aws:iam::027423573553:role/Admin\"}},{\"Sid\":\"KeyUsage\",\"Effect\":\"Allow\",\"Action\":[\"kms:ReEncrypt*\",\"kms:GenerateDataKey*\",\"kms:Encrypt\",\"kms:DescribeKey\",\"kms:Decrypt\"],\"Resource\":\"*\",\"Principal\":{\"AWS\":\"arn:aws:iam::027423573553:role/observability-stack-cluster-20260318201827553600000003\"}}]}", + "override_json": null, + "override_policy_documents": null, + "policy_id": null, + "source_json": null, + "source_policy_documents": null, + "statement": [ + { + "actions": [ + "kms:*" + ], + "condition": [], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [ + { + "identifiers": [ + "arn:aws:iam::027423573553:root" + ], + "type": "AWS" + } + ], + "resources": [ + "*" + ], + "sid": "Default" + }, + { + "actions": [ + "kms:CancelKeyDeletion", + "kms:Create*", + "kms:Delete*", + "kms:Describe*", + "kms:Disable*", + "kms:Enable*", + "kms:Get*", + "kms:ImportKeyMaterial", + "kms:List*", + "kms:Put*", + "kms:ReplicateKey", + "kms:Revoke*", + "kms:ScheduleKeyDeletion", + "kms:TagResource", + "kms:UntagResource", + "kms:Update*" + ], + "condition": [], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [ + { + "identifiers": [ + "arn:aws:iam::027423573553:role/Admin" + ], + "type": "AWS" + } + ], + "resources": [ + "*" + ], + "sid": "KeyAdministration" + }, + { + "actions": [ + "kms:Decrypt", + "kms:DescribeKey", + "kms:Encrypt", + "kms:GenerateDataKey*", + "kms:ReEncrypt*" + ], + "condition": [], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [ + { + "identifiers": [ + "arn:aws:iam::027423573553:role/observability-stack-cluster-20260318201827553600000003" + ], + "type": "AWS" + } + ], + "resources": [ + "*" + ], + "sid": "KeyUsage" + } + ], + "version": "2012-10-17" + }, + "sensitive_attributes": [] + } + ] + }, + { + "module": "module.eks.module.kms", + "mode": "data", + "type": "aws_partition", + "name": "current", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "dns_suffix": "amazonaws.com", + "id": "aws", + "partition": "aws", + "reverse_dns_prefix": "com.amazonaws" + }, + "sensitive_attributes": [] + } + ] + }, + { + "module": "module.eks.module.kms", + "mode": "managed", + "type": "aws_kms_alias", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": "cluster", + "schema_version": 0, + "attributes": { + "arn": "arn:aws:kms:us-west-2:027423573553:alias/eks/observability-stack", + "id": "alias/eks/observability-stack", + "name": "alias/eks/observability-stack", + "name_prefix": "", + "target_key_arn": "arn:aws:kms:us-west-2:027423573553:key/12030f91-64b4-40e3-b7ad-77340e0391c7", + "target_key_id": "12030f91-64b4-40e3-b7ad-77340e0391c7" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "module.eks.aws_iam_role.this", + "module.eks.data.aws_caller_identity.current", + "module.eks.data.aws_iam_policy_document.assume_role_policy", + "module.eks.data.aws_iam_session_context.current", + "module.eks.module.kms.aws_kms_external_key.this", + "module.eks.module.kms.aws_kms_key.this", + "module.eks.module.kms.aws_kms_replica_external_key.this", + "module.eks.module.kms.aws_kms_replica_key.this", + "module.eks.module.kms.data.aws_caller_identity.current", + "module.eks.module.kms.data.aws_iam_policy_document.this", + "module.eks.module.kms.data.aws_partition.current" + ] + } + ] + }, + { + "module": "module.eks.module.kms", + "mode": "managed", + "type": "aws_kms_external_key", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.eks.module.kms", + "mode": "managed", + "type": "aws_kms_grant", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.eks.module.kms", + "mode": "managed", + "type": "aws_kms_key", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "arn": "arn:aws:kms:us-west-2:027423573553:key/12030f91-64b4-40e3-b7ad-77340e0391c7", + "bypass_policy_lockout_safety_check": false, + "custom_key_store_id": "", + "customer_master_key_spec": "SYMMETRIC_DEFAULT", + "deletion_window_in_days": null, + "description": "observability-stack cluster encryption key", + "enable_key_rotation": true, + "id": "12030f91-64b4-40e3-b7ad-77340e0391c7", + "is_enabled": true, + "key_id": "12030f91-64b4-40e3-b7ad-77340e0391c7", + "key_usage": "ENCRYPT_DECRYPT", + "multi_region": false, + "policy": "{\"Statement\":[{\"Action\":\"kms:*\",\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::027423573553:root\"},\"Resource\":\"*\",\"Sid\":\"Default\"},{\"Action\":[\"kms:Update*\",\"kms:UntagResource\",\"kms:TagResource\",\"kms:ScheduleKeyDeletion\",\"kms:Revoke*\",\"kms:ReplicateKey\",\"kms:Put*\",\"kms:List*\",\"kms:ImportKeyMaterial\",\"kms:Get*\",\"kms:Enable*\",\"kms:Disable*\",\"kms:Describe*\",\"kms:Delete*\",\"kms:Create*\",\"kms:CancelKeyDeletion\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::027423573553:role/Admin\"},\"Resource\":\"*\",\"Sid\":\"KeyAdministration\"},{\"Action\":[\"kms:ReEncrypt*\",\"kms:GenerateDataKey*\",\"kms:Encrypt\",\"kms:DescribeKey\",\"kms:Decrypt\"],\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::027423573553:role/observability-stack-cluster-20260318201827553600000003\"},\"Resource\":\"*\",\"Sid\":\"KeyUsage\"}],\"Version\":\"2012-10-17\"}", + "rotation_period_in_days": 365, + "tags": { + "terraform-aws-modules": "eks" + }, + "tags_all": { + "ManagedBy": "terraform", + "Project": "observability-stack", + "terraform-aws-modules": "eks" + }, + "timeouts": null, + "xks_key_id": "" + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjoxMjAwMDAwMDAwMDB9fQ==", + "dependencies": [ + "module.eks.aws_iam_role.this", + "module.eks.data.aws_caller_identity.current", + "module.eks.data.aws_iam_policy_document.assume_role_policy", + "module.eks.data.aws_iam_session_context.current", + "module.eks.module.kms.data.aws_caller_identity.current", + "module.eks.module.kms.data.aws_iam_policy_document.this", + "module.eks.module.kms.data.aws_partition.current" + ], + "create_before_destroy": true + } + ] + }, + { + "module": "module.eks.module.kms", + "mode": "managed", + "type": "aws_kms_replica_external_key", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.eks.module.kms", + "mode": "managed", + "type": "aws_kms_replica_key", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "data", + "type": "aws_caller_identity", + "name": "current", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "account_id": "027423573553", + "arn": "arn:aws:sts::027423573553:assumed-role/Admin/kylhouns-Isengard", + "id": "027423573553", + "user_id": "AROAQMYUSQYYXMMZMGMPD:kylhouns-Isengard" + }, + "sensitive_attributes": [] + } + ] + }, + { + "module": "module.external_dns_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "amazon_managed_service_prometheus", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "appmesh_controller", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "appmesh_envoy_proxy", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "aws_gateway_controller", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "cert_manager", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "cluster_autoscaler", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "ebs_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "efs_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "external_dns", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "id": "3951040301", + "json": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Action\": \"route53:ChangeResourceRecordSets\",\n \"Resource\": \"arn:aws:route53:::hostedzone/Z07457962NTDHS0A6G9LH\"\n },\n {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"route53:ListTagsForResources\",\n \"route53:ListResourceRecordSets\",\n \"route53:ListHostedZones\"\n ],\n \"Resource\": \"*\"\n }\n ]\n}", + "minified_json": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"route53:ChangeResourceRecordSets\",\"Resource\":\"arn:aws:route53:::hostedzone/Z07457962NTDHS0A6G9LH\"},{\"Effect\":\"Allow\",\"Action\":[\"route53:ListTagsForResources\",\"route53:ListResourceRecordSets\",\"route53:ListHostedZones\"],\"Resource\":\"*\"}]}", + "override_json": null, + "override_policy_documents": null, + "policy_id": null, + "source_json": null, + "source_policy_documents": null, + "statement": [ + { + "actions": [ + "route53:ChangeResourceRecordSets" + ], + "condition": [], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "arn:aws:route53:::hostedzone/Z07457962NTDHS0A6G9LH" + ], + "sid": "" + }, + { + "actions": [ + "route53:ListHostedZones", + "route53:ListResourceRecordSets", + "route53:ListTagsForResources" + ], + "condition": [], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "*" + ], + "sid": "" + } + ], + "version": "2012-10-17" + }, + "sensitive_attributes": [] + } + ] + }, + { + "module": "module.external_dns_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "external_secrets", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "fsx_lustre_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "fsx_openzfs_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "karpenter_controller", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "load_balancer_controller", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "load_balancer_controller_targetgroup_only", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "mountpoint_s3_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "node_termination_handler", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "id": "3909713710", + "json": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Action\": \"sts:AssumeRoleWithWebIdentity\",\n \"Principal\": {\n \"Federated\": \"arn:aws:iam::027423573553:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D\"\n },\n \"Condition\": {\n \"StringEquals\": {\n \"oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D:aud\": \"sts.amazonaws.com\",\n \"oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D:sub\": \"system:serviceaccount:kube-system:external-dns\"\n }\n }\n }\n ]\n}", + "minified_json": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"sts:AssumeRoleWithWebIdentity\",\"Principal\":{\"Federated\":\"arn:aws:iam::027423573553:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D\"},\"Condition\":{\"StringEquals\":{\"oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D:aud\":\"sts.amazonaws.com\",\"oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D:sub\":\"system:serviceaccount:kube-system:external-dns\"}}}]}", + "override_json": null, + "override_policy_documents": null, + "policy_id": null, + "source_json": null, + "source_policy_documents": null, + "statement": [ + { + "actions": [ + "sts:AssumeRoleWithWebIdentity" + ], + "condition": [ + { + "test": "StringEquals", + "values": [ + "sts.amazonaws.com" + ], + "variable": "oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D:aud" + }, + { + "test": "StringEquals", + "values": [ + "system:serviceaccount:kube-system:external-dns" + ], + "variable": "oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D:sub" + } + ], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [ + { + "identifiers": [ + "arn:aws:iam::027423573553:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D" + ], + "type": "Federated" + } + ], + "resources": [], + "sid": "" + } + ], + "version": "2012-10-17" + }, + "sensitive_attributes": [] + } + ] + }, + { + "module": "module.external_dns_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "velero", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "vpc_cni", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "data", + "type": "aws_partition", + "name": "current", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "dns_suffix": "amazonaws.com", + "id": "aws", + "partition": "aws", + "reverse_dns_prefix": "com.amazonaws" + }, + "sensitive_attributes": [] + } + ] + }, + { + "module": "module.external_dns_irsa", + "mode": "data", + "type": "aws_region", + "name": "current", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "description": "US West (Oregon)", + "endpoint": "ec2.us-west-2.amazonaws.com", + "id": "us-west-2", + "name": "us-west-2" + }, + "sensitive_attributes": [] + } + ] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "amazon_managed_service_prometheus", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "appmesh_controller", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "appmesh_envoy_proxy", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "aws_gateway_controller", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "cert_manager", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "cluster_autoscaler", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "ebs_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "efs_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "external_dns", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "arn": "arn:aws:iam::027423573553:policy/AmazonEKS_External_DNS_Policy-20260318201827552700000001", + "attachment_count": 1, + "description": "External DNS policy to allow management of Route53 hosted zone records", + "id": "arn:aws:iam::027423573553:policy/AmazonEKS_External_DNS_Policy-20260318201827552700000001", + "name": "AmazonEKS_External_DNS_Policy-20260318201827552700000001", + "name_prefix": "AmazonEKS_External_DNS_Policy-", + "path": "/", + "policy": "{\"Statement\":[{\"Action\":\"route53:ChangeResourceRecordSets\",\"Effect\":\"Allow\",\"Resource\":\"arn:aws:route53:::hostedzone/Z07457962NTDHS0A6G9LH\"},{\"Action\":[\"route53:ListTagsForResources\",\"route53:ListResourceRecordSets\",\"route53:ListHostedZones\"],\"Effect\":\"Allow\",\"Resource\":\"*\"}],\"Version\":\"2012-10-17\"}", + "policy_id": "ANPAQMYUSQYYZYFDNRBWO", + "tags": {}, + "tags_all": { + "ManagedBy": "terraform", + "Project": "observability-stack" + } + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "module.external_dns_irsa.data.aws_iam_policy_document.external_dns" + ] + } + ] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "external_secrets", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "fsx_lustre_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "fsx_openzfs_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "karpenter_controller", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "load_balancer_controller", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "load_balancer_controller_targetgroup_only", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "mountpoint_s3_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "node_termination_handler", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "velero", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "vpc_cni", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_role", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "arn": "arn:aws:iam::027423573553:role/observability-stack-external-dns", + "assume_role_policy": "{\"Statement\":[{\"Action\":\"sts:AssumeRoleWithWebIdentity\",\"Condition\":{\"StringEquals\":{\"oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D:aud\":\"sts.amazonaws.com\",\"oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D:sub\":\"system:serviceaccount:kube-system:external-dns\"}},\"Effect\":\"Allow\",\"Principal\":{\"Federated\":\"arn:aws:iam::027423573553:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D\"}}],\"Version\":\"2012-10-17\"}", + "create_date": "2026-03-18T20:28:14Z", + "description": "", + "force_detach_policies": true, + "id": "observability-stack-external-dns", + "inline_policy": [], + "managed_policy_arns": [ + "arn:aws:iam::027423573553:policy/AmazonEKS_External_DNS_Policy-20260318201827552700000001" + ], + "max_session_duration": 3600, + "name": "observability-stack-external-dns", + "name_prefix": "", + "path": "/", + "permissions_boundary": "", + "tags": {}, + "tags_all": { + "ManagedBy": "terraform", + "Project": "observability-stack" + }, + "unique_id": "AROAQMYUSQYY43FP3UD6E" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "data.aws_availability_zones.available", + "module.eks.aws_cloudwatch_log_group.this", + "module.eks.aws_eks_cluster.this", + "module.eks.aws_iam_openid_connect_provider.oidc_provider", + "module.eks.aws_iam_policy.cni_ipv6_policy", + "module.eks.aws_iam_role.eks_auto", + "module.eks.aws_iam_role.this", + "module.eks.aws_iam_role_policy_attachment.this", + "module.eks.aws_security_group.cluster", + "module.eks.aws_security_group.node", + "module.eks.aws_security_group_rule.cluster", + "module.eks.aws_security_group_rule.node", + "module.eks.data.aws_caller_identity.current", + "module.eks.data.aws_iam_policy_document.assume_role_policy", + "module.eks.data.aws_iam_policy_document.cni_ipv6_policy", + "module.eks.data.aws_iam_policy_document.node_assume_role_policy", + "module.eks.data.aws_iam_session_context.current", + "module.eks.data.aws_partition.current", + "module.eks.data.tls_certificate.this", + "module.eks.module.kms.aws_kms_external_key.this", + "module.eks.module.kms.aws_kms_key.this", + "module.eks.module.kms.aws_kms_replica_external_key.this", + "module.eks.module.kms.aws_kms_replica_key.this", + "module.eks.module.kms.data.aws_caller_identity.current", + "module.eks.module.kms.data.aws_iam_policy_document.this", + "module.eks.module.kms.data.aws_partition.current", + "module.external_dns_irsa.data.aws_caller_identity.current", + "module.external_dns_irsa.data.aws_iam_policy_document.this", + "module.external_dns_irsa.data.aws_partition.current", + "module.vpc.aws_subnet.private", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ] + } + ] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "amazon_cloudwatch_observability", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "amazon_managed_service_prometheus", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "appmesh_controller", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "appmesh_envoy_proxy", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "aws_gateway_controller", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "cert_manager", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "cluster_autoscaler", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "ebs_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "efs_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "external_dns", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "id": "observability-stack-external-dns-20260318202815339800000014", + "policy_arn": "arn:aws:iam::027423573553:policy/AmazonEKS_External_DNS_Policy-20260318201827552700000001", + "role": "observability-stack-external-dns" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "data.aws_availability_zones.available", + "module.eks.aws_cloudwatch_log_group.this", + "module.eks.aws_eks_cluster.this", + "module.eks.aws_iam_openid_connect_provider.oidc_provider", + "module.eks.aws_iam_policy.cni_ipv6_policy", + "module.eks.aws_iam_role.eks_auto", + "module.eks.aws_iam_role.this", + "module.eks.aws_iam_role_policy_attachment.this", + "module.eks.aws_security_group.cluster", + "module.eks.aws_security_group.node", + "module.eks.aws_security_group_rule.cluster", + "module.eks.aws_security_group_rule.node", + "module.eks.data.aws_caller_identity.current", + "module.eks.data.aws_iam_policy_document.assume_role_policy", + "module.eks.data.aws_iam_policy_document.cni_ipv6_policy", + "module.eks.data.aws_iam_policy_document.node_assume_role_policy", + "module.eks.data.aws_iam_session_context.current", + "module.eks.data.aws_partition.current", + "module.eks.data.tls_certificate.this", + "module.eks.module.kms.aws_kms_external_key.this", + "module.eks.module.kms.aws_kms_key.this", + "module.eks.module.kms.aws_kms_replica_external_key.this", + "module.eks.module.kms.aws_kms_replica_key.this", + "module.eks.module.kms.data.aws_caller_identity.current", + "module.eks.module.kms.data.aws_iam_policy_document.this", + "module.eks.module.kms.data.aws_partition.current", + "module.external_dns_irsa.aws_iam_policy.external_dns", + "module.external_dns_irsa.aws_iam_role.this", + "module.external_dns_irsa.data.aws_caller_identity.current", + "module.external_dns_irsa.data.aws_iam_policy_document.external_dns", + "module.external_dns_irsa.data.aws_iam_policy_document.this", + "module.external_dns_irsa.data.aws_partition.current", + "module.vpc.aws_subnet.private", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ] + } + ] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "external_secrets", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "fsx_lustre_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "fsx_openzfs_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "karpenter_controller", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "load_balancer_controller", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "load_balancer_controller_targetgroup_only", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "mountpoint_s3_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "node_termination_handler", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "velero", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.external_dns_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "vpc_cni", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "data", + "type": "aws_caller_identity", + "name": "current", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "account_id": "027423573553", + "arn": "arn:aws:sts::027423573553:assumed-role/Admin/kylhouns-Isengard", + "id": "027423573553", + "user_id": "AROAQMYUSQYYXMMZMGMPD:kylhouns-Isengard" + }, + "sensitive_attributes": [] + } + ] + }, + { + "module": "module.lb_controller_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "amazon_managed_service_prometheus", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "appmesh_controller", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "appmesh_envoy_proxy", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "aws_gateway_controller", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "cert_manager", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "cluster_autoscaler", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "ebs_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "efs_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "external_dns", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "external_secrets", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "fsx_lustre_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "fsx_openzfs_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "karpenter_controller", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "load_balancer_controller", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "id": "1541424006", + "json": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Action\": \"iam:CreateServiceLinkedRole\",\n \"Resource\": \"*\",\n \"Condition\": {\n \"StringEquals\": {\n \"iam:AWSServiceName\": \"elasticloadbalancing.amazonaws.com\"\n }\n }\n },\n {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"elasticloadbalancing:DescribeTrustStores\",\n \"elasticloadbalancing:DescribeTargetHealth\",\n \"elasticloadbalancing:DescribeTargetGroups\",\n \"elasticloadbalancing:DescribeTargetGroupAttributes\",\n \"elasticloadbalancing:DescribeTags\",\n \"elasticloadbalancing:DescribeSSLPolicies\",\n \"elasticloadbalancing:DescribeRules\",\n \"elasticloadbalancing:DescribeLoadBalancers\",\n \"elasticloadbalancing:DescribeLoadBalancerAttributes\",\n \"elasticloadbalancing:DescribeListeners\",\n \"elasticloadbalancing:DescribeListenerCertificates\",\n \"elasticloadbalancing:DescribeListenerAttributes\",\n \"elasticloadbalancing:DescribeCapacityReservation\",\n \"ec2:GetSecurityGroupsForVpc\",\n \"ec2:GetCoipPoolUsage\",\n \"ec2:DescribeVpcs\",\n \"ec2:DescribeVpcPeeringConnections\",\n \"ec2:DescribeTags\",\n \"ec2:DescribeSubnets\",\n \"ec2:DescribeSecurityGroups\",\n \"ec2:DescribeRouteTables\",\n \"ec2:DescribeNetworkInterfaces\",\n \"ec2:DescribeIpamPools\",\n \"ec2:DescribeInternetGateways\",\n \"ec2:DescribeInstances\",\n \"ec2:DescribeCoipPools\",\n \"ec2:DescribeAvailabilityZones\",\n \"ec2:DescribeAddresses\",\n \"ec2:DescribeAccountAttributes\"\n ],\n \"Resource\": \"*\"\n },\n {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"wafv2:GetWebACLForResource\",\n \"wafv2:GetWebACL\",\n \"wafv2:DisassociateWebACL\",\n \"wafv2:AssociateWebACL\",\n \"waf-regional:GetWebACLForResource\",\n \"waf-regional:GetWebACL\",\n \"waf-regional:DisassociateWebACL\",\n \"waf-regional:AssociateWebACL\",\n \"shield:GetSubscriptionState\",\n \"shield:DescribeProtection\",\n \"shield:DeleteProtection\",\n \"shield:CreateProtection\",\n \"iam:ListServerCertificates\",\n \"iam:GetServerCertificate\",\n \"cognito-idp:DescribeUserPoolClient\",\n \"acm:ListCertificates\",\n \"acm:DescribeCertificate\"\n ],\n \"Resource\": \"*\"\n },\n {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"ec2:RevokeSecurityGroupIngress\",\n \"ec2:AuthorizeSecurityGroupIngress\"\n ],\n \"Resource\": \"*\"\n },\n {\n \"Effect\": \"Allow\",\n \"Action\": \"ec2:CreateSecurityGroup\",\n \"Resource\": \"*\"\n },\n {\n \"Effect\": \"Allow\",\n \"Action\": \"ec2:CreateTags\",\n \"Resource\": \"arn:aws:ec2:*:*:security-group/*\",\n \"Condition\": {\n \"Null\": {\n \"aws:RequestTag/elbv2.k8s.aws/cluster\": \"false\"\n },\n \"StringEquals\": {\n \"ec2:CreateAction\": \"CreateSecurityGroup\"\n }\n }\n },\n {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"ec2:DeleteTags\",\n \"ec2:CreateTags\"\n ],\n \"Resource\": \"arn:aws:ec2:*:*:security-group/*\",\n \"Condition\": {\n \"Null\": {\n \"aws:RequestTag/elbv2.k8s.aws/cluster\": \"true\",\n \"aws:ResourceTag/elbv2.k8s.aws/cluster\": \"false\"\n }\n }\n },\n {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"ec2:RevokeSecurityGroupIngress\",\n \"ec2:DeleteSecurityGroup\",\n \"ec2:AuthorizeSecurityGroupIngress\"\n ],\n \"Resource\": \"*\",\n \"Condition\": {\n \"Null\": {\n \"aws:ResourceTag/elbv2.k8s.aws/cluster\": \"false\"\n }\n }\n },\n {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"elasticloadbalancing:CreateTargetGroup\",\n \"elasticloadbalancing:CreateLoadBalancer\"\n ],\n \"Resource\": \"*\",\n \"Condition\": {\n \"Null\": {\n \"aws:RequestTag/elbv2.k8s.aws/cluster\": \"false\"\n }\n }\n },\n {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"elasticloadbalancing:DeleteRule\",\n \"elasticloadbalancing:DeleteListener\",\n \"elasticloadbalancing:CreateRule\",\n \"elasticloadbalancing:CreateListener\"\n ],\n \"Resource\": \"*\"\n },\n {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"elasticloadbalancing:RemoveTags\",\n \"elasticloadbalancing:AddTags\"\n ],\n \"Resource\": [\n \"arn:aws:elasticloadbalancing:*:*:targetgroup/*/*\",\n \"arn:aws:elasticloadbalancing:*:*:loadbalancer/net/*/*\",\n \"arn:aws:elasticloadbalancing:*:*:loadbalancer/app/*/*\"\n ],\n \"Condition\": {\n \"Null\": {\n \"aws:RequestTag/elbv2.k8s.aws/cluster\": \"true\",\n \"aws:ResourceTag/elbv2.k8s.aws/cluster\": \"false\"\n }\n }\n },\n {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"elasticloadbalancing:RemoveTags\",\n \"elasticloadbalancing:AddTags\"\n ],\n \"Resource\": [\n \"arn:aws:elasticloadbalancing:*:*:listener/net/*/*/*\",\n \"arn:aws:elasticloadbalancing:*:*:listener/app/*/*/*\",\n \"arn:aws:elasticloadbalancing:*:*:listener-rule/net/*/*/*\",\n \"arn:aws:elasticloadbalancing:*:*:listener-rule/app/*/*/*\"\n ]\n },\n {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"elasticloadbalancing:SetSubnets\",\n \"elasticloadbalancing:SetSecurityGroups\",\n \"elasticloadbalancing:SetIpAddressType\",\n \"elasticloadbalancing:ModifyTargetGroupAttributes\",\n \"elasticloadbalancing:ModifyTargetGroup\",\n \"elasticloadbalancing:ModifyLoadBalancerAttributes\",\n \"elasticloadbalancing:ModifyListenerAttributes\",\n \"elasticloadbalancing:ModifyIpPools\",\n \"elasticloadbalancing:ModifyCapacityReservation\",\n \"elasticloadbalancing:DeleteTargetGroup\",\n \"elasticloadbalancing:DeleteLoadBalancer\"\n ],\n \"Resource\": \"*\",\n \"Condition\": {\n \"Null\": {\n \"aws:ResourceTag/elbv2.k8s.aws/cluster\": \"false\"\n }\n }\n },\n {\n \"Effect\": \"Allow\",\n \"Action\": \"elasticloadbalancing:AddTags\",\n \"Resource\": [\n \"arn:aws:elasticloadbalancing:*:*:targetgroup/*/*\",\n \"arn:aws:elasticloadbalancing:*:*:loadbalancer/net/*/*\",\n \"arn:aws:elasticloadbalancing:*:*:loadbalancer/app/*/*\"\n ],\n \"Condition\": {\n \"Null\": {\n \"aws:RequestTag/elbv2.k8s.aws/cluster\": \"false\"\n },\n \"StringEquals\": {\n \"elasticloadbalancing:CreateAction\": [\n \"CreateTargetGroup\",\n \"CreateLoadBalancer\"\n ]\n }\n }\n },\n {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"elasticloadbalancing:RegisterTargets\",\n \"elasticloadbalancing:DeregisterTargets\"\n ],\n \"Resource\": \"arn:aws:elasticloadbalancing:*:*:targetgroup/*/*\"\n },\n {\n \"Effect\": \"Allow\",\n \"Action\": [\n \"elasticloadbalancing:SetWebAcl\",\n \"elasticloadbalancing:SetRulePriorities\",\n \"elasticloadbalancing:RemoveListenerCertificates\",\n \"elasticloadbalancing:ModifyRule\",\n \"elasticloadbalancing:ModifyListener\",\n \"elasticloadbalancing:AddListenerCertificates\"\n ],\n \"Resource\": \"*\"\n }\n ]\n}", + "minified_json": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"iam:CreateServiceLinkedRole\",\"Resource\":\"*\",\"Condition\":{\"StringEquals\":{\"iam:AWSServiceName\":\"elasticloadbalancing.amazonaws.com\"}}},{\"Effect\":\"Allow\",\"Action\":[\"elasticloadbalancing:DescribeTrustStores\",\"elasticloadbalancing:DescribeTargetHealth\",\"elasticloadbalancing:DescribeTargetGroups\",\"elasticloadbalancing:DescribeTargetGroupAttributes\",\"elasticloadbalancing:DescribeTags\",\"elasticloadbalancing:DescribeSSLPolicies\",\"elasticloadbalancing:DescribeRules\",\"elasticloadbalancing:DescribeLoadBalancers\",\"elasticloadbalancing:DescribeLoadBalancerAttributes\",\"elasticloadbalancing:DescribeListeners\",\"elasticloadbalancing:DescribeListenerCertificates\",\"elasticloadbalancing:DescribeListenerAttributes\",\"elasticloadbalancing:DescribeCapacityReservation\",\"ec2:GetSecurityGroupsForVpc\",\"ec2:GetCoipPoolUsage\",\"ec2:DescribeVpcs\",\"ec2:DescribeVpcPeeringConnections\",\"ec2:DescribeTags\",\"ec2:DescribeSubnets\",\"ec2:DescribeSecurityGroups\",\"ec2:DescribeRouteTables\",\"ec2:DescribeNetworkInterfaces\",\"ec2:DescribeIpamPools\",\"ec2:DescribeInternetGateways\",\"ec2:DescribeInstances\",\"ec2:DescribeCoipPools\",\"ec2:DescribeAvailabilityZones\",\"ec2:DescribeAddresses\",\"ec2:DescribeAccountAttributes\"],\"Resource\":\"*\"},{\"Effect\":\"Allow\",\"Action\":[\"wafv2:GetWebACLForResource\",\"wafv2:GetWebACL\",\"wafv2:DisassociateWebACL\",\"wafv2:AssociateWebACL\",\"waf-regional:GetWebACLForResource\",\"waf-regional:GetWebACL\",\"waf-regional:DisassociateWebACL\",\"waf-regional:AssociateWebACL\",\"shield:GetSubscriptionState\",\"shield:DescribeProtection\",\"shield:DeleteProtection\",\"shield:CreateProtection\",\"iam:ListServerCertificates\",\"iam:GetServerCertificate\",\"cognito-idp:DescribeUserPoolClient\",\"acm:ListCertificates\",\"acm:DescribeCertificate\"],\"Resource\":\"*\"},{\"Effect\":\"Allow\",\"Action\":[\"ec2:RevokeSecurityGroupIngress\",\"ec2:AuthorizeSecurityGroupIngress\"],\"Resource\":\"*\"},{\"Effect\":\"Allow\",\"Action\":\"ec2:CreateSecurityGroup\",\"Resource\":\"*\"},{\"Effect\":\"Allow\",\"Action\":\"ec2:CreateTags\",\"Resource\":\"arn:aws:ec2:*:*:security-group/*\",\"Condition\":{\"Null\":{\"aws:RequestTag/elbv2.k8s.aws/cluster\":\"false\"},\"StringEquals\":{\"ec2:CreateAction\":\"CreateSecurityGroup\"}}},{\"Effect\":\"Allow\",\"Action\":[\"ec2:DeleteTags\",\"ec2:CreateTags\"],\"Resource\":\"arn:aws:ec2:*:*:security-group/*\",\"Condition\":{\"Null\":{\"aws:RequestTag/elbv2.k8s.aws/cluster\":\"true\",\"aws:ResourceTag/elbv2.k8s.aws/cluster\":\"false\"}}},{\"Effect\":\"Allow\",\"Action\":[\"ec2:RevokeSecurityGroupIngress\",\"ec2:DeleteSecurityGroup\",\"ec2:AuthorizeSecurityGroupIngress\"],\"Resource\":\"*\",\"Condition\":{\"Null\":{\"aws:ResourceTag/elbv2.k8s.aws/cluster\":\"false\"}}},{\"Effect\":\"Allow\",\"Action\":[\"elasticloadbalancing:CreateTargetGroup\",\"elasticloadbalancing:CreateLoadBalancer\"],\"Resource\":\"*\",\"Condition\":{\"Null\":{\"aws:RequestTag/elbv2.k8s.aws/cluster\":\"false\"}}},{\"Effect\":\"Allow\",\"Action\":[\"elasticloadbalancing:DeleteRule\",\"elasticloadbalancing:DeleteListener\",\"elasticloadbalancing:CreateRule\",\"elasticloadbalancing:CreateListener\"],\"Resource\":\"*\"},{\"Effect\":\"Allow\",\"Action\":[\"elasticloadbalancing:RemoveTags\",\"elasticloadbalancing:AddTags\"],\"Resource\":[\"arn:aws:elasticloadbalancing:*:*:targetgroup/*/*\",\"arn:aws:elasticloadbalancing:*:*:loadbalancer/net/*/*\",\"arn:aws:elasticloadbalancing:*:*:loadbalancer/app/*/*\"],\"Condition\":{\"Null\":{\"aws:RequestTag/elbv2.k8s.aws/cluster\":\"true\",\"aws:ResourceTag/elbv2.k8s.aws/cluster\":\"false\"}}},{\"Effect\":\"Allow\",\"Action\":[\"elasticloadbalancing:RemoveTags\",\"elasticloadbalancing:AddTags\"],\"Resource\":[\"arn:aws:elasticloadbalancing:*:*:listener/net/*/*/*\",\"arn:aws:elasticloadbalancing:*:*:listener/app/*/*/*\",\"arn:aws:elasticloadbalancing:*:*:listener-rule/net/*/*/*\",\"arn:aws:elasticloadbalancing:*:*:listener-rule/app/*/*/*\"]},{\"Effect\":\"Allow\",\"Action\":[\"elasticloadbalancing:SetSubnets\",\"elasticloadbalancing:SetSecurityGroups\",\"elasticloadbalancing:SetIpAddressType\",\"elasticloadbalancing:ModifyTargetGroupAttributes\",\"elasticloadbalancing:ModifyTargetGroup\",\"elasticloadbalancing:ModifyLoadBalancerAttributes\",\"elasticloadbalancing:ModifyListenerAttributes\",\"elasticloadbalancing:ModifyIpPools\",\"elasticloadbalancing:ModifyCapacityReservation\",\"elasticloadbalancing:DeleteTargetGroup\",\"elasticloadbalancing:DeleteLoadBalancer\"],\"Resource\":\"*\",\"Condition\":{\"Null\":{\"aws:ResourceTag/elbv2.k8s.aws/cluster\":\"false\"}}},{\"Effect\":\"Allow\",\"Action\":\"elasticloadbalancing:AddTags\",\"Resource\":[\"arn:aws:elasticloadbalancing:*:*:targetgroup/*/*\",\"arn:aws:elasticloadbalancing:*:*:loadbalancer/net/*/*\",\"arn:aws:elasticloadbalancing:*:*:loadbalancer/app/*/*\"],\"Condition\":{\"Null\":{\"aws:RequestTag/elbv2.k8s.aws/cluster\":\"false\"},\"StringEquals\":{\"elasticloadbalancing:CreateAction\":[\"CreateTargetGroup\",\"CreateLoadBalancer\"]}}},{\"Effect\":\"Allow\",\"Action\":[\"elasticloadbalancing:RegisterTargets\",\"elasticloadbalancing:DeregisterTargets\"],\"Resource\":\"arn:aws:elasticloadbalancing:*:*:targetgroup/*/*\"},{\"Effect\":\"Allow\",\"Action\":[\"elasticloadbalancing:SetWebAcl\",\"elasticloadbalancing:SetRulePriorities\",\"elasticloadbalancing:RemoveListenerCertificates\",\"elasticloadbalancing:ModifyRule\",\"elasticloadbalancing:ModifyListener\",\"elasticloadbalancing:AddListenerCertificates\"],\"Resource\":\"*\"}]}", + "override_json": null, + "override_policy_documents": null, + "policy_id": null, + "source_json": null, + "source_policy_documents": null, + "statement": [ + { + "actions": [ + "iam:CreateServiceLinkedRole" + ], + "condition": [ + { + "test": "StringEquals", + "values": [ + "elasticloadbalancing.amazonaws.com" + ], + "variable": "iam:AWSServiceName" + } + ], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "*" + ], + "sid": "" + }, + { + "actions": [ + "ec2:DescribeAccountAttributes", + "ec2:DescribeAddresses", + "ec2:DescribeAvailabilityZones", + "ec2:DescribeCoipPools", + "ec2:DescribeInstances", + "ec2:DescribeInternetGateways", + "ec2:DescribeIpamPools", + "ec2:DescribeNetworkInterfaces", + "ec2:DescribeRouteTables", + "ec2:DescribeSecurityGroups", + "ec2:DescribeSubnets", + "ec2:DescribeTags", + "ec2:DescribeVpcPeeringConnections", + "ec2:DescribeVpcs", + "ec2:GetCoipPoolUsage", + "ec2:GetSecurityGroupsForVpc", + "elasticloadbalancing:DescribeCapacityReservation", + "elasticloadbalancing:DescribeListenerAttributes", + "elasticloadbalancing:DescribeListenerCertificates", + "elasticloadbalancing:DescribeListeners", + "elasticloadbalancing:DescribeLoadBalancerAttributes", + "elasticloadbalancing:DescribeLoadBalancers", + "elasticloadbalancing:DescribeRules", + "elasticloadbalancing:DescribeSSLPolicies", + "elasticloadbalancing:DescribeTags", + "elasticloadbalancing:DescribeTargetGroupAttributes", + "elasticloadbalancing:DescribeTargetGroups", + "elasticloadbalancing:DescribeTargetHealth", + "elasticloadbalancing:DescribeTrustStores" + ], + "condition": [], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "*" + ], + "sid": "" + }, + { + "actions": [ + "acm:DescribeCertificate", + "acm:ListCertificates", + "cognito-idp:DescribeUserPoolClient", + "iam:GetServerCertificate", + "iam:ListServerCertificates", + "shield:CreateProtection", + "shield:DeleteProtection", + "shield:DescribeProtection", + "shield:GetSubscriptionState", + "waf-regional:AssociateWebACL", + "waf-regional:DisassociateWebACL", + "waf-regional:GetWebACL", + "waf-regional:GetWebACLForResource", + "wafv2:AssociateWebACL", + "wafv2:DisassociateWebACL", + "wafv2:GetWebACL", + "wafv2:GetWebACLForResource" + ], + "condition": [], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "*" + ], + "sid": "" + }, + { + "actions": [ + "ec2:AuthorizeSecurityGroupIngress", + "ec2:RevokeSecurityGroupIngress" + ], + "condition": [], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "*" + ], + "sid": "" + }, + { + "actions": [ + "ec2:CreateSecurityGroup" + ], + "condition": [], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "*" + ], + "sid": "" + }, + { + "actions": [ + "ec2:CreateTags" + ], + "condition": [ + { + "test": "Null", + "values": [ + "false" + ], + "variable": "aws:RequestTag/elbv2.k8s.aws/cluster" + }, + { + "test": "StringEquals", + "values": [ + "CreateSecurityGroup" + ], + "variable": "ec2:CreateAction" + } + ], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "arn:aws:ec2:*:*:security-group/*" + ], + "sid": "" + }, + { + "actions": [ + "ec2:CreateTags", + "ec2:DeleteTags" + ], + "condition": [ + { + "test": "Null", + "values": [ + "false" + ], + "variable": "aws:ResourceTag/elbv2.k8s.aws/cluster" + }, + { + "test": "Null", + "values": [ + "true" + ], + "variable": "aws:RequestTag/elbv2.k8s.aws/cluster" + } + ], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "arn:aws:ec2:*:*:security-group/*" + ], + "sid": "" + }, + { + "actions": [ + "ec2:AuthorizeSecurityGroupIngress", + "ec2:DeleteSecurityGroup", + "ec2:RevokeSecurityGroupIngress" + ], + "condition": [ + { + "test": "Null", + "values": [ + "false" + ], + "variable": "aws:ResourceTag/elbv2.k8s.aws/cluster" + } + ], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "*" + ], + "sid": "" + }, + { + "actions": [ + "elasticloadbalancing:CreateLoadBalancer", + "elasticloadbalancing:CreateTargetGroup" + ], + "condition": [ + { + "test": "Null", + "values": [ + "false" + ], + "variable": "aws:RequestTag/elbv2.k8s.aws/cluster" + } + ], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "*" + ], + "sid": "" + }, + { + "actions": [ + "elasticloadbalancing:CreateListener", + "elasticloadbalancing:CreateRule", + "elasticloadbalancing:DeleteListener", + "elasticloadbalancing:DeleteRule" + ], + "condition": [], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "*" + ], + "sid": "" + }, + { + "actions": [ + "elasticloadbalancing:AddTags", + "elasticloadbalancing:RemoveTags" + ], + "condition": [ + { + "test": "Null", + "values": [ + "false" + ], + "variable": "aws:ResourceTag/elbv2.k8s.aws/cluster" + }, + { + "test": "Null", + "values": [ + "true" + ], + "variable": "aws:RequestTag/elbv2.k8s.aws/cluster" + } + ], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "arn:aws:elasticloadbalancing:*:*:loadbalancer/app/*/*", + "arn:aws:elasticloadbalancing:*:*:loadbalancer/net/*/*", + "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*" + ], + "sid": "" + }, + { + "actions": [ + "elasticloadbalancing:AddTags", + "elasticloadbalancing:RemoveTags" + ], + "condition": [], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "arn:aws:elasticloadbalancing:*:*:listener-rule/app/*/*/*", + "arn:aws:elasticloadbalancing:*:*:listener-rule/net/*/*/*", + "arn:aws:elasticloadbalancing:*:*:listener/app/*/*/*", + "arn:aws:elasticloadbalancing:*:*:listener/net/*/*/*" + ], + "sid": "" + }, + { + "actions": [ + "elasticloadbalancing:DeleteLoadBalancer", + "elasticloadbalancing:DeleteTargetGroup", + "elasticloadbalancing:ModifyCapacityReservation", + "elasticloadbalancing:ModifyIpPools", + "elasticloadbalancing:ModifyListenerAttributes", + "elasticloadbalancing:ModifyLoadBalancerAttributes", + "elasticloadbalancing:ModifyTargetGroup", + "elasticloadbalancing:ModifyTargetGroupAttributes", + "elasticloadbalancing:SetIpAddressType", + "elasticloadbalancing:SetSecurityGroups", + "elasticloadbalancing:SetSubnets" + ], + "condition": [ + { + "test": "Null", + "values": [ + "false" + ], + "variable": "aws:ResourceTag/elbv2.k8s.aws/cluster" + } + ], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "*" + ], + "sid": "" + }, + { + "actions": [ + "elasticloadbalancing:AddTags" + ], + "condition": [ + { + "test": "Null", + "values": [ + "false" + ], + "variable": "aws:RequestTag/elbv2.k8s.aws/cluster" + }, + { + "test": "StringEquals", + "values": [ + "CreateTargetGroup", + "CreateLoadBalancer" + ], + "variable": "elasticloadbalancing:CreateAction" + } + ], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "arn:aws:elasticloadbalancing:*:*:loadbalancer/app/*/*", + "arn:aws:elasticloadbalancing:*:*:loadbalancer/net/*/*", + "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*" + ], + "sid": "" + }, + { + "actions": [ + "elasticloadbalancing:DeregisterTargets", + "elasticloadbalancing:RegisterTargets" + ], + "condition": [], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*" + ], + "sid": "" + }, + { + "actions": [ + "elasticloadbalancing:AddListenerCertificates", + "elasticloadbalancing:ModifyListener", + "elasticloadbalancing:ModifyRule", + "elasticloadbalancing:RemoveListenerCertificates", + "elasticloadbalancing:SetRulePriorities", + "elasticloadbalancing:SetWebAcl" + ], + "condition": [], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [], + "resources": [ + "*" + ], + "sid": "" + } + ], + "version": "2012-10-17" + }, + "sensitive_attributes": [] + } + ] + }, + { + "module": "module.lb_controller_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "load_balancer_controller_targetgroup_only", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "mountpoint_s3_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "node_termination_handler", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "id": "1290851146", + "json": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Action\": \"sts:AssumeRoleWithWebIdentity\",\n \"Principal\": {\n \"Federated\": \"arn:aws:iam::027423573553:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D\"\n },\n \"Condition\": {\n \"StringEquals\": {\n \"oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D:aud\": \"sts.amazonaws.com\",\n \"oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D:sub\": \"system:serviceaccount:kube-system:aws-load-balancer-controller\"\n }\n }\n }\n ]\n}", + "minified_json": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"sts:AssumeRoleWithWebIdentity\",\"Principal\":{\"Federated\":\"arn:aws:iam::027423573553:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D\"},\"Condition\":{\"StringEquals\":{\"oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D:aud\":\"sts.amazonaws.com\",\"oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D:sub\":\"system:serviceaccount:kube-system:aws-load-balancer-controller\"}}}]}", + "override_json": null, + "override_policy_documents": null, + "policy_id": null, + "source_json": null, + "source_policy_documents": null, + "statement": [ + { + "actions": [ + "sts:AssumeRoleWithWebIdentity" + ], + "condition": [ + { + "test": "StringEquals", + "values": [ + "sts.amazonaws.com" + ], + "variable": "oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D:aud" + }, + { + "test": "StringEquals", + "values": [ + "system:serviceaccount:kube-system:aws-load-balancer-controller" + ], + "variable": "oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D:sub" + } + ], + "effect": "Allow", + "not_actions": [], + "not_principals": [], + "not_resources": [], + "principals": [ + { + "identifiers": [ + "arn:aws:iam::027423573553:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D" + ], + "type": "Federated" + } + ], + "resources": [], + "sid": "" + } + ], + "version": "2012-10-17" + }, + "sensitive_attributes": [] + } + ] + }, + { + "module": "module.lb_controller_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "velero", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "vpc_cni", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "data", + "type": "aws_partition", + "name": "current", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "dns_suffix": "amazonaws.com", + "id": "aws", + "partition": "aws", + "reverse_dns_prefix": "com.amazonaws" + }, + "sensitive_attributes": [] + } + ] + }, + { + "module": "module.lb_controller_irsa", + "mode": "data", + "type": "aws_region", + "name": "current", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "schema_version": 0, + "attributes": { + "description": "US West (Oregon)", + "endpoint": "ec2.us-west-2.amazonaws.com", + "id": "us-west-2", + "name": "us-west-2" + }, + "sensitive_attributes": [] + } + ] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "amazon_managed_service_prometheus", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "appmesh_controller", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "appmesh_envoy_proxy", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "aws_gateway_controller", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "cert_manager", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "cluster_autoscaler", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "ebs_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "efs_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "external_dns", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "external_secrets", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "fsx_lustre_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "fsx_openzfs_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "karpenter_controller", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "load_balancer_controller", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "arn": "arn:aws:iam::027423573553:policy/AmazonEKS_AWS_Load_Balancer_Controller-20260318201827555800000006", + "attachment_count": 1, + "description": "Provides permissions for AWS Load Balancer Controller addon", + "id": "arn:aws:iam::027423573553:policy/AmazonEKS_AWS_Load_Balancer_Controller-20260318201827555800000006", + "name": "AmazonEKS_AWS_Load_Balancer_Controller-20260318201827555800000006", + "name_prefix": "AmazonEKS_AWS_Load_Balancer_Controller-", + "path": "/", + "policy": "{\"Statement\":[{\"Action\":\"iam:CreateServiceLinkedRole\",\"Condition\":{\"StringEquals\":{\"iam:AWSServiceName\":\"elasticloadbalancing.amazonaws.com\"}},\"Effect\":\"Allow\",\"Resource\":\"*\"},{\"Action\":[\"elasticloadbalancing:DescribeTrustStores\",\"elasticloadbalancing:DescribeTargetHealth\",\"elasticloadbalancing:DescribeTargetGroups\",\"elasticloadbalancing:DescribeTargetGroupAttributes\",\"elasticloadbalancing:DescribeTags\",\"elasticloadbalancing:DescribeSSLPolicies\",\"elasticloadbalancing:DescribeRules\",\"elasticloadbalancing:DescribeLoadBalancers\",\"elasticloadbalancing:DescribeLoadBalancerAttributes\",\"elasticloadbalancing:DescribeListeners\",\"elasticloadbalancing:DescribeListenerCertificates\",\"elasticloadbalancing:DescribeListenerAttributes\",\"elasticloadbalancing:DescribeCapacityReservation\",\"ec2:GetSecurityGroupsForVpc\",\"ec2:GetCoipPoolUsage\",\"ec2:DescribeVpcs\",\"ec2:DescribeVpcPeeringConnections\",\"ec2:DescribeTags\",\"ec2:DescribeSubnets\",\"ec2:DescribeSecurityGroups\",\"ec2:DescribeRouteTables\",\"ec2:DescribeNetworkInterfaces\",\"ec2:DescribeIpamPools\",\"ec2:DescribeInternetGateways\",\"ec2:DescribeInstances\",\"ec2:DescribeCoipPools\",\"ec2:DescribeAvailabilityZones\",\"ec2:DescribeAddresses\",\"ec2:DescribeAccountAttributes\"],\"Effect\":\"Allow\",\"Resource\":\"*\"},{\"Action\":[\"wafv2:GetWebACLForResource\",\"wafv2:GetWebACL\",\"wafv2:DisassociateWebACL\",\"wafv2:AssociateWebACL\",\"waf-regional:GetWebACLForResource\",\"waf-regional:GetWebACL\",\"waf-regional:DisassociateWebACL\",\"waf-regional:AssociateWebACL\",\"shield:GetSubscriptionState\",\"shield:DescribeProtection\",\"shield:DeleteProtection\",\"shield:CreateProtection\",\"iam:ListServerCertificates\",\"iam:GetServerCertificate\",\"cognito-idp:DescribeUserPoolClient\",\"acm:ListCertificates\",\"acm:DescribeCertificate\"],\"Effect\":\"Allow\",\"Resource\":\"*\"},{\"Action\":[\"ec2:RevokeSecurityGroupIngress\",\"ec2:AuthorizeSecurityGroupIngress\"],\"Effect\":\"Allow\",\"Resource\":\"*\"},{\"Action\":\"ec2:CreateSecurityGroup\",\"Effect\":\"Allow\",\"Resource\":\"*\"},{\"Action\":\"ec2:CreateTags\",\"Condition\":{\"Null\":{\"aws:RequestTag/elbv2.k8s.aws/cluster\":\"false\"},\"StringEquals\":{\"ec2:CreateAction\":\"CreateSecurityGroup\"}},\"Effect\":\"Allow\",\"Resource\":\"arn:aws:ec2:*:*:security-group/*\"},{\"Action\":[\"ec2:DeleteTags\",\"ec2:CreateTags\"],\"Condition\":{\"Null\":{\"aws:RequestTag/elbv2.k8s.aws/cluster\":\"true\",\"aws:ResourceTag/elbv2.k8s.aws/cluster\":\"false\"}},\"Effect\":\"Allow\",\"Resource\":\"arn:aws:ec2:*:*:security-group/*\"},{\"Action\":[\"ec2:RevokeSecurityGroupIngress\",\"ec2:DeleteSecurityGroup\",\"ec2:AuthorizeSecurityGroupIngress\"],\"Condition\":{\"Null\":{\"aws:ResourceTag/elbv2.k8s.aws/cluster\":\"false\"}},\"Effect\":\"Allow\",\"Resource\":\"*\"},{\"Action\":[\"elasticloadbalancing:CreateTargetGroup\",\"elasticloadbalancing:CreateLoadBalancer\"],\"Condition\":{\"Null\":{\"aws:RequestTag/elbv2.k8s.aws/cluster\":\"false\"}},\"Effect\":\"Allow\",\"Resource\":\"*\"},{\"Action\":[\"elasticloadbalancing:DeleteRule\",\"elasticloadbalancing:DeleteListener\",\"elasticloadbalancing:CreateRule\",\"elasticloadbalancing:CreateListener\"],\"Effect\":\"Allow\",\"Resource\":\"*\"},{\"Action\":[\"elasticloadbalancing:RemoveTags\",\"elasticloadbalancing:AddTags\"],\"Condition\":{\"Null\":{\"aws:RequestTag/elbv2.k8s.aws/cluster\":\"true\",\"aws:ResourceTag/elbv2.k8s.aws/cluster\":\"false\"}},\"Effect\":\"Allow\",\"Resource\":[\"arn:aws:elasticloadbalancing:*:*:targetgroup/*/*\",\"arn:aws:elasticloadbalancing:*:*:loadbalancer/net/*/*\",\"arn:aws:elasticloadbalancing:*:*:loadbalancer/app/*/*\"]},{\"Action\":[\"elasticloadbalancing:RemoveTags\",\"elasticloadbalancing:AddTags\"],\"Effect\":\"Allow\",\"Resource\":[\"arn:aws:elasticloadbalancing:*:*:listener/net/*/*/*\",\"arn:aws:elasticloadbalancing:*:*:listener/app/*/*/*\",\"arn:aws:elasticloadbalancing:*:*:listener-rule/net/*/*/*\",\"arn:aws:elasticloadbalancing:*:*:listener-rule/app/*/*/*\"]},{\"Action\":[\"elasticloadbalancing:SetSubnets\",\"elasticloadbalancing:SetSecurityGroups\",\"elasticloadbalancing:SetIpAddressType\",\"elasticloadbalancing:ModifyTargetGroupAttributes\",\"elasticloadbalancing:ModifyTargetGroup\",\"elasticloadbalancing:ModifyLoadBalancerAttributes\",\"elasticloadbalancing:ModifyListenerAttributes\",\"elasticloadbalancing:ModifyIpPools\",\"elasticloadbalancing:ModifyCapacityReservation\",\"elasticloadbalancing:DeleteTargetGroup\",\"elasticloadbalancing:DeleteLoadBalancer\"],\"Condition\":{\"Null\":{\"aws:ResourceTag/elbv2.k8s.aws/cluster\":\"false\"}},\"Effect\":\"Allow\",\"Resource\":\"*\"},{\"Action\":\"elasticloadbalancing:AddTags\",\"Condition\":{\"Null\":{\"aws:RequestTag/elbv2.k8s.aws/cluster\":\"false\"},\"StringEquals\":{\"elasticloadbalancing:CreateAction\":[\"CreateTargetGroup\",\"CreateLoadBalancer\"]}},\"Effect\":\"Allow\",\"Resource\":[\"arn:aws:elasticloadbalancing:*:*:targetgroup/*/*\",\"arn:aws:elasticloadbalancing:*:*:loadbalancer/net/*/*\",\"arn:aws:elasticloadbalancing:*:*:loadbalancer/app/*/*\"]},{\"Action\":[\"elasticloadbalancing:RegisterTargets\",\"elasticloadbalancing:DeregisterTargets\"],\"Effect\":\"Allow\",\"Resource\":\"arn:aws:elasticloadbalancing:*:*:targetgroup/*/*\"},{\"Action\":[\"elasticloadbalancing:SetWebAcl\",\"elasticloadbalancing:SetRulePriorities\",\"elasticloadbalancing:RemoveListenerCertificates\",\"elasticloadbalancing:ModifyRule\",\"elasticloadbalancing:ModifyListener\",\"elasticloadbalancing:AddListenerCertificates\"],\"Effect\":\"Allow\",\"Resource\":\"*\"}],\"Version\":\"2012-10-17\"}", + "policy_id": "ANPAQMYUSQYYYIABW6PHV", + "tags": {}, + "tags_all": { + "ManagedBy": "terraform", + "Project": "observability-stack" + } + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "module.lb_controller_irsa.data.aws_iam_policy_document.load_balancer_controller", + "module.lb_controller_irsa.data.aws_partition.current" + ] + } + ] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "load_balancer_controller_targetgroup_only", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "mountpoint_s3_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "node_termination_handler", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "velero", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_policy", + "name": "vpc_cni", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_role", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "arn": "arn:aws:iam::027423573553:role/observability-stack-lb-controller", + "assume_role_policy": "{\"Statement\":[{\"Action\":\"sts:AssumeRoleWithWebIdentity\",\"Condition\":{\"StringEquals\":{\"oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D:aud\":\"sts.amazonaws.com\",\"oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D:sub\":\"system:serviceaccount:kube-system:aws-load-balancer-controller\"}},\"Effect\":\"Allow\",\"Principal\":{\"Federated\":\"arn:aws:iam::027423573553:oidc-provider/oidc.eks.us-west-2.amazonaws.com/id/91D986DCB52447A7F312838B02FCD62D\"}}],\"Version\":\"2012-10-17\"}", + "create_date": "2026-03-18T20:28:14Z", + "description": "", + "force_detach_policies": true, + "id": "observability-stack-lb-controller", + "inline_policy": [], + "managed_policy_arns": [ + "arn:aws:iam::027423573553:policy/AmazonEKS_AWS_Load_Balancer_Controller-20260318201827555800000006" + ], + "max_session_duration": 3600, + "name": "observability-stack-lb-controller", + "name_prefix": "", + "path": "/", + "permissions_boundary": "", + "tags": {}, + "tags_all": { + "ManagedBy": "terraform", + "Project": "observability-stack" + }, + "unique_id": "AROAQMYUSQYYXI2MJFYL2" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "data.aws_availability_zones.available", + "module.eks.aws_cloudwatch_log_group.this", + "module.eks.aws_eks_cluster.this", + "module.eks.aws_iam_openid_connect_provider.oidc_provider", + "module.eks.aws_iam_policy.cni_ipv6_policy", + "module.eks.aws_iam_role.eks_auto", + "module.eks.aws_iam_role.this", + "module.eks.aws_iam_role_policy_attachment.this", + "module.eks.aws_security_group.cluster", + "module.eks.aws_security_group.node", + "module.eks.aws_security_group_rule.cluster", + "module.eks.aws_security_group_rule.node", + "module.eks.data.aws_caller_identity.current", + "module.eks.data.aws_iam_policy_document.assume_role_policy", + "module.eks.data.aws_iam_policy_document.cni_ipv6_policy", + "module.eks.data.aws_iam_policy_document.node_assume_role_policy", + "module.eks.data.aws_iam_session_context.current", + "module.eks.data.aws_partition.current", + "module.eks.data.tls_certificate.this", + "module.eks.module.kms.aws_kms_external_key.this", + "module.eks.module.kms.aws_kms_key.this", + "module.eks.module.kms.aws_kms_replica_external_key.this", + "module.eks.module.kms.aws_kms_replica_key.this", + "module.eks.module.kms.data.aws_caller_identity.current", + "module.eks.module.kms.data.aws_iam_policy_document.this", + "module.eks.module.kms.data.aws_partition.current", + "module.lb_controller_irsa.data.aws_caller_identity.current", + "module.lb_controller_irsa.data.aws_iam_policy_document.this", + "module.lb_controller_irsa.data.aws_partition.current", + "module.vpc.aws_subnet.private", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ] + } + ] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "amazon_cloudwatch_observability", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "amazon_managed_service_prometheus", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "appmesh_controller", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "appmesh_envoy_proxy", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "aws_gateway_controller", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "cert_manager", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "cluster_autoscaler", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "ebs_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "efs_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "external_dns", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "external_secrets", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "fsx_lustre_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "fsx_openzfs_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "karpenter_controller", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "load_balancer_controller", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "id": "observability-stack-lb-controller-20260318202815389000000016", + "policy_arn": "arn:aws:iam::027423573553:policy/AmazonEKS_AWS_Load_Balancer_Controller-20260318201827555800000006", + "role": "observability-stack-lb-controller" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "data.aws_availability_zones.available", + "module.eks.aws_cloudwatch_log_group.this", + "module.eks.aws_eks_cluster.this", + "module.eks.aws_iam_openid_connect_provider.oidc_provider", + "module.eks.aws_iam_policy.cni_ipv6_policy", + "module.eks.aws_iam_role.eks_auto", + "module.eks.aws_iam_role.this", + "module.eks.aws_iam_role_policy_attachment.this", + "module.eks.aws_security_group.cluster", + "module.eks.aws_security_group.node", + "module.eks.aws_security_group_rule.cluster", + "module.eks.aws_security_group_rule.node", + "module.eks.data.aws_caller_identity.current", + "module.eks.data.aws_iam_policy_document.assume_role_policy", + "module.eks.data.aws_iam_policy_document.cni_ipv6_policy", + "module.eks.data.aws_iam_policy_document.node_assume_role_policy", + "module.eks.data.aws_iam_session_context.current", + "module.eks.data.aws_partition.current", + "module.eks.data.tls_certificate.this", + "module.eks.module.kms.aws_kms_external_key.this", + "module.eks.module.kms.aws_kms_key.this", + "module.eks.module.kms.aws_kms_replica_external_key.this", + "module.eks.module.kms.aws_kms_replica_key.this", + "module.eks.module.kms.data.aws_caller_identity.current", + "module.eks.module.kms.data.aws_iam_policy_document.this", + "module.eks.module.kms.data.aws_partition.current", + "module.lb_controller_irsa.aws_iam_policy.load_balancer_controller", + "module.lb_controller_irsa.aws_iam_role.this", + "module.lb_controller_irsa.data.aws_caller_identity.current", + "module.lb_controller_irsa.data.aws_iam_policy_document.load_balancer_controller", + "module.lb_controller_irsa.data.aws_iam_policy_document.this", + "module.lb_controller_irsa.data.aws_partition.current", + "module.vpc.aws_subnet.private", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ] + } + ] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "load_balancer_controller_targetgroup_only", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "mountpoint_s3_csi", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "node_termination_handler", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "velero", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.lb_controller_irsa", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "vpc_cni", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "data", + "type": "aws_caller_identity", + "name": "current", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "flow_log_cloudwatch_assume_role", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "data", + "type": "aws_iam_policy_document", + "name": "vpc_flow_log_cloudwatch", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "data", + "type": "aws_partition", + "name": "current", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "data", + "type": "aws_region", + "name": "current", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_cloudwatch_log_group", + "name": "flow_log", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_customer_gateway", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_db_subnet_group", + "name": "database", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_default_network_acl", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "arn": "arn:aws:ec2:us-west-2:027423573553:network-acl/acl-0a5e114c086bba3b7", + "default_network_acl_id": "acl-0a5e114c086bba3b7", + "egress": [ + { + "action": "allow", + "cidr_block": "", + "from_port": 0, + "icmp_code": 0, + "icmp_type": 0, + "ipv6_cidr_block": "::/0", + "protocol": "-1", + "rule_no": 101, + "to_port": 0 + }, + { + "action": "allow", + "cidr_block": "0.0.0.0/0", + "from_port": 0, + "icmp_code": 0, + "icmp_type": 0, + "ipv6_cidr_block": "", + "protocol": "-1", + "rule_no": 100, + "to_port": 0 + } + ], + "id": "acl-0a5e114c086bba3b7", + "ingress": [ + { + "action": "allow", + "cidr_block": "", + "from_port": 0, + "icmp_code": 0, + "icmp_type": 0, + "ipv6_cidr_block": "::/0", + "protocol": "-1", + "rule_no": 101, + "to_port": 0 + }, + { + "action": "allow", + "cidr_block": "0.0.0.0/0", + "from_port": 0, + "icmp_code": 0, + "icmp_type": 0, + "ipv6_cidr_block": "", + "protocol": "-1", + "rule_no": 100, + "to_port": 0 + } + ], + "owner_id": "027423573553", + "subnet_ids": [ + "subnet-00bc6b6598ab09efb", + "subnet-0103d5dff6443d113", + "subnet-02fb98c38c541a8d8", + "subnet-06f8647c688701ae4", + "subnet-071119bffc7eafe55", + "subnet-0862c3b38b530fd97" + ], + "tags": { + "Name": "observability-stack-default" + }, + "tags_all": { + "ManagedBy": "terraform", + "Name": "observability-stack-default", + "Project": "observability-stack" + }, + "vpc_id": "vpc-03aefcf5aa0581d7a" + }, + "sensitive_attributes": [], + "private": "bnVsbA==", + "dependencies": [ + "module.vpc.aws_vpc.this" + ] + } + ] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_default_route_table", + "name": "default", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "arn": "arn:aws:ec2:us-west-2:027423573553:route-table/rtb-0eb0c8a9b7385e199", + "default_route_table_id": "rtb-0eb0c8a9b7385e199", + "id": "rtb-0eb0c8a9b7385e199", + "owner_id": "027423573553", + "propagating_vgws": [], + "route": [], + "tags": { + "Name": "observability-stack-default" + }, + "tags_all": { + "ManagedBy": "terraform", + "Name": "observability-stack-default", + "Project": "observability-stack" + }, + "timeouts": { + "create": "5m", + "update": "5m" + }, + "vpc_id": "vpc-03aefcf5aa0581d7a" + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjozMDAwMDAwMDAwMDAsInVwZGF0ZSI6MzAwMDAwMDAwMDAwfX0=", + "dependencies": [ + "module.vpc.aws_vpc.this" + ] + } + ] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_default_security_group", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 1, + "attributes": { + "arn": "arn:aws:ec2:us-west-2:027423573553:security-group/sg-01804f6e1f144e984", + "description": "default VPC security group", + "egress": [], + "id": "sg-01804f6e1f144e984", + "ingress": [], + "name": "default", + "name_prefix": "", + "owner_id": "027423573553", + "revoke_rules_on_delete": false, + "tags": { + "Name": "observability-stack-default" + }, + "tags_all": { + "ManagedBy": "terraform", + "Name": "observability-stack-default", + "Project": "observability-stack" + }, + "vpc_id": "vpc-03aefcf5aa0581d7a" + }, + "sensitive_attributes": [], + "private": "eyJzY2hlbWFfdmVyc2lvbiI6IjEifQ==", + "dependencies": [ + "module.vpc.aws_vpc.this" + ] + } + ] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_default_vpc", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_egress_only_internet_gateway", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_eip", + "name": "nat", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "address": null, + "allocation_id": "eipalloc-0113a2632fcf6cddf", + "arn": "arn:aws:ec2:us-west-2:027423573553:elastic-ip/eipalloc-0113a2632fcf6cddf", + "associate_with_private_ip": null, + "association_id": "eipassoc-04a75448822bedae0", + "carrier_ip": "", + "customer_owned_ip": "", + "customer_owned_ipv4_pool": "", + "domain": "vpc", + "id": "eipalloc-0113a2632fcf6cddf", + "instance": "", + "ipam_pool_id": null, + "network_border_group": "us-west-2", + "network_interface": "eni-0d26887f86c85fe3e", + "private_dns": "ip-10-0-120-98.us-west-2.compute.internal", + "private_ip": "10.0.120.98", + "ptr_record": "", + "public_dns": "ec2-52-88-124-67.us-west-2.compute.amazonaws.com", + "public_ip": "52.88.124.67", + "public_ipv4_pool": "amazon", + "tags": { + "Name": "observability-stack-us-west-2a" + }, + "tags_all": { + "ManagedBy": "terraform", + "Name": "observability-stack-us-west-2a", + "Project": "observability-stack" + }, + "timeouts": null, + "vpc": true + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiZGVsZXRlIjoxODAwMDAwMDAwMDAsInJlYWQiOjkwMDAwMDAwMDAwMCwidXBkYXRlIjozMDAwMDAwMDAwMDB9fQ==", + "dependencies": [ + "data.aws_availability_zones.available", + "module.vpc.aws_internet_gateway.this", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ] + } + ] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_elasticache_subnet_group", + "name": "elasticache", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_flow_log", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_iam_policy", + "name": "vpc_flow_log_cloudwatch", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_iam_role", + "name": "vpc_flow_log_cloudwatch", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_iam_role_policy_attachment", + "name": "vpc_flow_log_cloudwatch", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_internet_gateway", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "arn": "arn:aws:ec2:us-west-2:027423573553:internet-gateway/igw-0017951791f30c8cc", + "id": "igw-0017951791f30c8cc", + "owner_id": "027423573553", + "tags": { + "Name": "observability-stack" + }, + "tags_all": { + "ManagedBy": "terraform", + "Name": "observability-stack", + "Project": "observability-stack" + }, + "timeouts": null, + "vpc_id": "vpc-03aefcf5aa0581d7a" + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjoxMjAwMDAwMDAwMDAwLCJkZWxldGUiOjEyMDAwMDAwMDAwMDAsInVwZGF0ZSI6MTIwMDAwMDAwMDAwMH19", + "dependencies": [ + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ] + } + ] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_nat_gateway", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "allocation_id": "eipalloc-0113a2632fcf6cddf", + "association_id": "eipassoc-04a75448822bedae0", + "connectivity_type": "public", + "id": "nat-0777712a8d4bdb8c1", + "network_interface_id": "eni-0d26887f86c85fe3e", + "private_ip": "10.0.120.98", + "public_ip": "52.88.124.67", + "secondary_allocation_ids": [], + "secondary_private_ip_address_count": 0, + "secondary_private_ip_addresses": [], + "subnet_id": "subnet-0103d5dff6443d113", + "tags": { + "Name": "observability-stack-us-west-2a" + }, + "tags_all": { + "ManagedBy": "terraform", + "Name": "observability-stack-us-west-2a", + "Project": "observability-stack" + }, + "timeouts": null + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjo2MDAwMDAwMDAwMDAsImRlbGV0ZSI6MTgwMDAwMDAwMDAwMCwidXBkYXRlIjo2MDAwMDAwMDAwMDB9fQ==", + "dependencies": [ + "data.aws_availability_zones.available", + "module.vpc.aws_eip.nat", + "module.vpc.aws_internet_gateway.this", + "module.vpc.aws_subnet.public", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ] + } + ] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_network_acl", + "name": "database", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_network_acl", + "name": "elasticache", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_network_acl", + "name": "intra", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_network_acl", + "name": "outpost", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_network_acl", + "name": "private", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_network_acl", + "name": "public", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_network_acl", + "name": "redshift", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_network_acl_rule", + "name": "database_inbound", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_network_acl_rule", + "name": "database_outbound", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_network_acl_rule", + "name": "elasticache_inbound", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_network_acl_rule", + "name": "elasticache_outbound", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_network_acl_rule", + "name": "intra_inbound", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_network_acl_rule", + "name": "intra_outbound", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_network_acl_rule", + "name": "outpost_inbound", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_network_acl_rule", + "name": "outpost_outbound", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_network_acl_rule", + "name": "private_inbound", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_network_acl_rule", + "name": "private_outbound", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_network_acl_rule", + "name": "public_inbound", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_network_acl_rule", + "name": "public_outbound", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_network_acl_rule", + "name": "redshift_inbound", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_network_acl_rule", + "name": "redshift_outbound", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_redshift_subnet_group", + "name": "redshift", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_route", + "name": "database_dns64_nat_gateway", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_route", + "name": "database_internet_gateway", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_route", + "name": "database_ipv6_egress", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_route", + "name": "database_nat_gateway", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_route", + "name": "private_dns64_nat_gateway", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_route", + "name": "private_ipv6_egress", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_route", + "name": "private_nat_gateway", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "carrier_gateway_id": "", + "core_network_arn": "", + "destination_cidr_block": "0.0.0.0/0", + "destination_ipv6_cidr_block": "", + "destination_prefix_list_id": "", + "egress_only_gateway_id": "", + "gateway_id": "", + "id": "r-rtb-09296e0d036ce62661080289494", + "instance_id": "", + "instance_owner_id": "", + "local_gateway_id": "", + "nat_gateway_id": "nat-0777712a8d4bdb8c1", + "network_interface_id": "", + "origin": "CreateRoute", + "route_table_id": "rtb-09296e0d036ce6266", + "state": "active", + "timeouts": { + "create": "5m", + "delete": null, + "update": null + }, + "transit_gateway_id": "", + "vpc_endpoint_id": "", + "vpc_peering_connection_id": "" + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjozMDAwMDAwMDAwMDAsImRlbGV0ZSI6MzAwMDAwMDAwMDAwLCJ1cGRhdGUiOjEyMDAwMDAwMDAwMH19", + "dependencies": [ + "data.aws_availability_zones.available", + "module.vpc.aws_eip.nat", + "module.vpc.aws_internet_gateway.this", + "module.vpc.aws_nat_gateway.this", + "module.vpc.aws_route_table.private", + "module.vpc.aws_subnet.public", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ] + } + ] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_route", + "name": "public_internet_gateway", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "carrier_gateway_id": "", + "core_network_arn": "", + "destination_cidr_block": "0.0.0.0/0", + "destination_ipv6_cidr_block": "", + "destination_prefix_list_id": "", + "egress_only_gateway_id": "", + "gateway_id": "igw-0017951791f30c8cc", + "id": "r-rtb-073d827383549597d1080289494", + "instance_id": "", + "instance_owner_id": "", + "local_gateway_id": "", + "nat_gateway_id": "", + "network_interface_id": "", + "origin": "CreateRoute", + "route_table_id": "rtb-073d827383549597d", + "state": "active", + "timeouts": { + "create": "5m", + "delete": null, + "update": null + }, + "transit_gateway_id": "", + "vpc_endpoint_id": "", + "vpc_peering_connection_id": "" + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjozMDAwMDAwMDAwMDAsImRlbGV0ZSI6MzAwMDAwMDAwMDAwLCJ1cGRhdGUiOjEyMDAwMDAwMDAwMH19", + "dependencies": [ + "data.aws_availability_zones.available", + "module.vpc.aws_internet_gateway.this", + "module.vpc.aws_route_table.public", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ] + } + ] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_route", + "name": "public_internet_gateway_ipv6", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_route_table", + "name": "database", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_route_table", + "name": "elasticache", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_route_table", + "name": "intra", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_route_table", + "name": "private", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "arn": "arn:aws:ec2:us-west-2:027423573553:route-table/rtb-09296e0d036ce6266", + "id": "rtb-09296e0d036ce6266", + "owner_id": "027423573553", + "propagating_vgws": [], + "route": [ + { + "carrier_gateway_id": "", + "cidr_block": "0.0.0.0/0", + "core_network_arn": "", + "destination_prefix_list_id": "", + "egress_only_gateway_id": "", + "gateway_id": "", + "ipv6_cidr_block": "", + "local_gateway_id": "", + "nat_gateway_id": "nat-0777712a8d4bdb8c1", + "network_interface_id": "", + "transit_gateway_id": "", + "vpc_endpoint_id": "", + "vpc_peering_connection_id": "" + } + ], + "tags": { + "Name": "observability-stack-private" + }, + "tags_all": { + "ManagedBy": "terraform", + "Name": "observability-stack-private", + "Project": "observability-stack" + }, + "timeouts": null, + "vpc_id": "vpc-03aefcf5aa0581d7a" + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjozMDAwMDAwMDAwMDAsImRlbGV0ZSI6MzAwMDAwMDAwMDAwLCJ1cGRhdGUiOjEyMDAwMDAwMDAwMH19", + "dependencies": [ + "data.aws_availability_zones.available", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ] + } + ] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_route_table", + "name": "public", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "arn": "arn:aws:ec2:us-west-2:027423573553:route-table/rtb-073d827383549597d", + "id": "rtb-073d827383549597d", + "owner_id": "027423573553", + "propagating_vgws": [], + "route": [ + { + "carrier_gateway_id": "", + "cidr_block": "0.0.0.0/0", + "core_network_arn": "", + "destination_prefix_list_id": "", + "egress_only_gateway_id": "", + "gateway_id": "igw-0017951791f30c8cc", + "ipv6_cidr_block": "", + "local_gateway_id": "", + "nat_gateway_id": "", + "network_interface_id": "", + "transit_gateway_id": "", + "vpc_endpoint_id": "", + "vpc_peering_connection_id": "" + } + ], + "tags": { + "Name": "observability-stack-public" + }, + "tags_all": { + "ManagedBy": "terraform", + "Name": "observability-stack-public", + "Project": "observability-stack" + }, + "timeouts": null, + "vpc_id": "vpc-03aefcf5aa0581d7a" + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjozMDAwMDAwMDAwMDAsImRlbGV0ZSI6MzAwMDAwMDAwMDAwLCJ1cGRhdGUiOjEyMDAwMDAwMDAwMH19", + "dependencies": [ + "data.aws_availability_zones.available", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ] + } + ] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_route_table", + "name": "redshift", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_route_table_association", + "name": "database", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_route_table_association", + "name": "elasticache", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_route_table_association", + "name": "intra", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_route_table_association", + "name": "outpost", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_route_table_association", + "name": "private", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "gateway_id": "", + "id": "rtbassoc-0733c252b1b4d11ad", + "route_table_id": "rtb-09296e0d036ce6266", + "subnet_id": "subnet-00bc6b6598ab09efb", + "timeouts": null + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjozMDAwMDAwMDAwMDAsImRlbGV0ZSI6MzAwMDAwMDAwMDAwLCJ1cGRhdGUiOjEyMDAwMDAwMDAwMH19", + "dependencies": [ + "data.aws_availability_zones.available", + "module.vpc.aws_route_table.private", + "module.vpc.aws_subnet.private", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ] + }, + { + "index_key": 1, + "schema_version": 0, + "attributes": { + "gateway_id": "", + "id": "rtbassoc-09f0385e55967b756", + "route_table_id": "rtb-09296e0d036ce6266", + "subnet_id": "subnet-0862c3b38b530fd97", + "timeouts": null + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjozMDAwMDAwMDAwMDAsImRlbGV0ZSI6MzAwMDAwMDAwMDAwLCJ1cGRhdGUiOjEyMDAwMDAwMDAwMH19", + "dependencies": [ + "data.aws_availability_zones.available", + "module.vpc.aws_route_table.private", + "module.vpc.aws_subnet.private", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ] + }, + { + "index_key": 2, + "schema_version": 0, + "attributes": { + "gateway_id": "", + "id": "rtbassoc-0ba7f463260829933", + "route_table_id": "rtb-09296e0d036ce6266", + "subnet_id": "subnet-06f8647c688701ae4", + "timeouts": null + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjozMDAwMDAwMDAwMDAsImRlbGV0ZSI6MzAwMDAwMDAwMDAwLCJ1cGRhdGUiOjEyMDAwMDAwMDAwMH19", + "dependencies": [ + "data.aws_availability_zones.available", + "module.vpc.aws_route_table.private", + "module.vpc.aws_subnet.private", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ] + } + ] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_route_table_association", + "name": "public", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 0, + "attributes": { + "gateway_id": "", + "id": "rtbassoc-024db46e61ffe0bb4", + "route_table_id": "rtb-073d827383549597d", + "subnet_id": "subnet-0103d5dff6443d113", + "timeouts": null + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjozMDAwMDAwMDAwMDAsImRlbGV0ZSI6MzAwMDAwMDAwMDAwLCJ1cGRhdGUiOjEyMDAwMDAwMDAwMH19", + "dependencies": [ + "data.aws_availability_zones.available", + "module.vpc.aws_route_table.public", + "module.vpc.aws_subnet.public", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ] + }, + { + "index_key": 1, + "schema_version": 0, + "attributes": { + "gateway_id": "", + "id": "rtbassoc-0c441f9a8fd6291e5", + "route_table_id": "rtb-073d827383549597d", + "subnet_id": "subnet-071119bffc7eafe55", + "timeouts": null + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjozMDAwMDAwMDAwMDAsImRlbGV0ZSI6MzAwMDAwMDAwMDAwLCJ1cGRhdGUiOjEyMDAwMDAwMDAwMH19", + "dependencies": [ + "data.aws_availability_zones.available", + "module.vpc.aws_route_table.public", + "module.vpc.aws_subnet.public", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ] + }, + { + "index_key": 2, + "schema_version": 0, + "attributes": { + "gateway_id": "", + "id": "rtbassoc-0a754d2b6cb30938f", + "route_table_id": "rtb-073d827383549597d", + "subnet_id": "subnet-02fb98c38c541a8d8", + "timeouts": null + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjozMDAwMDAwMDAwMDAsImRlbGV0ZSI6MzAwMDAwMDAwMDAwLCJ1cGRhdGUiOjEyMDAwMDAwMDAwMH19", + "dependencies": [ + "data.aws_availability_zones.available", + "module.vpc.aws_route_table.public", + "module.vpc.aws_subnet.public", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ] + } + ] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_route_table_association", + "name": "redshift", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_route_table_association", + "name": "redshift_public", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_subnet", + "name": "database", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_subnet", + "name": "elasticache", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_subnet", + "name": "intra", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_subnet", + "name": "outpost", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_subnet", + "name": "private", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 1, + "attributes": { + "arn": "arn:aws:ec2:us-west-2:027423573553:subnet/subnet-00bc6b6598ab09efb", + "assign_ipv6_address_on_creation": false, + "availability_zone": "us-west-2a", + "availability_zone_id": "usw2-az2", + "cidr_block": "10.0.0.0/19", + "customer_owned_ipv4_pool": "", + "enable_dns64": false, + "enable_lni_at_device_index": 0, + "enable_resource_name_dns_a_record_on_launch": false, + "enable_resource_name_dns_aaaa_record_on_launch": false, + "id": "subnet-00bc6b6598ab09efb", + "ipv6_cidr_block": "", + "ipv6_cidr_block_association_id": "", + "ipv6_native": false, + "map_customer_owned_ip_on_launch": false, + "map_public_ip_on_launch": false, + "outpost_arn": "", + "owner_id": "027423573553", + "private_dns_hostname_type_on_launch": "ip-name", + "tags": { + "Name": "observability-stack-private-us-west-2a", + "kubernetes.io/role/internal-elb": "1" + }, + "tags_all": { + "ManagedBy": "terraform", + "Name": "observability-stack-private-us-west-2a", + "Project": "observability-stack", + "kubernetes.io/role/internal-elb": "1" + }, + "timeouts": null, + "vpc_id": "vpc-03aefcf5aa0581d7a" + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjo2MDAwMDAwMDAwMDAsImRlbGV0ZSI6MTIwMDAwMDAwMDAwMH0sInNjaGVtYV92ZXJzaW9uIjoiMSJ9", + "dependencies": [ + "data.aws_availability_zones.available", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ], + "create_before_destroy": true + }, + { + "index_key": 1, + "schema_version": 1, + "attributes": { + "arn": "arn:aws:ec2:us-west-2:027423573553:subnet/subnet-0862c3b38b530fd97", + "assign_ipv6_address_on_creation": false, + "availability_zone": "us-west-2b", + "availability_zone_id": "usw2-az1", + "cidr_block": "10.0.32.0/19", + "customer_owned_ipv4_pool": "", + "enable_dns64": false, + "enable_lni_at_device_index": 0, + "enable_resource_name_dns_a_record_on_launch": false, + "enable_resource_name_dns_aaaa_record_on_launch": false, + "id": "subnet-0862c3b38b530fd97", + "ipv6_cidr_block": "", + "ipv6_cidr_block_association_id": "", + "ipv6_native": false, + "map_customer_owned_ip_on_launch": false, + "map_public_ip_on_launch": false, + "outpost_arn": "", + "owner_id": "027423573553", + "private_dns_hostname_type_on_launch": "ip-name", + "tags": { + "Name": "observability-stack-private-us-west-2b", + "kubernetes.io/role/internal-elb": "1" + }, + "tags_all": { + "ManagedBy": "terraform", + "Name": "observability-stack-private-us-west-2b", + "Project": "observability-stack", + "kubernetes.io/role/internal-elb": "1" + }, + "timeouts": null, + "vpc_id": "vpc-03aefcf5aa0581d7a" + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjo2MDAwMDAwMDAwMDAsImRlbGV0ZSI6MTIwMDAwMDAwMDAwMH0sInNjaGVtYV92ZXJzaW9uIjoiMSJ9", + "dependencies": [ + "data.aws_availability_zones.available", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ], + "create_before_destroy": true + }, + { + "index_key": 2, + "schema_version": 1, + "attributes": { + "arn": "arn:aws:ec2:us-west-2:027423573553:subnet/subnet-06f8647c688701ae4", + "assign_ipv6_address_on_creation": false, + "availability_zone": "us-west-2c", + "availability_zone_id": "usw2-az3", + "cidr_block": "10.0.64.0/19", + "customer_owned_ipv4_pool": "", + "enable_dns64": false, + "enable_lni_at_device_index": 0, + "enable_resource_name_dns_a_record_on_launch": false, + "enable_resource_name_dns_aaaa_record_on_launch": false, + "id": "subnet-06f8647c688701ae4", + "ipv6_cidr_block": "", + "ipv6_cidr_block_association_id": "", + "ipv6_native": false, + "map_customer_owned_ip_on_launch": false, + "map_public_ip_on_launch": false, + "outpost_arn": "", + "owner_id": "027423573553", + "private_dns_hostname_type_on_launch": "ip-name", + "tags": { + "Name": "observability-stack-private-us-west-2c", + "kubernetes.io/role/internal-elb": "1" + }, + "tags_all": { + "ManagedBy": "terraform", + "Name": "observability-stack-private-us-west-2c", + "Project": "observability-stack", + "kubernetes.io/role/internal-elb": "1" + }, + "timeouts": null, + "vpc_id": "vpc-03aefcf5aa0581d7a" + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjo2MDAwMDAwMDAwMDAsImRlbGV0ZSI6MTIwMDAwMDAwMDAwMH0sInNjaGVtYV92ZXJzaW9uIjoiMSJ9", + "dependencies": [ + "data.aws_availability_zones.available", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ], + "create_before_destroy": true + } + ] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_subnet", + "name": "public", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 1, + "attributes": { + "arn": "arn:aws:ec2:us-west-2:027423573553:subnet/subnet-0103d5dff6443d113", + "assign_ipv6_address_on_creation": false, + "availability_zone": "us-west-2a", + "availability_zone_id": "usw2-az2", + "cidr_block": "10.0.96.0/19", + "customer_owned_ipv4_pool": "", + "enable_dns64": false, + "enable_lni_at_device_index": 0, + "enable_resource_name_dns_a_record_on_launch": false, + "enable_resource_name_dns_aaaa_record_on_launch": false, + "id": "subnet-0103d5dff6443d113", + "ipv6_cidr_block": "", + "ipv6_cidr_block_association_id": "", + "ipv6_native": false, + "map_customer_owned_ip_on_launch": false, + "map_public_ip_on_launch": false, + "outpost_arn": "", + "owner_id": "027423573553", + "private_dns_hostname_type_on_launch": "ip-name", + "tags": { + "Name": "observability-stack-public-us-west-2a", + "kubernetes.io/role/elb": "1" + }, + "tags_all": { + "ManagedBy": "terraform", + "Name": "observability-stack-public-us-west-2a", + "Project": "observability-stack", + "kubernetes.io/role/elb": "1" + }, + "timeouts": null, + "vpc_id": "vpc-03aefcf5aa0581d7a" + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjo2MDAwMDAwMDAwMDAsImRlbGV0ZSI6MTIwMDAwMDAwMDAwMH0sInNjaGVtYV92ZXJzaW9uIjoiMSJ9", + "dependencies": [ + "data.aws_availability_zones.available", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ] + }, + { + "index_key": 1, + "schema_version": 1, + "attributes": { + "arn": "arn:aws:ec2:us-west-2:027423573553:subnet/subnet-071119bffc7eafe55", + "assign_ipv6_address_on_creation": false, + "availability_zone": "us-west-2b", + "availability_zone_id": "usw2-az1", + "cidr_block": "10.0.128.0/19", + "customer_owned_ipv4_pool": "", + "enable_dns64": false, + "enable_lni_at_device_index": 0, + "enable_resource_name_dns_a_record_on_launch": false, + "enable_resource_name_dns_aaaa_record_on_launch": false, + "id": "subnet-071119bffc7eafe55", + "ipv6_cidr_block": "", + "ipv6_cidr_block_association_id": "", + "ipv6_native": false, + "map_customer_owned_ip_on_launch": false, + "map_public_ip_on_launch": false, + "outpost_arn": "", + "owner_id": "027423573553", + "private_dns_hostname_type_on_launch": "ip-name", + "tags": { + "Name": "observability-stack-public-us-west-2b", + "kubernetes.io/role/elb": "1" + }, + "tags_all": { + "ManagedBy": "terraform", + "Name": "observability-stack-public-us-west-2b", + "Project": "observability-stack", + "kubernetes.io/role/elb": "1" + }, + "timeouts": null, + "vpc_id": "vpc-03aefcf5aa0581d7a" + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjo2MDAwMDAwMDAwMDAsImRlbGV0ZSI6MTIwMDAwMDAwMDAwMH0sInNjaGVtYV92ZXJzaW9uIjoiMSJ9", + "dependencies": [ + "data.aws_availability_zones.available", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ] + }, + { + "index_key": 2, + "schema_version": 1, + "attributes": { + "arn": "arn:aws:ec2:us-west-2:027423573553:subnet/subnet-02fb98c38c541a8d8", + "assign_ipv6_address_on_creation": false, + "availability_zone": "us-west-2c", + "availability_zone_id": "usw2-az3", + "cidr_block": "10.0.160.0/19", + "customer_owned_ipv4_pool": "", + "enable_dns64": false, + "enable_lni_at_device_index": 0, + "enable_resource_name_dns_a_record_on_launch": false, + "enable_resource_name_dns_aaaa_record_on_launch": false, + "id": "subnet-02fb98c38c541a8d8", + "ipv6_cidr_block": "", + "ipv6_cidr_block_association_id": "", + "ipv6_native": false, + "map_customer_owned_ip_on_launch": false, + "map_public_ip_on_launch": false, + "outpost_arn": "", + "owner_id": "027423573553", + "private_dns_hostname_type_on_launch": "ip-name", + "tags": { + "Name": "observability-stack-public-us-west-2c", + "kubernetes.io/role/elb": "1" + }, + "tags_all": { + "ManagedBy": "terraform", + "Name": "observability-stack-public-us-west-2c", + "Project": "observability-stack", + "kubernetes.io/role/elb": "1" + }, + "timeouts": null, + "vpc_id": "vpc-03aefcf5aa0581d7a" + }, + "sensitive_attributes": [], + "private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjo2MDAwMDAwMDAwMDAsImRlbGV0ZSI6MTIwMDAwMDAwMDAwMH0sInNjaGVtYV92ZXJzaW9uIjoiMSJ9", + "dependencies": [ + "data.aws_availability_zones.available", + "module.vpc.aws_vpc.this", + "module.vpc.aws_vpc_ipv4_cidr_block_association.this" + ] + } + ] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_subnet", + "name": "redshift", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_vpc", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [ + { + "index_key": 0, + "schema_version": 1, + "attributes": { + "arn": "arn:aws:ec2:us-west-2:027423573553:vpc/vpc-03aefcf5aa0581d7a", + "assign_generated_ipv6_cidr_block": false, + "cidr_block": "10.0.0.0/16", + "default_network_acl_id": "acl-0a5e114c086bba3b7", + "default_route_table_id": "rtb-0eb0c8a9b7385e199", + "default_security_group_id": "sg-01804f6e1f144e984", + "dhcp_options_id": "dopt-092ebbc7273e1297b", + "enable_dns_hostnames": true, + "enable_dns_support": true, + "enable_network_address_usage_metrics": false, + "id": "vpc-03aefcf5aa0581d7a", + "instance_tenancy": "default", + "ipv4_ipam_pool_id": null, + "ipv4_netmask_length": null, + "ipv6_association_id": "", + "ipv6_cidr_block": "", + "ipv6_cidr_block_network_border_group": "", + "ipv6_ipam_pool_id": "", + "ipv6_netmask_length": 0, + "main_route_table_id": "rtb-0eb0c8a9b7385e199", + "owner_id": "027423573553", + "tags": { + "Name": "observability-stack" + }, + "tags_all": { + "ManagedBy": "terraform", + "Name": "observability-stack", + "Project": "observability-stack" + } + }, + "sensitive_attributes": [], + "private": "eyJzY2hlbWFfdmVyc2lvbiI6IjEifQ==", + "create_before_destroy": true + } + ] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_vpc_block_public_access_exclusion", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_vpc_block_public_access_options", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_vpc_dhcp_options", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_vpc_dhcp_options_association", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_vpc_ipv4_cidr_block_association", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_vpn_gateway", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_vpn_gateway_attachment", + "name": "this", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_vpn_gateway_route_propagation", + "name": "intra", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_vpn_gateway_route_propagation", + "name": "private", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + }, + { + "module": "module.vpc", + "mode": "managed", + "type": "aws_vpn_gateway_route_propagation", + "name": "public", + "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]", + "instances": [] + } + ], + "check_results": [ + { + "object_kind": "resource", + "config_addr": "module.eks.module.eks_managed_node_group.module.user_data.null_resource.validate_cluster_service_cidr", + "status": "unknown", + "objects": [ + { + "object_addr": "module.eks.module.eks_managed_node_group[\"default\"].module.user_data.null_resource.validate_cluster_service_cidr", + "status": "unknown" + } + ] + }, + { + "object_kind": "resource", + "config_addr": "module.eks.module.self_managed_node_group.module.user_data.null_resource.validate_cluster_service_cidr", + "status": "pass", + "objects": null + } + ] +} diff --git a/terraform/aws/terraform.tfvars.example b/terraform/aws/terraform.tfvars.example new file mode 100644 index 00000000..5f5ea787 --- /dev/null +++ b/terraform/aws/terraform.tfvars.example @@ -0,0 +1,13 @@ +# All optional. Just `terraform apply` for a working stack on plain HTTP. +# Uncomment domain + route53_zone_id to enable HTTPS. + +# domain = "obs.example.com" +# route53_zone_id = "Z0123456789ABCDEFGHIJ" + +# region = "us-west-2" +# cluster_name = "observability-stack" +# node_instance_type = "m5.xlarge" +# node_count = 2 +# enable_waf = false +# anonymous_auth = false +# enable_examples = false diff --git a/terraform/aws/values-eks.yaml b/terraform/aws/values-eks.yaml new file mode 100644 index 00000000..754f2fc2 --- /dev/null +++ b/terraform/aws/values-eks.yaml @@ -0,0 +1,75 @@ +# EKS-specific overrides for the observability-stack helm chart. +# Used by: helm upgrade obs-stack ... -f values-eks.yaml +# Used by: terraform/aws/observability-stack.tf (via values = [file(...)]) +# +# TLS annotations (certificate-arn, listen-ports, ssl-redirect, hostname) +# are injected conditionally by Terraform via dynamic set blocks — not here. + +# gp2 is the default EBS StorageClass on EKS. Without this, OpenSearch PVCs +# stay Pending because the chart default ("") doesn't match any provisioner. +opensearch: + singleNode: false + replicas: 3 + persistence: + storageClass: gp2 + resources: + requests: + memory: "4Gi" + cpu: "2000m" + limits: + memory: "4Gi" + cpu: "4000m" + extraEnvs: + - name: OPENSEARCH_INITIAL_ADMIN_PASSWORD + value: "My_password_123!@#" + - name: OPENSEARCH_JAVA_OPTS + value: "-Xms2g -Xmx2g" + +opensearch-dashboards: + replicaCount: 3 + resources: + requests: + cpu: "500m" + memory: "1Gi" + limits: + cpu: "2000m" + memory: "2Gi" + ingress: + enabled: true + ingressClassName: alb + annotations: + alb.ingress.kubernetes.io/scheme: internet-facing + alb.ingress.kubernetes.io/target-type: ip + alb.ingress.kubernetes.io/listen-ports: '[{"HTTP":80}]' # Terraform overrides to HTTPS:443 when domain is set + hosts: + - host: "" + paths: + - path: / + backend: + servicePort: 5601 + +# Examples — pulls from GHCR (public images built by .github/workflows/publish-images.yml) +examples: + enabled: false + +# Prometheus — persistent storage + resource limits +prometheus: + server: + persistentVolume: + enabled: true + size: 50Gi + resources: + requests: + memory: "2Gi" + cpu: "500m" + limits: + memory: "4Gi" + cpu: "1000m" + +# OTel Demo — realistic telemetry from ~20 microservices +opentelemetry-demo: + enabled: false + +# Gateway not needed — ALB handles ingress directly. +gateway: + enabled: false diff --git a/terraform/aws/variables.tf b/terraform/aws/variables.tf new file mode 100644 index 00000000..e015e040 --- /dev/null +++ b/terraform/aws/variables.tf @@ -0,0 +1,89 @@ +# ============================================================================ +# No required variables. Just `terraform apply` for a working stack. +# Add domain + route53_zone_id when ready for TLS/DNS. +# ============================================================================ + +variable "region" { + description = "AWS region" + type = string + default = "us-west-2" +} + +variable "cluster_name" { + description = "EKS cluster name" + type = string + default = "observability-stack" +} + +variable "kubernetes_version" { + description = "EKS Kubernetes version" + type = string + default = "1.32" +} + +variable "node_instance_type" { + description = "EC2 instance type for EKS nodes" + type = string + default = "m5.xlarge" +} + +variable "node_count" { + description = "Number of EKS worker nodes" + type = number + default = 2 +} + +# ============================================================================ +# TLS / DNS — optional. Set both to enable HTTPS + custom domain. +# ============================================================================ + +variable "domain" { + description = "Domain name for OpenSearch Dashboards (e.g. obs.example.com). Leave empty for plain HTTP on ALB." + type = string + default = "" +} + +variable "route53_zone_id" { + description = "Route53 hosted zone ID. Required when domain is set." + type = string + default = "" +} + +# ============================================================================ +# Security — off by default for initial smoke test +# ============================================================================ + +variable "enable_waf" { + description = "Enable WAF rate limiting on the ALB (2000 req/5min/IP)" + type = bool + default = false +} + +variable "anonymous_auth" { + description = "Enable anonymous read-only access to OpenSearch Dashboards (for public demos)" + type = bool + default = false +} + +variable "enable_examples" { + description = "Deploy example agent services (weather-agent, travel-planner, canary)" + type = bool + default = false +} + +variable "tags" { + description = "Tags applied to all resources" + type = map(string) + default = { + Project = "observability-stack" + ManagedBy = "terraform" + } +} + +# ============================================================================ +# Derived +# ============================================================================ + +locals { + enable_tls = var.domain != "" && var.route53_zone_id != "" +} diff --git a/test/helm-test.sh b/test/helm-test.sh new file mode 100755 index 00000000..455683c2 --- /dev/null +++ b/test/helm-test.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +# Helm lint + unit tests for the observability-stack chart. +# Requires: helm, helm-unittest plugin (helm plugin install https://github.com/helm-unittest/helm-unittest.git) +# Usage: ./test/helm-test.sh +set -euo pipefail + +CHART="charts/observability-stack" + +echo "==> helm lint" +helm lint "$CHART" + +echo "" +echo "==> helm unittest" +helm unittest "$CHART"