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.
Patterns for AWS CLI configuration, authentication, and Terraform AWS Provider infrastructure as code.
# ~/.aws/config
[default]
region = ap-northeast-1
output = json
[profile dev]
region = ap-northeast-1
# ~/.aws/credentials (prefer SSO over storing credentials)
[default]
aws_access_key_id = AKIA...
aws_secret_access_key = ...
AWS_PROFILE - active profileAWS_REGION / AWS_DEFAULT_REGION - regionAWS_SESSION_TOKEN - temporary credentialsexport AWS_PROFILE=dev
# or inline
aws s3 ls --profile prod
[profile sso-dev]
sso_session = my-sso
sso_account_id = 123456789012
sso_role_name = DeveloperAccess
region = ap-northeast-1
[sso-session my-sso]
sso_start_url = https://example.awsapps.com/start
sso_region = ap-northeast-1
aws sso login --sso-session my-sso
[profile cross-account]
role_arn = arn:aws:iam::987654321098:role/CrossAccountRole
source_profile = default
# .github/workflows/deploy.yml
permissions:
id-token: write
contents: read
steps:
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/GitHubActionsRole
aws-region: ap-northeast-1
aws sts get-caller-identity
aws s3 ls s3://bucket/prefix/
aws s3 cp file.txt s3://bucket/
aws s3 sync ./local s3://bucket/prefix/
aws s3 presign s3://bucket/key --expires-in 3600
aws ec2 describe-instances
aws ec2 start-instances --instance-ids i-123...
aws ec2 stop-instances --instance-ids i-123...
# Single value
aws ec2 describe-instances --query 'Reservations[0].Instances[0].InstanceId' --output text
# Filtered list
aws ec2 describe-instances --query 'Reservations[].Instances[?State.Name==`running`].InstanceId'
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "ap-northeast-1"
default_tags {
tags = {
Environment = "dev"
ManagedBy = "terraform"
}
}
}
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "env/dev/terraform.tfstate"
region = "ap-northeast-1"
encrypt = true
dynamodb_table = "terraform-locks"
}
}
IAM Role:
resource "aws_iam_role" "lambda" {
name = "lambda-execution-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = { Service = "lambda.amazonaws.com" }
}]
})
}
S3 Bucket:
resource "aws_s3_bucket" "main" {
bucket = "my-bucket"
}
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
}
OIDC for GitHub Actions:
resource "aws_iam_openid_connect_provider" "github" {
url = "https://token.actions.githubusercontent.com"
client_id_list = ["sts.amazonaws.com"]
thumbprint_list = ["ffffffffffffffffffffffffffffffffffffffff"]
}
terraform init
terraform plan -out=tfplan
terraform apply tfplan
terraform fmt -recursive
terraform validate
Critical:
High:
Terraform:
| Avoid | Instead |
|---|---|
| Hardcoded credentials | IAM roles, SSO, credential_process |
| Long-term access keys | Temporary credentials via SSO/AssumeRole |
| Root account for CLI | IAM users or SSO |
| Wildcard permissions | Least privilege with specific resources |
| State without locking | DynamoDB table for S3 backend |
Must:
Avoid:
Library ID: /hashicorp/terraform-provider-aws