AWS Ecosystem

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.

$ 설치

git clone https://github.com/takeokunn/nixos-configuration /tmp/nixos-configuration && cp -r /tmp/nixos-configuration/home-manager/programs/claude-code/skills/aws-ecosystem ~/.claude/skills/nixos-configuration

// tip: Run this command in your terminal to install the skill


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

<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 aws sso login --sso-session my-sso aws sso logout --sso-session my-sso PKCE authorization (default since AWS CLI v2.22.0) Recommended for desktop/mobile access; provides secure OAuth 2.0 flow Automatic token refresh without re-authentication Requires AWS CLI v2.9.0+ or v1.27.10+; sso-session configuration enables token refresh support Use SSO with sso-session for human users; use IAM roles for services

<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 No long-term credentials stored in CI/CD; temporary credentials via STS Validate OIDC thumbprints and restrict ClientIDList to prevent misconfiguration </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

<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

<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" }

assume_role { role_arn = "arn:aws:iam::987654321098:role/TerraformRole" session_name = "terraform-session" external_id = "unique-external-id" } }

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" }

default_tags { tags = { Environment = "dev" ManagedBy = "terraform" Project = "my-project" } } } </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" } }

attribute { name = "LockID" type = "S" } } </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 }

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"] } }

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" }

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:*" } } } ] }) } Always restrict sub claim to specific repos/branches

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 }

filename = "lambda.zip" source_code_hash = filebase64sha256("lambda.zip")

environment { variables = { ENV = "production" } } }

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 } ] } ]) }

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" } } </common_resources>

<data_sources> Get available availability zones data "aws_availability_zones" "available" { state = "available" }

output "account_id" { value = data.aws_caller_identity.current.account_id }

output "region" { value = data.aws_region.current.name }

filter { name = "name" values = ["al2023-ami-*-x86_64"] } } </data_sources>

cidr_block = "10.0.0.0/16" name = "main" }

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 }

<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

<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)

<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_agents> Architecture design for AWS infrastructure and service integration CloudFormation and Terraform documentation generation AWS CLI operations and Terraform deployment tasks Debugging AWS API errors and Terraform state issues </related_agents>

<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>