{"id":24041940,"url":"https://github.com/extensionengine/infra-code-blocks","last_synced_at":"2026-06-10T13:00:36.195Z","repository":{"id":197929819,"uuid":"699330912","full_name":"ExtensionEngine/infra-code-blocks","owner":"ExtensionEngine","description":"Studion common infra components","archived":false,"fork":false,"pushed_at":"2026-06-09T12:03:52.000Z","size":1539,"stargazers_count":14,"open_issues_count":16,"forks_count":2,"subscribers_count":5,"default_branch":"master","last_synced_at":"2026-06-09T14:06:05.829Z","etag":null,"topics":["infrastructure","infrastructure-as-code","pulumi","studion"],"latest_commit_sha":null,"homepage":"https://github.com/ExtensionEngine/infra-code-blocks/blob/master/README.md","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ExtensionEngine.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-10-02T12:27:43.000Z","updated_at":"2026-06-09T12:04:33.000Z","dependencies_parsed_at":"2025-04-08T19:41:12.819Z","dependency_job_id":"3ecb1bd9-f06d-4249-aad5-d14c4e567383","html_url":"https://github.com/ExtensionEngine/infra-code-blocks","commit_stats":{"total_commits":122,"total_committers":4,"mean_commits":30.5,"dds":"0.10655737704918034","last_synced_commit":"ae46742e6b3e5966a983cbc89cee3aa06d4aa2bc"},"previous_names":["extensionengine/infra-code-blocks"],"tags_count":63,"template":false,"template_full_name":null,"purl":"pkg:github/ExtensionEngine/infra-code-blocks","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ExtensionEngine%2Finfra-code-blocks","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ExtensionEngine%2Finfra-code-blocks/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ExtensionEngine%2Finfra-code-blocks/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ExtensionEngine%2Finfra-code-blocks/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ExtensionEngine","download_url":"https://codeload.github.com/ExtensionEngine/infra-code-blocks/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ExtensionEngine%2Finfra-code-blocks/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34153483,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-10T02:00:07.152Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["infrastructure","infrastructure-as-code","pulumi","studion"],"created_at":"2025-01-08T22:14:02.208Z","updated_at":"2026-06-10T13:00:36.177Z","avatar_url":"https://github.com/ExtensionEngine.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# `@studion/infra-code-blocks`\n\n[![npm version](https://img.shields.io/npm/v/@studion/infra-code-blocks)](https://www.npmjs.com/package/@studion/infra-code-blocks)\n[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n[![CircleCI](https://dl.circleci.com/status-badge/img/gh/ExtensionEngine/infra-code-blocks/tree/master.svg?style=shield)](https://dl.circleci.com/status-badge/redirect/gh/ExtensionEngine/infra-code-blocks/tree/master)\n\nOpinionated TypeScript building blocks for Pulumi-based AWS infrastructure.\n\n\u003e Deploying examples or components can create billable AWS resources. Preview changes before deploying and run `pulumi destroy` when resources are no longer needed.\n\n## Table of contents\n\n- [Overview](#overview)\n- [Quick start](#quick-start)\n- [Usage](#usage)\n- [SSM Connect](#ssm-connect)\n- [API reference](#api-reference)\n- [Development](#development)\n- [Contributing](#contributing)\n- [Troubleshooting](#troubleshooting)\n- [License](#license)\n\n## Overview\n\n`@studion/infra-code-blocks` provides reusable Pulumi components for common AWS infrastructure patterns used in Studion projects.\n\n### When to use this package\n\nUse this package when you want to:\n\n- provision common AWS infrastructure patterns without rewriting Pulumi boilerplate\n- standardize networking, compute, data, and observability setup across multiple services\n- compose higher-level infrastructure from opinionated building blocks instead of low-level resources\n\nThis package is most useful for teams already working with Pulumi, AWS, and TypeScript.\n\n### Scope\n\nThe package provides building blocks across four areas:\n\n| Area                    | What it covers                                                             | Typical entry points                                                                                              |\n| ----------------------- | -------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |\n| Networking and delivery | VPCs, ACM certificates, CloudFront, and static hosting                     | `Vpc`, `AcmCertificate`, `CloudFront`, `StaticSite`, `S3Assets`                                                   |\n| Compute                 | Generic ECS services and ALB-backed web services                           | `EcsService`, `WebServer`, `WebServerBuilder`, `WebServerLoadBalancer`                                            |\n| Data                    | PostgreSQL, replicas, SSM access helpers, Redis, and password storage      | `Database`, `DatabaseBuilder`, `DatabaseReplica`, `Ec2SSMConnect`, `ElastiCacheRedis`, `UpstashRedis`, `Password` |\n| Observability           | OpenTelemetry collector integration, Grafana resources, and PromQL helpers | `OtelCollector`, `OtelCollectorBuilder`, `grafana`, `prometheus`                                                  |\n\n## Quick start\n\n### Prerequisites\n\n**Required for all usage**\n\n- Node.js 20 or newer and npm.\n- A Pulumi TypeScript project. If you do not already have one, `pulumi new aws-typescript` is a suitable starting point.\n\n**Required for AWS deployment**\n\n- Pulumi CLI authenticated with `pulumi login`.\n- AWS credentials with permissions for the resources you create.\n- Pulumi AWS provider region configuration, for example `pulumi config set aws:region eu-central-1` (environment: `AWS_REGION`). Region-aware components use an explicit component `region` when provided and otherwise derive the region from the active AWS provider.\n\n**Required only for ECS/web-service components**\n\n- An ECS cluster when using `EcsService`, `WebServer`, or `WebServerBuilder`.\n\n**Required only for DNS/TLS/static-site/custom-domain components**\n\n- A Route 53 hosted zone.\n- A domain name managed by or delegated to that hosted zone.\n\n**Required only for database and SSM Connect components**\n\n- Private or isolated subnets from this package's `Vpc` component or a compatible AWSX VPC.\n- AWS CLI and the Session Manager plugin when opening local SSM tunnels.\n\n**Required only for Grafana components**\n\n- Grafana Cloud stack URL configured as Pulumi config `grafana:url` or environment variable `GRAFANA_URL`, for example `https://\u003cstack\u003e.grafana.net`.\n- Grafana Cloud access policy token configured for the Grafana provider as Pulumi config `grafana:cloudAccessPolicyToken` or environment variable `GRAFANA_CLOUD_ACCESS_POLICY_TOKEN`.\n- Initial Grafana Cloud token scopes: `accesspolicies:read`, `accesspolicies:write`, `accesspolicies:delete`, `stacks:read`, and `stack-service-accounts:write`.\n- The access policy managed by this package includes the scopes needed for data sources, dashboards, and plugins.\n\n**Required only for Upstash components**\n\n- Pulumi config value `upstash:apiKey` (environment: `UPSTASH_API_KEY`).\n- Pulumi config value `upstash:email` (environment: `UPSTASH_EMAIL`).\n\n### Install\n\n```bash\nnpm install @studion/infra-code-blocks\n```\n\n### Minimal deploy flow\n\nUse this flow in a new directory if you want the shortest domain-free path from a Pulumi project to a deployed resource:\n\n```bash\npulumi new aws-typescript\nnpm install @studion/infra-code-blocks\npulumi config set aws:region eu-central-1\n```\n\nAdd a minimal VPC to your Pulumi program:\n\n```ts\nimport * as studion from '@studion/infra-code-blocks';\n\nconst vpc = new studion.Vpc('app');\n\nexport const vpcId = vpc.vpc.vpcId;\n```\n\nPreview, deploy, and clean up when finished:\n\n```bash\npulumi up\npulumi destroy\n```\n\nThis example avoids Route 53 and ACM, but creating a VPC can still create billable AWS resources such as NAT gateways depending on provider defaults and region.\n\n### Typical next steps\n\n1. Start with a foundation resource such as `Vpc`.\n2. Add higher-level components such as `WebServer`, `Database`, `ElastiCacheRedis`, or `StaticSite`.\n3. Export the resulting IDs, ARNs, hostnames, or endpoints from your stack.\n4. Use `pulumi preview` before deploying and `pulumi destroy` for cleanup in temporary environments.\n\n## Usage\n\n### Create a VPC and ACM certificate\n\nUse this example when your stack already has a public Route 53 hosted zone and you need a DNS-validated certificate:\n\n```ts\nimport * as aws from '@pulumi/aws';\nimport * as studion from '@studion/infra-code-blocks';\n\nconst hostedZone = aws.route53.getZoneOutput({\n  name: 'example.com',\n  privateZone: false,\n});\n\nconst vpc = new studion.Vpc('app');\n\nconst certificate = new studion.AcmCertificate('app-cert', {\n  domain: 'app.example.com',\n  hostedZoneId: hostedZone.zoneId,\n});\n\nexport const vpcId = vpc.vpc.vpcId;\nexport const certificateArn = certificate.certificate.arn;\n```\n\n### Create an ECS web service with OpenTelemetry\n\nThis example creates the surrounding AWS resources required by the web service instrumentation: a VPC, ECS cluster, CloudWatch log group, and AWS Managed Service for Prometheus workspace. It also expects the AWS provider region to be configured through `aws:region` or `AWS_REGION`.\n\n```ts\nimport * as aws from '@pulumi/aws';\nimport * as pulumi from '@pulumi/pulumi';\nimport * as studion from '@studion/infra-code-blocks';\n\nconst env = pulumi.getStack();\nconst vpc = new studion.Vpc('app');\nconst cluster = new aws.ecs.Cluster('app-cluster', {});\nconst logGroup = new aws.cloudwatch.LogGroup('app-otel-logs', {});\nconst workspace = new aws.amp.Workspace('app-amp', {});\n\nconst otelCollector = new studion.OtelCollectorBuilder('app', env)\n  .withDefault({\n    prometheusNamespace: 'app',\n    prometheusWorkspace: workspace,\n    region: aws.config.requireRegion(),\n    logGroup,\n    logStreamName: 'app',\n  })\n  .build();\n\nconst web = new studion.WebServerBuilder('app')\n  .withContainer('nginx:stable', 80, {\n    environment: [\n      { name: 'OTEL_SERVICE_NAME', value: 'app' },\n      { name: 'OTEL_EXPORTER_OTLP_ENDPOINT', value: 'http://127.0.0.1:4318' },\n      { name: 'OTEL_EXPORTER_OTLP_PROTOCOL', value: 'http/json' },\n    ],\n  })\n  .withEcsConfig({\n    cluster,\n    desiredCount: 1,\n    size: 'small',\n    autoscaling: { enabled: false },\n  })\n  .withVpc(vpc.vpc)\n  .withOtelCollector(otelCollector)\n  .build();\n\nexport const webServiceName = web.service.apply(\n  ecsService =\u003e ecsService.service.name,\n);\n```\n\n## SSM Connect\n\n`Database` instances are deployed inside isolated subnets and are not publicly reachable. When you need operator access for migrations, debugging, or a desktop database client, this package can provision an `Ec2SSMConnect` helper host that stays private and is reachable through AWS Systems Manager.\n\nThis workflow reuses the helper EC2 instance plus the SSM, EC2 Messages, and SSM Messages VPC interface endpoints created by the component, so you do not need a bastion with a public IP or SSH key pair. The helper instance itself accepts SSH only from within the VPC, while your local machine connects through an SSM session.\n\n![AWS RDS connection schema](https://raw.githubusercontent.com/ExtensionEngine/infra-code-blocks/master/assets/images/ssm-rds.png)\n\n### Prerequisites\n\n1. Install the AWS CLI and the [Session Manager plugin](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html).\n2. Ensure an AWS region is available. `Ec2SSMConnect` uses explicit `region` when provided and otherwise derives the region from the active AWS provider for region-specific VPC endpoint service names.\n3. Provision a `Database` with SSM helper access enabled.\n\n### Enable SSM access\n\nUse the database builder when you want the database and helper instance created together:\n\n```ts\nimport * as studion from '@studion/infra-code-blocks';\n\nconst vpc = new studion.Vpc('platform');\n\nconst database = new studion.DatabaseBuilder('platform-db')\n  .withVpc(vpc.vpc)\n  .withInstance({ dbName: 'platform' })\n  .withCredentials({ username: 'platform_user' })\n  .withSSMConnect({ instanceType: 't4g.small' })\n  .build();\n\nexport const databaseAddress = database.instance.address;\nexport const databasePort = database.instance.port;\nexport const ssmHostId = database.ec2SSMConnect!.ec2.id;\n```\n\nYou can also provision `Ec2SSMConnect` directly when you want a standalone helper host for an existing VPC:\n\n```ts\nimport * as studion from '@studion/infra-code-blocks';\n\nconst vpc = new studion.Vpc('platform');\n\nconst ssmConnect = new studion.Ec2SSMConnect('platform-db-ssm', {\n  vpc: vpc.vpc,\n  instanceType: 't4g.small',\n});\n\nexport const ssmHostId = ssmConnect.ec2.id;\n```\n\n### Open the tunnel\n\nExport the stack outputs into local shell variables:\n\n```bash\nexport SSM_HOST_ID=$(pulumi stack output ssmHostId)\nexport DATABASE_ADDRESS=$(pulumi stack output databaseAddress)\nexport DATABASE_PORT=$(pulumi stack output databasePort)\n```\n\nStart a single SSM port-forwarding session from your laptop to the private database through the helper instance:\n\n```bash\naws ssm start-session --target \"$SSM_HOST_ID\" --document-name AWS-StartPortForwardingSessionToRemoteHost --parameters \"{\\\"host\\\":[\\\"$DATABASE_ADDRESS\\\"],\\\"portNumber\\\":[\\\"$DATABASE_PORT\\\"],\\\"localPortNumber\\\":[\\\"5555\\\"]}\"\n```\n\nWhere:\n\n- `SSM_HOST_ID` is the exported EC2 instance ID from `database.ec2SSMConnect.ec2.id` or `ssmConnect.ec2.id`.\n- `DATABASE_ADDRESS` is the RDS endpoint, for example `database.instance.address`.\n- `DATABASE_PORT` is the RDS port, for example `database.instance.port`.\n\nKeep that command running, then connect your database client to `localhost:5555` using the same database name, username, and password you configured for the `Database` component. The examples above do not export database credentials automatically.\n\n![RDS connection](https://raw.githubusercontent.com/ExtensionEngine/infra-code-blocks/master/assets/images/rds-connection.png)\n\n## API reference\n\n| Export                  | Kind      | Use it for                                     | Docs                                                        |\n| ----------------------- | --------- | ---------------------------------------------- | ----------------------------------------------------------- |\n| `Vpc`                   | class     | Standard AWSX VPC with fixed subnet ordering.  | [vpc](src/components/vpc/README.md)                         |\n| `AcmCertificate`        | class     | ACM certificate with Route 53 DNS validation.  | [acm-certificate](src/components/acm-certificate/README.md) |\n| `EcsService`            | class     | Generic ECS/Fargate service composition.       | [ecs-service](src/components/ecs-service/README.md)         |\n| `WebServer`             | class     | ALB-backed ECS web service.                    | [web-server](src/components/web-server/README.md)           |\n| `WebServerBuilder`      | class     | Fluent builder for `WebServer`.                | [web-server](src/components/web-server/README.md)           |\n| `WebServerLoadBalancer` | class     | Standalone ALB and target group.               | [web-server](src/components/web-server/README.md)           |\n| `Database`              | class     | PostgreSQL primary instance with extras.       | [database](src/components/database/README.md)               |\n| `DatabaseBuilder`       | class     | Fluent builder for `Database`.                 | [database](src/components/database/README.md)               |\n| `DatabaseReplica`       | class     | PostgreSQL read replica.                       | [database](src/components/database/README.md)               |\n| `Ec2SSMConnect`         | class     | Private EC2 helper reachable through SSM.      | [database](src/components/database/README.md)               |\n| `ElastiCacheRedis`      | class     | VPC-scoped Redis on ElastiCache.               | [redis](src/components/redis/README.md)                     |\n| `UpstashRedis`          | class     | Managed Redis on Upstash.                      | [redis](src/components/redis/README.md)                     |\n| `Password`              | class     | Secret-backed password generation and storage. | [password](src/components/password/README.md)               |\n| `CloudFront`            | class     | Behavior-driven CloudFront distribution.       | [cloudfront](src/components/cloudfront/README.md)           |\n| `StaticSite`            | class     | S3 website plus CloudFront composition.        | [static-site](src/components/static-site/README.md)         |\n| `S3Assets`              | class     | Public S3 website bucket for static assets.    | [static-site](src/components/static-site/README.md)         |\n| `OtelCollector`         | class     | ECS-side collector container generation.       | [otel](src/otel/README.md)                                  |\n| `OtelCollectorBuilder`  | class     | Fluent builder for OTel collector sidecars.    | [otel](src/otel/README.md)                                  |\n| `grafana`               | namespace | Grafana folders, data sources, and dashboards. | [grafana](src/components/grafana/README.md)                 |\n| `prometheus`            | namespace | PromQL query helpers for SLOs and latency.     | [prometheus](src/components/prometheus/README.md)           |\n\n## Development\n\nThese steps are for contributors developing this package, not for consumers using it in a Pulumi project.\n\n### Prerequisites\n\n- Install dependencies with `npm install`.\n- Install the AWS and Pulumi CLIs.\n- Configure AWS credentials, preferably with an `AWS_PROFILE` that uses SSO.\n- Authenticate Pulumi with `pulumi login`.\n- Set these environment variables when running the full test suite; all are required for the complete integration/E2E suite:\n  - `AWS_REGION`\n  - `ICB_DOMAIN_NAME`\n  - `ICB_HOSTED_ZONE_ID`\n  - `GRAFANA_AWS_ACCOUNT_ID`\n  - `GRAFANA_CLOUD_ACCESS_POLICY_TOKEN`\n  - `GRAFANA_URL`\n  - `UPSTASH_API_KEY`\n  - `UPSTASH_EMAIL`\n\n### Commands\n\n```bash\nnpm run build                                        # Compile the package into dist/\nnpm run format                                       # Format code using Prettier\nnpm run test                                         # Run the integration/E2E test suite\nnpm run test -- tests/\u003ccomponent-name\u003e/index.test.ts # Run integration/E2E tests for specific component(s)\nnpm run test:build                                   # Run build validation and type-level checks\n```\n\n## Contributing\n\nContributions should keep the documentation and exported API aligned.\n\n1. Install dependencies with `npm install`.\n2. Make your changes in `src/` and update any affected README files.\n3. Add or update integration/E2E tests and run `npm run test -- tests/\u003ccomponent-name\u003e/index.test.ts` when your change affects infrastructure behavior.\n4. Add or update build-level tests and run `npm run test:build` when your change affects public API.\n5. The pre-commit hook will automatically format code before committing, or you can run `npm run format` manually.\n\n## Troubleshooting\n\n- **Missing AWS region or provider-region error:** configure the AWS provider region, for example with `pulumi config set aws:region \u003cregion\u003e` or `AWS_REGION`, or pass an explicit component `region` where supported.\n- **AWS credentials, profile, or authorization errors:** configure AWS credentials, set the intended `AWS_PROFILE`, and confirm the identity has the required permissions.\n- **Route 53 validation or custom-domain setup failure:** confirm that the domain is managed by, or delegated to, the hosted zone whose ID you passed to the component.\n- **ACM certificate validation appears stuck:** DNS validation can take time. Check that the generated Route 53 validation record exists in the public hosted zone.\n- **`aws ssm start-session` fails before opening a tunnel:** install the Session Manager plugin, verify `SSM_HOST_ID`, and confirm the helper instance is managed by Systems Manager.\n- **Grafana authentication or authorization errors:** check `grafana:cloudAccessPolicyToken`, `grafana:url`, and the required access-policy scopes.\n- **Upstash provider authentication errors:** check `upstash:apiKey` and `upstash:email`.\n- **CloudFront or static-site deployments appear slow:** CloudFront distribution creation and updates commonly take several minutes.\n\n## License\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fextensionengine%2Finfra-code-blocks","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fextensionengine%2Finfra-code-blocks","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fextensionengine%2Finfra-code-blocks/lists"}