
aws-ecosystem
by takeokunn
takeokunn's nixos-configuration
SKILL.md
name: AWS Ecosystem description: This skill should be used when the user asks to "aws cli", "aws configure", "aws sso", "aws sts", "terraform aws", or works with AWS CLI and Terraform AWS Provider patterns. Provides comprehensive AWS ecosystem patterns and best practices.
<cli_configuration> <config_files> AWS CLI configuration file [default] region = ap-northeast-1 output = json
[profile dev]
region = ap-northeast-1
output = json
[profile prod]
region = ap-northeast-1
output = json
</example>
</file>
<file name="~/.aws/credentials">
<description>AWS credentials file (avoid storing long-term credentials)</description>
<example>
[default]
aws_access_key_id = AKIA...
aws_secret_access_key = ...
</example>
<warning>Prefer SSO or IAM roles over long-term credentials</warning>
</file>
</config_files>
<environment_variables> Active profile name Override region Default region Access key (avoid in production) Secret key (avoid in production) Session token for temporary credentials Custom config file path Custom credentials file path </environment_variables>
<profile_switching> Set profile via environment variable export AWS_PROFILE=dev Set profile inline with command aws s3 ls --profile prod </profile_switching> </cli_configuration>
[sso-session my-sso]
sso_start_url = https://example.awsapps.com/start
sso_region = ap-northeast-1
sso_registration_scopes = sso:account:access
</example>
<commands>
<command name="login">aws sso login --sso-session my-sso</command>
<command name="logout">aws sso logout --sso-session my-sso</command>
</commands>
<concept name="pkce_authorization">
<description>PKCE authorization (default since AWS CLI v2.22.0)</description>
<note>Recommended for desktop/mobile access; provides secure OAuth 2.0 flow</note>
</concept>
<concept name="token_refresh">
<description>Automatic token refresh without re-authentication</description>
<note>Requires AWS CLI v2.9.0+ or v1.27.10+; sso-session configuration enables token refresh support</note>
</concept>
<note>Use SSO with sso-session for human users; use IAM roles for services</note>
<assume_role> Cross-account or elevated access via role assumption [profile cross-account] role_arn = arn:aws:iam::987654321098:role/CrossAccountRole source_profile = default region = ap-northeast-1 aws sts assume-role --role-arn arn:aws:iam::123456789012:role/MyRole --role-session-name session1 Assume role from another assumed role [profile chained] role_arn = arn:aws:iam::111111111111:role/FinalRole source_profile = cross-account </assume_role>
<credential_process> External credential provider [profile external] credential_process = /path/to/credential-provider Integration with 1Password, Vault, or custom providers </credential_process>
<oidc_federation> OIDC federation for CI/CD (2025 best practice) Use cases: GitHub Actions, GitLab CI, Azure DevOps with OIDC
<file_reference>.github/workflows/deploy.yml</file_reference>
permissions:
id-token: write
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps: - uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/GitHubActionsRole
aws-region: ap-northeast-1
</example>
<note>No long-term credentials stored in CI/CD; temporary credentials via STS</note>
<warning>Validate OIDC thumbprints and restrict ClientIDList to prevent misconfiguration</warning>
</oidc_federation>
<output_filtering> <decision_tree name="when_to_use"> Do you need to filter or transform AWS CLI output? <if_yes>Use --query for AWS-native filtering or pipe to jq for complex transformations</if_yes> <if_no>Use default JSON output for full response data</if_no> </decision_tree>
<output_formats> Default, machine-readable (--output json) Tab-delimited, scriptable (--output text) Human-readable (--output table) YAML format (--output yaml) </output_formats>
<query_examples> Extract single value from query aws ec2 describe-instances --query 'Reservations[0].Instances[0].InstanceId' --output text
<pattern name="list">
<description>Extract list of values</description>
<example>aws ec2 describe-instances --query 'Reservations[].Instances[].InstanceId' --output text</example>
</pattern>
<pattern name="filtered">
<description>Filter results by condition</description>
<example>aws ec2 describe-instances --query 'Reservations[].Instances[?State.Name==`running`].InstanceId' --output text</example>
</pattern>
<pattern name="projection">
<description>Project multiple fields with custom formatting</description>
<example>aws ec2 describe-instances --query 'Reservations[].Instances[].[InstanceId,State.Name,Tags[?Key==`Name`].Value|[0]]' --output table</example>
</pattern>
<pattern name="sorting">
<description>Sort results by field</description>
<example>aws ec2 describe-instances --query 'sort_by(Reservations[].Instances[], &LaunchTime)[].InstanceId'</example>
</pattern>
</query_examples>
<jq_integration> Basic jq filtering aws ec2 describe-instances | jq '.Reservations[].Instances[].InstanceId' Complex jq transformation with TSV output aws ec2 describe-instances | jq -r '.Reservations[].Instances[] | [.InstanceId, .State.Name] | @tsv' </jq_integration> </output_filtering>
<common_commands> aws s3 ls aws s3 ls s3://bucket-name/prefix/ aws s3 cp file.txt s3://bucket-name/ aws s3 sync ./local-dir s3://bucket-name/prefix/ aws s3 presign s3://bucket-name/object-key --expires-in 3600
<secrets_manager> aws secretsmanager get-secret-value --secret-id my-secret --query SecretString --output text aws secretsmanager create-secret --name my-secret --secret-string '{"key":"value"}' </secrets_manager> </common_commands>
<scripting_patterns> <wait_commands> Wait for EC2 instance to reach running state aws ec2 wait instance-running --instance-ids i-1234567890abcdef0 Wait for CloudFormation stack creation aws cloudformation wait stack-create-complete --stack-name my-stack </wait_commands>
<batch_operations> Batch operations using shell loop for id in $(aws ec2 describe-instances --query 'Reservations[].Instances[].InstanceId' --output text); do aws ec2 create-tags --resources "$id" --tags Key=Environment,Value=Dev done
<pattern name="xargs">
<description>Batch operations using xargs</description>
<example>
aws ec2 describe-instances --query 'Reservations[].Instances[].InstanceId' --output text | \
xargs -I {} aws ec2 create-tags --resources {} --tags Key=Backup,Value=true
</example>
</pattern>
</batch_operations> </scripting_patterns>
<anti_patterns> Never hardcode credentials in scripts or config Use IAM roles, SSO, or credential_process
<best_practices> Eliminate long-term access keys; use SSO or IAM roles instead Use sso-session configuration for token refresh support (CLI v2.9.0+) Use OIDC federation for CI/CD (GitHub Actions, GitLab CI) Use Instance Profiles for EC2, EKS Service Accounts for K8s, Lambda Execution Roles for serverless Enable MFA for all human users Follow least privilege principle; avoid wildcard permissions Enable CloudTrail for CLI activity monitoring Use --query for filtering instead of jq when possible Set default region in config to avoid specifying every time Use named profiles for different environments Use aws sts get-caller-identity to verify current identity Enable CLI auto-prompt: export AWS_CLI_AUTO_PROMPT=on-partial Use --dry-run for destructive operations first Use wait commands in scripts for async operations Store credentials file with 600 permissions </best_practices>
<provider_configuration> Basic AWS provider configuration terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 5.0" } } }
provider "aws" {
region = "ap-northeast-1"
}
</example>
</pattern>
<pattern name="with_profile">
<description>Using AWS CLI profile</description>
<example>
provider "aws" {
region = "ap-northeast-1"
profile = "dev"
}
</example>
</pattern>
<pattern name="with_assume_role">
<description>Cross-account access with assume role</description>
<example>
provider "aws" {
region = "ap-northeast-1"
assume_role {
role_arn = "arn:aws:iam::987654321098:role/TerraformRole"
session_name = "terraform-session"
external_id = "unique-external-id"
}
}
</example>
</pattern>
<pattern name="multi_region">
<description>Multiple region configuration with aliases</description>
<example>
provider "aws" {
region = "ap-northeast-1"
alias = "tokyo"
}
provider "aws" {
region = "us-east-1"
alias = "virginia"
}
resource "aws_s3_bucket" "tokyo_bucket" {
provider = aws.tokyo
bucket = "my-tokyo-bucket"
}
resource "aws_s3_bucket" "virginia_bucket" {
provider = aws.virginia
bucket = "my-virginia-bucket"
}
</example>
</pattern>
<pattern name="default_tags">
<description>Apply default tags to all resources</description>
<example>
provider "aws" {
region = "ap-northeast-1"
default_tags {
tags = {
Environment = "dev"
ManagedBy = "terraform"
Project = "my-project"
}
}
}
</example>
</pattern>
</provider_configuration>
<backend_configuration> Remote state with S3 and DynamoDB locking terraform { backend "s3" { bucket = "my-terraform-state" key = "env/dev/terraform.tfstate" region = "ap-northeast-1" encrypt = true dynamodb_table = "terraform-locks" } }
<pattern name="state_locking">
<description>DynamoDB table for state locking</description>
<example>
resource "aws_dynamodb_table" "terraform_locks" {
name = "terraform-locks"
billing_mode = "PAY_PER_REQUEST"
hash_key = "LockID"
attribute {
name = "LockID"
type = "S"
}
}
</example>
</pattern>
</backend_configuration>
<common_resources> VPC with subnets and internet gateway resource "aws_vpc" "main" { cidr_block = "10.0.0.0/16" enable_dns_hostnames = true enable_dns_support = true
tags = {
Name = "main-vpc"
}
}
resource "aws_subnet" "public" {
count = 2
vpc_id = aws_vpc.main.id
cidr_block = cidrsubnet(aws_vpc.main.cidr_block, 8, count.index)
availability_zone = data.aws_availability_zones.available.names[count.index]
map_public_ip_on_launch = true
tags = {
Name = "public-subnet-${count.index + 1}"
}
}
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
}
</example>
</pattern>
<pattern name="security_group">
<description>Security group with ingress and egress rules</description>
<example>
resource "aws_security_group" "web" {
name = "web-sg"
description = "Security group for web servers"
vpc_id = aws_vpc.main.id
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"]
}
}
</example>
</pattern>
<pattern name="iam_role">
<description>IAM role with policy attachment</description>
<example>
resource "aws_iam_role" "lambda_role" {
name = "lambda-execution-role"
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_role.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}
</example>
</pattern>
<pattern name="oidc_provider">
<description>OIDC provider for GitHub Actions (2025 recommended)</description>
<example>
resource "aws_iam_openid_connect_provider" "github" {
url = "https://token.actions.githubusercontent.com"
client_id_list = ["sts.amazonaws.com"]
thumbprint_list = ["ffffffffffffffffffffffffffffffffffffffff"]
}
resource "aws_iam_role" "github_actions" {
name = "github-actions-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
Federated = aws_iam_openid_connect_provider.github.arn
}
Action = "sts:AssumeRoleWithWebIdentity"
Condition = {
StringEquals = {
"token.actions.githubusercontent.com:aud" = "sts.amazonaws.com"
}
StringLike = {
"token.actions.githubusercontent.com:sub" = "repo:org/repo:*"
}
}
}
]
})
}
</example>
<note>Always restrict sub claim to specific repos/branches</note>
</pattern>
<pattern name="sts_preferences">
<description>STS global endpoint token version (2025 security)</description>
<example>
resource "aws_iam_security_token_service_preferences" "main" {
global_endpoint_token_version = "v2Token"
}
</example>
<note>v2Token provides regional STS tokens for improved security</note>
</pattern>
<pattern name="s3_bucket">
<description>S3 bucket with versioning, encryption, and public access block</description>
<example>
resource "aws_s3_bucket" "main" {
bucket = "my-unique-bucket-name"
}
resource "aws_s3_bucket_versioning" "main" {
bucket = aws_s3_bucket.main.id
versioning_configuration {
status = "Enabled"
}
}
resource "aws_s3_bucket_server_side_encryption_configuration" "main" {
bucket = aws_s3_bucket.main.id
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}
resource "aws_s3_bucket_public_access_block" "main" {
bucket = aws_s3_bucket.main.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
</example>
</pattern>
<pattern name="lambda">
<description>Lambda function with environment variables</description>
<example>
resource "aws_lambda_function" "main" {
function_name = "my-function"
role = aws_iam_role.lambda_role.arn
handler = "index.handler"
runtime = "nodejs20.x" # or "nodejs22.x" (Node.js 22 LTS)
timeout = 30
memory_size = 256
filename = "lambda.zip"
source_code_hash = filebase64sha256("lambda.zip")
environment {
variables = {
ENV = "production"
}
}
}
</example>
</pattern>
<pattern name="ecs">
<description>ECS cluster with Fargate task definition</description>
<example>
resource "aws_ecs_cluster" "main" {
name = "my-cluster"
setting {
name = "containerInsights"
value = "enabled"
}
}
resource "aws_ecs_task_definition" "app" {
family = "my-app"
network_mode = "awsvpc"
requires_compatibilities = ["FARGATE"]
cpu = "256"
memory = "512"
execution_role_arn = aws_iam_role.ecs_execution.arn
task_role_arn = aws_iam_role.ecs_task.arn
container_definitions = jsonencode([
{
name = "app"
image = "nginx:latest"
portMappings = [
{
containerPort = 80
hostPort = 80
}
]
}
])
}
</example>
</pattern>
<pattern name="rds">
<description>RDS PostgreSQL instance with encryption and backups</description>
<example>
resource "aws_db_instance" "main" {
identifier = "my-database"
engine = "postgres"
engine_version = "15"
instance_class = "db.t3.micro"
allocated_storage = 20
storage_encrypted = true
db_name = "mydb"
username = "admin"
password = var.db_password
vpc_security_group_ids = [aws_security_group.rds.id]
db_subnet_group_name = aws_db_subnet_group.main.name
backup_retention_period = 7
skip_final_snapshot = false
final_snapshot_identifier = "my-database-final"
tags = {
Name = "my-database"
}
}
</example>
</pattern>
</common_resources>
<data_sources> Get available availability zones data "aws_availability_zones" "available" { state = "available" }
<pattern name="caller_identity">
<description>Get current AWS account ID and ARN</description>
<example>
data "aws_caller_identity" "current" {}
output "account_id" {
value = data.aws_caller_identity.current.account_id
}
</example>
</pattern>
<pattern name="region">
<description>Get current AWS region</description>
<example>
data "aws_region" "current" {}
output "region" {
value = data.aws_region.current.name
}
</example>
</pattern>
<pattern name="ami">
<description>Find latest Amazon Linux AMI</description>
<example>
data "aws_ami" "amazon_linux" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["al2023-ami-*-x86_64"]
}
}
</example>
</pattern>
</data_sources>
cidr_block = "10.0.0.0/16"
name = "main"
}
</example>
</pattern>
<pattern name="registry_module">
<description>Terraform Registry module</description>
<example>
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "5.0.0"
name = "my-vpc"
cidr = "10.0.0.0/16"
azs = ["ap-northeast-1a", "ap-northeast-1c"]
private_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
public_subnets = ["10.0.101.0/24", "10.0.102.0/24"]
enable_nat_gateway = true
single_nat_gateway = true
}
</example>
</pattern>
<terraform_commands> terraform init terraform plan -out=tfplan terraform apply tfplan terraform destroy terraform fmt -recursive terraform validate terraform state list terraform state show aws_instance.example terraform import aws_instance.example i-1234567890abcdef0 terraform refresh terraform output -json </terraform_commands>
<terraform_anti_patterns> Never hardcode AWS credentials in Terraform files Use environment variables, AWS CLI profiles, or IAM roles
<avoid name="hardcoded_secrets">
<description>Never store secrets in terraform.tfvars or state</description>
<instead>Use AWS Secrets Manager, SSM Parameter Store, or external secret management</instead>
</avoid>
<avoid name="no_state_locking">
<description>Running Terraform without state locking in teams</description>
<instead>Use DynamoDB table for S3 backend locking</instead>
</avoid>
<avoid name="wildcard_permissions">
<description>Using "*" for resources and actions in IAM policies</description>
<instead>Follow least privilege principle with specific resources</instead>
</avoid>
<avoid name="unencrypted_state">
<description>Storing state without encryption</description>
<instead>Enable encryption for S3 backend state</instead>
</avoid>
<avoid name="no_versioning">
<description>Not versioning provider and module versions</description>
<instead>Pin versions with ~> or exact versions</instead>
</avoid>
</terraform_anti_patterns>
<terraform_best_practices> Use remote state with S3 backend and DynamoDB locking Enable state encryption with encrypt = true Pin provider versions to avoid breaking changes Use default_tags for consistent resource tagging Separate environments using workspaces or directory structure Run terraform plan before apply to review changes Use terraform fmt before committing code Use data sources instead of hardcoding ARNs Store sensitive variables in environment or secret managers Use modules for reusable infrastructure components Enable versioning on S3 state bucket Use lifecycle rules to prevent accidental deletion </terraform_best_practices>
<context7_integration> Library ID is already known: /hashicorp/terraform-provider-aws (trust score 9.8, 31100 snippets)
<tool name="get-library-docs">
<description>Fetch documentation with specific topic</description>
<use_case>VPC and networking resources (topic: vpc)</use_case>
<use_case>IAM roles and policies (topic: iam)</use_case>
<use_case>Lambda function configuration (topic: lambda)</use_case>
<use_case>ECS cluster and task definitions (topic: ecs)</use_case>
<use_case>S3 bucket configuration (topic: s3)</use_case>
</tool>
</context7_integration>
<error_escalation> Minor tagging inconsistency Fix tags, follow naming conventions IAM policy too permissive Restrict permissions, apply least privilege Security group allows unrestricted access Stop, require security review before proceeding Potential data exposure or credential leak Block operation, require immediate remediation </error_escalation>
<related_skills> Symbol operations for Terraform code navigation Terraform AWS Provider documentation via /hashicorp/terraform-provider-aws Debugging authentication failures and service quota issues Creating infrastructure documentation and runbooks </related_skills>
Score
Total Score
Based on repository quality metrics
SKILL.mdファイルが含まれている
ライセンスが設定されている
100文字以上の説明がある
GitHub Stars 100以上
1ヶ月以内に更新
10回以上フォークされている
オープンIssueが50未満
プログラミング言語が設定されている
1つ以上のタグが設定されている
Reviews
Reviews coming soon


