AlphaMoatによると、2026-09時点でInfrastructure as Codeのダウンロード数は4,265、スター数は1で、AIスキル全体5,078件中2,319位、IT運用・セキュリティでは264件中132位です。
| プラットフォーム | インストール数 | ダウンロード数 | スター数 | コメント |
|---|---|---|---|---|
| ClawHub ↗ | 143 | 3974 | 1 | - |
| SkillHub ↗ | 177 | 4265 | 1 | — |
プラットフォームごとに集計方法と集計時点が異なります。
文書では、Terraform、CloudFormation、Pulumiを使った計算、ネットワーク、ストレージ、データベース、状態管理、デプロイ計画を扱います。デプロイや状態変更は本番資源に影響する可能性があります。計画をプレビューし、環境と状態を確認して、承認後に実行してください。
資料公開日 2026-10-27
スキルのドキュメントをもとに生成した例であり、実際の実行結果ではありません。
2026-09 から集計方法を変更し、同名スキルを作者ごとに分けて集計し、全スキルを対象にしました。破線は変更前の月で、変更後のデータとは直接比較せず、変更をまたぐ増減も計算していません。
| 月 | ダウンロード数 | 前月比 | スター数 |
|---|---|---|---|
| 2026-09 | 4265 | — | 1 |
| 2026-08 | 4037 | +1.7% | 1 |
| 2026-07 | 3970 | +4.1% | 1 |
| 2026-06 | 3815 | +3.9% | 1 |
| 2026-05 | 3671 | — | 1 |
| 2026-03 | 3101 | — | 1 |
作者が公開した元のファイルをテキストのまま表示しています。AlphaMoat による編集や審査はしていません。リンクはクリックできません。コマンドは内容を確認してから実行してください。取得日 2026-10-23。
---
name: infra-as-code
description: Define and manage cloud infrastructure with code. Use when writing Terraform, CloudFormation, or Pulumi configs, managing state, planning deployments, setting up networking/compute/storage resources, or debugging infrastructure drift.
metadata: {"clawdbot":{"emoji":"🏗️","requires":{"anyBins":["terraform","aws","pulumi"]},"os":["linux","darwin","win32"]}}
---
# Infrastructure as Code
Define, deploy, and manage cloud infrastructure using declarative configuration. Covers Terraform (multi-cloud), AWS CloudFormation, and Pulumi (code-first), with patterns for compute, networking, storage, databases, and state management.
## When to Use
- Setting up cloud infrastructure (VPCs, EC2, Lambda, S3, RDS, etc.)
- Writing or modifying Terraform configurations
- Managing Terraform state (remote backends, workspaces, imports)
- Creating CloudFormation templates
- Using Pulumi for infrastructure in TypeScript/Python/Go
- Planning and previewing infrastructure changes safely
- Debugging drift between declared state and actual resources
- Setting up multi-environment deployments (dev/staging/prod)
## Terraform
### Quick Start
```bash
# Install: https://developer.hashicorp.com/terraform/install
# Initialize a project
mkdir infra && cd infra
terraform init
# Core workflow
terraform plan # Preview changes (safe, read-only)
terraform apply # Apply changes (creates/modifies resources)
terraform destroy # Tear down all resources
# Format and validate
terraform fmt -recursive # Auto-format all .tf files
terraform validate # Check syntax and config validity
```
### Project Structure
```
infra/
main.tf # Primary resources
variables.tf # Input variable declarations
outputs.tf # Output values
providers.tf # Provider configuration
terraform.tfvars # Variable values (don't commit secrets)
backend.tf # Remote state configuration
modules/
vpc/
main.tf
variables.tf
outputs.tf
compute/
main.tf
variables.tf
outputs.tf
```
### Provider Configuration
```hcl
# providers.tf
terraform {
required_version = ">= 1.5"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = var.aws_region
default_tags {
tags = {
Project = var.project_name
Environment = var.environment
ManagedBy = "terraform"
}
}
}
```
### Variables and Outputs
```hcl
# variables.tf
variable "aws_region" {
type = string
default = "us-east-1"
description = "AWS region for all resources"
}
variable "environment" {
type = string
description = "Deployment environment"
validation {
condition = contains(["dev", "staging", "prod"], var.environment)
error_message = "Environment must be dev, staging, or prod."
}
}
variable "instance_type" {
type = string
default = "t3.micro"
}
variable "db_password" {
type = string
sensitive = true
description = "Database password (pass via TF_VAR_db_password env var)"
}
# outputs.tf
output "vpc_id" {
value = aws_vpc.main.id
description = "VPC ID"
}
output "api_endpoint" {
value = aws_lb.api.dns_name
}
```
### VPC + Networking
```hcl
# Networking module
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_support = true
enable_dns_hostnames = true
tags = { Name = "${var.project_name}-vpc" }
}
resource "aws_subnet" "public" {
count = 2
vpc_id = aws_vpc.main.id
cidr_block = "10.0.${count.index + 1}.0/24"
availability_zone = data.aws_availability_zones.available.names[count.index]
map_public_ip_on_launch = true
tags = { Name = "${var.project_name}-public-${count.index + 1}" }
}
resource "aws_subnet" "private" {
count = 2
vpc_id = aws_vpc.main.id
cidr_block = "10.0.${count.index + 10}.0/24"
availability_zone = data.aws_availability_zones.available.names[count.index]
tags = { Name = "${var.project_name}-private-${count.index + 1}" }
}
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
}
resource "aws_route_table" "public" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.main.id
}
}
resource "aws_route_table_association" "public" {
count = 2
subnet_id = aws_subnet.public[count.index].id
route_table_id = aws_route_table.public.id
}
resource "aws_security_group" "web" {
name_prefix = "${var.project_name}-web-"
vpc_id = aws_vpc.main.id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
data "aws_availability_zones" "available" {
state = "available"
}
```
### Compute (EC2)
```hcl
resource "aws_instance" "app" {
ami = data.aws_ami.ubuntu.id
instance_type = var.instance_type
subnet_id = aws_subnet.public[0].id
vpc_security_group_ids = [aws_security_group.web.id]
key_name = var.key_pair_name
user_data = <<-EOF
#!/bin/bash
apt-get update
apt-get install -y docker.io
systemctl start docker
docker run -d -p 80:8080 ${var.docker_image}
EOF
tags = { Name = "${var.project_name}-app" }
}
data "aws_ami" "ubuntu" {
most_recent = true
owners = ["099720109477"] # Canonical
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-*-24.04-amd64-server-*"]
}
}
```
### S3 + Static Website
```hcl
resource "aws_s3_bucket" "website" {
bucket = "${var.project_name}-website"
}
resource "aws_s3_bucket_website_configuration" "website" {
bucket = aws_s3_bucket.website.id
index_document { suffix = "index.html" }
error_document { key = "error.html" }
}
resource "aws_s3_bucket_public_access_block" "website" {
bucket = aws_s3_bucket.website.id
block_public_acls = false
block_public_policy = false
ignore_public_acls = false
restrict_public_buckets = false
}
resource "aws_s3_bucket_policy" "website" {
bucket = aws_s3_bucket.website.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Sid = "PublicRead"
Effect = "Allow"
Principal = "*"
Action = "s3:GetObject"
Resource = "${aws_s3_bucket.website.arn}/*"
}]
})
depends_on = [aws_s3_bucket_public_access_block.website]
}
```
### RDS Database
```hcl
resource "aws_db_subnet_group" "main" {
name = "${var.project_name}-db"
subnet_ids = aws_subnet.private[*].id
}
resource "aws_security_group" "db" {
name_prefix = "${var.project_name}-db-"
vpc_id = aws_vpc.main.id
ingress {
from_port = 5432
to_port = 5432
protocol = "tcp"
security_groups = [aws_security_group.web.id]
}
}
resource "aws_db_instance" "main" {
identifier = "${var.project_name}-db"
engine = "postgres"
engine_version = "16.1"
instance_class = "db.t3.micro"
allocated_storage = 20
db_name = var.db_name
username = var.db_username
password = var.db_password
db_subnet_group_name = aws_db_subnet_group.main.name
vpc_security_group_ids = [aws_security_group.db.id]
backup_retention_period = 7
skip_final_snapshot = var.environment != "prod"
deletion_protection = var.environment == "prod"
}
```
### Lambda Function
```hcl
data "archive_file" "lambda_zip" {
type = "zip"
source_dir = "${path.module}/lambda"
output_path = "${path.module}/lambda.zip"
}
resource "aws_lambda_function" "api" {
function_name = "${var.project_name}-api"
filename = data.archive_file.lambda_zip.output_path
source_code_hash = data.archive_file.lambda_zip.output_base64sha256
handler = "index.handler"
runtime = "nodejs20.x"
timeout = 30
role = aws_iam_role.lambda_exec.arn
environment {
variables = {
DB_HOST = aws_db_instance.main.endpoint
ENVIRONMENT = var.environment
}
}
}
resource "aws_iam_role" "lambda_exec" {
name = "${var.project_name}-lambda-exec"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = { Service = "lambda.amazonaws.com" }
}]
})
}
resource "aws_iam_role_policy_attachment" "lambda_basic" {
role = aws_iam_role.lambda_exec.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}
```
### State Management
```hcl
# backend.tf - Remote state in S3
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "project/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-locks"
encrypt = true
}
}
```
```bash
# State operations
terraform state list # List all resources in state
terraform state show aws_instance.app # Show resource details
terraform state mv aws_instance.app aws_instance.web # Rename resource
terraform state rm aws_instance.old # Remove from state (doesn't destroy)
# Import existing resource into Terraform
terraform import aws_instance.app i-1234567890abcdef0
# Workspaces (multiple environments, same config)
terraform workspace new dev
terraform workspace new staging
terraform workspace new prod
terraform workspace select dev
terraform workspace list
```
### Multi-Environment Pattern
```hcl
# Use workspaces + tfvars files
# terraform.tfvars (default)
# env/dev.tfvars
# env/staging.tfvars
# env/prod.tfvars
# Apply for specific environment
# terraform apply -var-file=env/prod.tfvars
```
```bash
# Environment-specific apply
ENV=${1:-dev}
terraform workspace select "$ENV" || terraform workspace new "$ENV"
terraform apply -var-file="env/$ENV.tfvars"
```
## AWS CloudFormation
### Template Structure
```yaml
# cloudformation.yaml
AWSTemplateFormatVersion: '2010-09-09'
Description: My application stack
Parameters:
Environment:
Type: String
AllowedValues: [dev, staging, prod]
Default: dev
InstanceType:
Type: String
Default: t3.micro
Conditions:
IsProd: !Equals [!Ref Environment, prod]
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-vpc"
PublicSubnet:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: 10.0.1.0/24
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-public"
AppInstance:
Type: AWS::EC2::Instance
Properties:
InstanceType: !Ref InstanceType
SubnetId: !Ref PublicSubnet
ImageId: !FindInMap [RegionAMI, !Ref "AWS::Region", ubuntu]
Database:
Type: AWS::RDS::DBInstance
Condition: IsProd
DeletionPolicy: Snapshot
Properties:
Engine: postgres
DBInstanceClass: db.t3.micro
AllocatedStorage: 20
MasterUsername: admin
MasterUserPassword: !Ref DBPassword
Outputs:
VpcId:
Value: !Ref VPC
Export:
Name: !Sub "${AWS::StackName}-VpcId"
InstanceIP:
Value: !GetAtt AppInstance.PublicIp
```
### CloudFormation CLI
```bash
# Validate template
aws cloudformation validate-template --template-body file://cloudformation.yaml
# Create stack
aws cloudformation create-stack \
--stack-name myapp-dev \
--template-body file://cloudformation.yaml \
--parameters ParameterKey=Environment,ParameterValue=dev \
--capabilities CAPABILITY_IAM
# Update stack
aws cloudformation update-stack \
--stack-name myapp-dev \
--template-body file://cloudformation.yaml \
--parameters ParameterKey=Environment,ParameterValue=dev
# Preview changes (changeset)
aws cloudformation create-change-set \
--stack-name myapp-dev \
--change-set-name update-1 \
--template-body file://cloudformation.yaml
aws cloudformation describe-change-set \
--stack-name myapp-dev \
--change-set-name update-1
# Delete stack
aws cloudformation delete-stack --stack-name myapp-dev
# List stacks
aws cloudformation list-stacks --stack-status-filter CREATE_COMPLETE UPDATE_COMPLETE
# Stack events (debugging)
aws cloudformation describe-stack-events --stack-name myapp-dev | head -50
```
## Pulumi (Code-First IaC)
### Quick Start (TypeScript)
```bash
# Install: https://www.pulumi.com/docs/install/
pulumi new aws-typescript
# Core workflow
pulumi preview # Preview changes
pulumi up # Apply changes
pulumi destroy # Tear down
pulumi stack ls # List stacks
```
### TypeScript Example
```typescript
// index.ts
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const config = new pulumi.Config();
const environment = config.require("environment");
// VPC
const vpc = new aws.ec2.Vpc("main", {
cidrBlock: "10.0.0.0/16",
enableDnsSupport: true,
enableDnsHostnames: true,
tags: { Name: `myapp-${environment}-vpc` },
});
// Public subnet
const publicSubnet = new aws.ec2.Subnet("public", {
vpcId: vpc.id,
cidrBlock: "10.0.1.0/24",
mapPublicIpOnLaunch: true,
tags: { Name: `myapp-${environment}-public` },
});
// S3 bucket
const bucket = new aws.s3.Bucket("data", {
bucket: `myapp-${environment}-data`,
versioning: { enabled: true },
});
// Lambda function
const lambdaRole = new aws.iam.Role("lambda-role", {
assumeRolePolicy: JSON.stringify({
Version: "2012-10-17",
Statement: [{
Action: "sts:AssumeRole",
Effect: "Allow",
Principal: { Service: "lambda.amazonaws.com" },
}],
}),
});
const lambdaFunc = new aws.lambda.Function("api", {
runtime: "nodejs20.x",
handler: "index.handler",
role: lambdaRole.arn,
code: new pulumi.asset.FileArchive("./lambda"),
environment: {
variables: {
BUCKET_NAME: bucket.id,
ENVIRONMENT: environment,
},
},
});
// Outputs
export const vpcId = vpc.id;
export const bucketName = bucket.id;
export const lambdaArn = lambdaFunc.arn;
```
### Python Example
```python
# __main__.py
import pulumi
import pulumi_aws as aws
config = pulumi.Config()
environment = config.require("environment")
vpc = aws.ec2.Vpc("main",
cidr_block="10.0.0.0/16",
enable_dns_support=True,
enable_dns_hostnames=True,
tags={"Name": f"myapp-{environment}-vpc"})
bucket = aws.s3.Bucket("data",
bucket=f"myapp-{environment}-data",
versioning=aws.s3.BucketVersioningArgs(enabled=True))
pulumi.export("vpc_id", vpc.id)
pulumi.export("bucket_name", bucket.id)
```
### Pulumi State and Stacks
```bash
# Create per-environment stacks
pulumi stack init dev
pulumi stack init staging
pulumi stack init prod
# Switch stack
pulumi stack select dev
# Set config per stack
pulumi config set environment dev
pulumi config set aws:region us-east-1
pulumi config set --secret dbPassword 'my-secret-pass'
# Stack references (cross-stack)
# In consuming stack:
const infra = new pulumi.StackReference("org/infra/prod");
const vpcId = infra.getOutput("vpcId");
```
## Debugging Infrastructure
### Terraform plan issues
```bash
# Detailed plan output
terraform plan -out=plan.tfplan
terraform show plan.tfplan
terraform show -json plan.tfplan | jq '.resource_changes[] | {address, change: .change.actions}'
# Debug mode
TF_LOG=DEBUG terraform plan 2> debug.log
# Check for drift
terraform plan -refresh-only
# Force refresh state
terraform apply -refresh-only
```
### Common issues
```bash
# Resource stuck in "tainted" state
terraform untaint aws_instance.app
# State locked (another apply running or crashed)
terraform force-unlock LOCK_ID
# Provider version conflict
terraform providers lock # Generate lock file
terraform init -upgrade # Upgrade providers
# Circular dependency
# Error: "Cycle" in terraform plan
# Fix: use depends_on explicitly, or break the cycle with data sources
```
### Cost estimation
```bash
# Infracost (estimates monthly cost from Terraform plans)
# Install: https://www.infracost.io/docs/
infracost breakdown --path .
infracost diff --path . --compare-to infracost-base.json
```
## Tips
- Always run `terraform plan` before `apply`. Read the plan output carefully — especially lines showing `destroy` or `replace`.
- Use remote state from day one. Local state files get lost, can't be shared, and have no locking.
- Tag everything. At minimum: Project, Environment, ManagedBy. Tags make cost tracking and cleanup possible.
- Never store secrets in `.tf` files or `terraform.tfvars`. Use environment variables (`TF_VAR_name`), secrets managers, or Vault.
- Use `prevent_destroy` lifecycle rules on stateful resources (databases, S3 buckets with data) to prevent accidental deletion.
- Pin provider versions (`~> 5.0` not `>= 5.0`) to avoid surprise breaking changes.
- For multi-environment setups, prefer workspaces + var files over duplicated configurations.
- CloudFormation change sets are the equivalent of `terraform plan` — always create one before updating a stack.
- Pulumi's advantage is using real programming languages (loops, conditionals, type checking). Use it when Terraform's HCL feels limiting.
使う前にスキルパッケージの安全性を調べ、結果に応じて導入を止めるスキルです。
Manages free AI models from OpenRouter for OpenClaw. Automatically ranks models by quality, configures fallbacks for rate-limit handling, and updates opencla...
OpenClaw の設定、資格情報、ワークスペースをバックアップし復元するスキルです。
1Password CLI でシークレットを扱うための設定と使い方です。
プロンプト注入や危険なコマンドを検出すると説明されている OpenClaw 用セキュリティプラグインです。
tmux セッションを遠隔操作し、対話型 CLI にキーを送って出力を取得します。
アプリケーションセキュリティ技術者の視点でコードと構成を監査します。
Tencent Cloud のオブジェクトストレージとデータ処理サービスを管理するスキルです。
コマンドラインから SQL データベースの照会、設計、移行、最適化を行います。
security-audit はコードとインフラの安全性を確認するチェックリストとコマンド例を提供します。
git-workflows は履歴整理、デバッグ、リポジトリ管理の高度な Git 手順を提供します。
コマンドラインで HTTP API を組み立て、試し、文書化し、調べます。
各種のアプリケーションログを解析、検索、分析し、障害の手がかりを探します。
データ月:2026-09 · ダウンロード数、スター数、インストール数は公開スキルレジストリ(ClawHub、SkillHub)から月単位で集計しています。詳しくはデータの方法論をご覧ください。