diff --git a/.doc_gen/metadata/api_gateway_apigateway_lambda_metadata.yaml b/.doc_gen/metadata/api_gateway_apigateway_lambda_metadata.yaml new file mode 100644 index 00000000..73beb53b --- /dev/null +++ b/.doc_gen/metadata/api_gateway_apigateway_lambda_metadata.yaml @@ -0,0 +1,26 @@ +api_gateway_GettingStarted_087: + title: Create a REST API with Lambda proxy integration + title_abbrev: Create a REST API with Lambda proxy integration + synopsis_list: + - Create an IAM role for Lambda execution + - Create and deploy a Lambda function + - Create a REST API + - Configure Lambda proxy integration + - Deploy and test the API + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/087-apigateway-lambda-integration + excerpts: + - description: + snippet_files: + - tuts/087-apigateway-lambda-integration/apigateway-lambda-integration.sh + services: + api-gateway: {CreateDeployment, CreateResource, CreateRestApi, DeleteRestApi, GetResources, GetRestApis, PutIntegration, PutMethod} + iam: {AttachRolePolicy, CreateRole, DeleteRole, DetachRolePolicy} + lambda: {AddPermission, CreateFunction, DeleteFunction} + sts: {GetCallerIdentity} diff --git a/.doc_gen/metadata/athena_amazon_athena_metadata.yaml b/.doc_gen/metadata/athena_amazon_athena_metadata.yaml new file mode 100644 index 00000000..3bf81f30 --- /dev/null +++ b/.doc_gen/metadata/athena_amazon_athena_metadata.yaml @@ -0,0 +1,24 @@ +athena_GettingStarted_061: + title: Getting started with Amazon Athena + title_abbrev: Getting started with Amazon Athena + synopsis_list: + - Create an S3 bucket for query results + - Create a database + - Create a table + - Run a query + - Create and use named queries + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/061-amazon-athena-gs + excerpts: + - description: + snippet_files: + - tuts/061-amazon-athena-gs/amazon-athena-gs.sh + services: + athena: {CreateNamedQuery, DeleteNamedQuery, GetNamedQuery, GetQueryExecution, GetQueryResults, ListDatabases, ListNamedQueries, ListTableMetadata, StartQueryExecution} + s3: {Cp, Mb, Rb, Rm} diff --git a/.doc_gen/metadata/cloudformation_cloudformation_gs_metadata.yaml b/.doc_gen/metadata/cloudformation_cloudformation_gs_metadata.yaml new file mode 100644 index 00000000..108d6a80 --- /dev/null +++ b/.doc_gen/metadata/cloudformation_cloudformation_gs_metadata.yaml @@ -0,0 +1,20 @@ +cloudformation_GettingStarted_021: + title: Creating your first CloudFormation stack + title_abbrev: Creating your first CloudFormation stack + synopsis_list: + - Create a CloudFormation template + - Test the web server + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/021-cloudformation-gs + excerpts: + - description: + snippet_files: + - tuts/021-cloudformation-gs/cloudformation-gs.sh + services: + cloudformation: {CreateStack, DeleteStack, DescribeStacks, ListStackResources, ValidateTemplate, Wait} diff --git a/.doc_gen/metadata/cloudfront_metadata.yaml b/.doc_gen/metadata/cloudfront_metadata.yaml index 3b6e95a6..507317d5 100644 --- a/.doc_gen/metadata/cloudfront_metadata.yaml +++ b/.doc_gen/metadata/cloudfront_metadata.yaml @@ -1,14 +1,11 @@ cloudfront_GettingStarted: - title: Get started with a basic CloudFront distribution using the CLI - title_abbrev: Get started with CloudFront + title: Get started with a basic CloudFront distribution + title_abbrev: Get started with a basic CloudFront distribution synopsis_list: - - Create an Amazon S3 bucket for content storage - - Upload sample content to the S3 bucket - - Create an origin access control (OAC) for secure S3 access - - Create a CloudFront distribution with S3 as origin - - Update S3 bucket policy to allow CloudFront access - - Wait for distribution deployment and test content access - - Clean up resources including distribution, OAC, and S3 bucket + - Create an Amazon S3 bucket + - Upload content to the bucket + - Create a CloudFront distribution with OAC + - Clean up resources category: Scenarios languages: Bash: diff --git a/.doc_gen/metadata/cloudmap_metadata.yaml b/.doc_gen/metadata/cloudmap_metadata.yaml index e2a6bf98..0803f995 100644 --- a/.doc_gen/metadata/cloudmap_metadata.yaml +++ b/.doc_gen/metadata/cloudmap_metadata.yaml @@ -1,13 +1,14 @@ cloudmap_CustomAttributes: - title: Use custom attributes with Cloud Map + title: Using Cloud Map service discovery with custom attributes title_abbrev: Cloud Map custom attributes synopsis_list: - - Create an HTTP namespace for API-based service discovery - - Create a DynamoDB table and register it as a data service with custom attributes - - Create Lambda functions for reading and writing data - - Register Lambda functions as service instances with custom attributes for action-based discovery - - Build client applications that discover services using custom attributes - - Clean up all resources including Lambda functions, DynamoDB table, and Cloud Map services + - Create an Cloud Map namespace + - Create a DynamoDB table + - Create an Cloud Map data service and register the DynamoDB table + - Create an IAM role for Lambda functions + - Create the Lambda function to write data + - Create an Cloud Map app service and register the Lambda write function + - Create the Lambda function to read data category: Scenarios languages: Bash: diff --git a/.doc_gen/metadata/cloudwatch_cloudwatch_dynamicdash_metadata.yaml b/.doc_gen/metadata/cloudwatch_cloudwatch_dynamicdash_metadata.yaml new file mode 100644 index 00000000..a26e0630 --- /dev/null +++ b/.doc_gen/metadata/cloudwatch_cloudwatch_dynamicdash_metadata.yaml @@ -0,0 +1,24 @@ +cloudwatch_GettingStarted_031: + title: Creating a CloudWatch dashboard with function name as a variable + title_abbrev: Creating a CloudWatch dashboard with function name as a variable + synopsis_list: + - Create a CloudWatch dashboard + - Add Lambda metrics widgets with a function name variable + - Verify the dashboard + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/031-cloudwatch-dynamicdash + excerpts: + - description: + snippet_files: + - tuts/031-cloudwatch-dynamicdash/cloudwatch-dynamicdash.sh + services: + cloudwatch: {DeleteDashboards, GetDashboard, ListDashboards, PutDashboard} + iam: {AttachRolePolicy, CreateRole, DeleteRole, DetachRolePolicy} + lambda: {CreateFunction, DeleteFunction, Invoke, ListFunctions} + sts: {GetCallerIdentity} diff --git a/.doc_gen/metadata/cognito_identity_provider_amazon_cognito_metadata.yaml b/.doc_gen/metadata/cognito_identity_provider_amazon_cognito_metadata.yaml new file mode 100644 index 00000000..cc3a0788 --- /dev/null +++ b/.doc_gen/metadata/cognito_identity_provider_amazon_cognito_metadata.yaml @@ -0,0 +1,24 @@ +cognito_identity_provider_GettingStarted_066: + title: Getting started with Amazon Cognito user pools + title_abbrev: Getting started with Amazon Cognito user pools + synopsis_list: + - Create a user pool + - Create an app client + - Set up a domain for your user pool + - Create a user as an administrator + - Enable self-registration + - List users in the user pool + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/066-amazon-cognito-gs + excerpts: + - description: + snippet_files: + - tuts/066-amazon-cognito-gs/amazon-cognito-gs.sh + services: + cognito-identity-provider: {AdminConfirmSignUp, AdminCreateUser, CreateUserPool, CreateUserPoolClient, CreateUserPoolDomain, DeleteUserPool, DeleteUserPoolDomain, DescribeUserPool, DescribeUserPoolClient, InitiateAuth, ListUsers, SignUp} diff --git a/.doc_gen/metadata/config_service_aws_config_metadata.yaml b/.doc_gen/metadata/config_service_aws_config_metadata.yaml new file mode 100644 index 00000000..5ba06e62 --- /dev/null +++ b/.doc_gen/metadata/config_service_aws_config_metadata.yaml @@ -0,0 +1,28 @@ +config_service_GettingStarted_053: + title: Getting started with Config + title_abbrev: Getting started with Config + synopsis_list: + - Create an Amazon S3 bucket + - Create an Amazon SNS topic + - Create an IAM role for Config + - Set up the Config configuration recorder + - Set up the Config delivery channel + - Start the configuration recorder + - Verify the Config setup + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/053-aws-config-gs + excerpts: + - description: + snippet_files: + - tuts/053-aws-config-gs/aws-config-gs.sh + services: + config-service: {DeleteConfigurationRecorder, DeleteDeliveryChannel, DescribeConfigurationRecorderStatus, DescribeConfigurationRecorders, DescribeDeliveryChannels, PutConfigurationRecorder, PutDeliveryChannel, StartConfigurationRecorder, StopConfigurationRecorder} + iam: {AttachRolePolicy, CreateRole, DeleteRole, DeleteRolePolicy, DetachRolePolicy, PutRolePolicy} + s3: {CreateBucket, DeleteBucket, PutPublicAccessBlock, Rm} + sns: {CreateTopic, DeleteTopic} + sts: {GetCallerIdentity} diff --git a/.doc_gen/metadata/connect_connect_gs_metadata.yaml b/.doc_gen/metadata/connect_connect_gs_metadata.yaml new file mode 100644 index 00000000..6399a2e5 --- /dev/null +++ b/.doc_gen/metadata/connect_connect_gs_metadata.yaml @@ -0,0 +1,22 @@ +connect_GettingStarted_027: + title: Creating an Amazon Connect instance + title_abbrev: Creating an Amazon Connect instance + synopsis_list: + - Create an Amazon Connect instance + - Configure an administrator user + - Configure telephony options + - Set up a phone number + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/027-connect-gs + excerpts: + - description: + snippet_files: + - tuts/027-connect-gs/connect-gs.sh + services: + connect: {ClaimPhoneNumber, CreateInstance, CreateUser, DeleteInstance, DescribeInstance, ListInstanceStorageConfigs, ListInstances, ListRoutingProfiles, ListSecurityProfiles, ReleasePhoneNumber, SearchAvailablePhoneNumbers, UpdateInstanceAttribute} diff --git a/.doc_gen/metadata/directconnect_aws_direct_metadata.yaml b/.doc_gen/metadata/directconnect_aws_direct_metadata.yaml new file mode 100644 index 00000000..08f1945b --- /dev/null +++ b/.doc_gen/metadata/directconnect_aws_direct_metadata.yaml @@ -0,0 +1,24 @@ +directconnect_GettingStarted_051: + title: Get started with Aws Direct Connect using the CLI + title_abbrev: Get started with Aws Direct Connect + synopsis_list: + - Use ec2 CreateVpnGateway + - Use ec2 DeleteVpnGateway + - Use ec2 DescribeVpnGateways + - Use directconnect CreateConnection + - Use directconnect CreatePrivateVirtualInterface + - Use directconnect DeleteConnection + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/051-aws-direct-connect-gs + excerpts: + - description: + snippet_files: + - tuts/051-aws-direct-connect-gs/aws-direct-connect-gs.sh + services: + direct-connect: {CreateConnection, CreatePrivateVirtualInterface, DeleteConnection, DeleteVirtualInterface, DescribeConnections, DescribeLoa, DescribeLocations, DescribeVirtualInterfaces, UpdateConnection} + ec2: {CreateVpnGateway, DeleteVpnGateway, DescribeVpnGateways} diff --git a/.doc_gen/metadata/docdb_documentdb_gs_metadata.yaml b/.doc_gen/metadata/docdb_documentdb_gs_metadata.yaml new file mode 100644 index 00000000..59537c53 --- /dev/null +++ b/.doc_gen/metadata/docdb_documentdb_gs_metadata.yaml @@ -0,0 +1,24 @@ +docdb_GettingStarted_025: + title: Getting started with Amazon DocumentDB + title_abbrev: Getting started with Amazon DocumentDB + synopsis_list: + - Create a DB subnet group + - Create a DocumentDB cluster + - Create a DocumentDB instance + - Configure security and connectivity + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/025-documentdb-gs + excerpts: + - description: + snippet_files: + - tuts/025-documentdb-gs/documentdb-gs.sh + services: + docdb: {CreateDbCluster, CreateDbInstance, CreateDbSubnetGroup, DeleteDbCluster, DeleteDbInstance, DeleteDbSubnetGroup, DescribeDbClusters, DescribeDbInstances, Wait} + ec2: {AuthorizeSecurityGroupIngress, CreateDefaultVpc, DescribeSubnets, DescribeVpcs, RevokeSecurityGroupIngress} + secrets-manager: {CreateSecret, DeleteSecret, GetSecretValue} diff --git a/.doc_gen/metadata/dynamodb_amazon_dynamodb_metadata.yaml b/.doc_gen/metadata/dynamodb_amazon_dynamodb_metadata.yaml new file mode 100644 index 00000000..9618d6e3 --- /dev/null +++ b/.doc_gen/metadata/dynamodb_amazon_dynamodb_metadata.yaml @@ -0,0 +1,21 @@ +dynamodb_GettingStarted_070: + title: Getting started with DynamoDB + title_abbrev: Getting started with DynamoDB + synopsis_list: + - Create a table in DynamoDB + - Update data in a DynamoDB table + - Query data in a DynamoDB table + - Delete your DynamoDB table + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/070-amazon-dynamodb-gs + excerpts: + - description: + snippet_files: + - tuts/070-amazon-dynamodb-gs/amazon-dynamodb-gs.sh + services: + dynamodb: {CreateTable, DeleteTable, DescribeTable, GetItem, PutItem, Query, UpdateContinuousBackups, UpdateItem, Wait} diff --git a/.doc_gen/metadata/ec2_amazon_elasticache_metadata.yaml b/.doc_gen/metadata/ec2_amazon_elasticache_metadata.yaml new file mode 100644 index 00000000..65660840 --- /dev/null +++ b/.doc_gen/metadata/ec2_amazon_elasticache_metadata.yaml @@ -0,0 +1,21 @@ +ec2_GettingStarted_065: + title: Getting started with Amazon ElastiCache + title_abbrev: Getting started with Amazon ElastiCache + synopsis_list: + - Set up security group for ElastiCache access + - Create a Valkey serverless cache + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/065-amazon-elasticache-gs + excerpts: + - description: + snippet_files: + - tuts/065-amazon-elasticache-gs/amazon-elasticache-gs.sh + services: + ec2: {AuthorizeSecurityGroupIngress, DescribeSecurityGroups, RevokeSecurityGroupIngress} + elasticache: {CreateServerlessCache, DeleteServerlessCache, DescribeServerlessCaches} diff --git a/.doc_gen/metadata/ec2_amazon_managed_metadata.yaml b/.doc_gen/metadata/ec2_amazon_managed_metadata.yaml new file mode 100644 index 00000000..9b3a7e26 --- /dev/null +++ b/.doc_gen/metadata/ec2_amazon_managed_metadata.yaml @@ -0,0 +1,27 @@ +ec2_GettingStarted_057: + title: Getting started with Amazon MSK + title_abbrev: Getting started with Amazon MSK + synopsis_list: + - Create an MSK cluster + - Create IAM permissions for MSK access + - Create a client machine + - Get bootstrap brokers + - Set up the client machine + - Create a topic and produce/consume data + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/057-amazon-managed-streaming-for-apache-kafka-gs + excerpts: + - description: + snippet_files: + - tuts/057-amazon-managed-streaming-for-apache-kafka-gs/amazon-managed-streaming-for-apache-kafka-gs.sh + services: + ec2: {AuthorizeSecurityGroupIngress, CreateKeyPair, CreateSecurityGroup, DeleteKeyPair, DeleteSecurityGroup, DescribeAvailabilityZones, DescribeImages, DescribeInstanceTypeOfferings, DescribeInstances, DescribeKeyPairs, DescribeSecurityGroups, DescribeSubnets, DescribeVpcs, RevokeSecurityGroupEgress, RevokeSecurityGroupIngress, RunInstances, TerminateInstances, Wait} + iam: {AddRoleToInstanceProfile, AttachRolePolicy, CreateInstanceProfile, CreatePolicy, CreateRole, DeleteInstanceProfile, DeletePolicy, DeleteRole, DetachRolePolicy, GetInstanceProfile, GetPolicy, GetRole, RemoveRoleFromInstanceProfile} + kafka: {CreateCluster, DeleteCluster, DescribeCluster, GetBootstrapBrokers} + sts: {GetCallerIdentity} diff --git a/.doc_gen/metadata/ec2_amazon_neptune_metadata.yaml b/.doc_gen/metadata/ec2_amazon_neptune_metadata.yaml new file mode 100644 index 00000000..807aed75 --- /dev/null +++ b/.doc_gen/metadata/ec2_amazon_neptune_metadata.yaml @@ -0,0 +1,25 @@ +ec2_GettingStarted_064: + title: Getting started with Amazon Neptune + title_abbrev: Getting started with Amazon Neptune + synopsis_list: + - Create a VPC for your Neptune database + - Create subnets in multiple availability zones + - Configure security for your Neptune database + - Create a Neptune DB subnet group + - Create a Neptune DB cluster and instance + - Add data to your graph database + - Query your graph database + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/064-amazon-neptune-gs + excerpts: + - description: + snippet_files: + - tuts/064-amazon-neptune-gs/amazon-neptune-gs.sh + services: + ec2: {AssociateRouteTable, AttachInternetGateway, AuthorizeSecurityGroupIngress, CreateInternetGateway, CreateRoute, CreateRouteTable, CreateSecurityGroup, CreateSubnet, CreateVpc, DeleteInternetGateway, DeleteRouteTable, DeleteSecurityGroup, DeleteSubnet, DeleteVpc, DescribeAvailabilityZones, DetachInternetGateway, ModifyVpcAttribute} + neptune: {CreateDbCluster, CreateDbInstance, CreateDbSubnetGroup, DeleteDbCluster, DeleteDbInstance, DeleteDbSubnetGroup, DescribeDbClusters, Wait} diff --git a/.doc_gen/metadata/ec2_ebs_gs_metadata.yaml b/.doc_gen/metadata/ec2_ebs_gs_metadata.yaml new file mode 100644 index 00000000..b21cefb2 --- /dev/null +++ b/.doc_gen/metadata/ec2_ebs_gs_metadata.yaml @@ -0,0 +1,22 @@ +ec2_GettingStarted_020: + title: Creating and managing Amazon EBS volumes + title_abbrev: Creating and managing Amazon EBS volumes + synopsis_list: + - Create an EBS volume + - Check volume status + - Create an EC2 instance (optional) + - Attach a volume to an EC2 instance + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/020-ebs-gs-volumes + excerpts: + - description: + snippet_files: + - tuts/020-ebs-gs-volumes/ebs-gs-volumes.sh + services: + ec2: {AttachVolume, AuthorizeSecurityGroupIngress, CreateSecurityGroup, CreateVolume, DeleteSecurityGroup, DeleteVolume, DescribeAvailabilityZones, DescribeImages, DescribeInstanceTypeOfferings, DescribeInstances, DescribeSubnets, DescribeVolumes, DescribeVpcs, DetachVolume, RunInstances, TerminateInstances, Wait} diff --git a/.doc_gen/metadata/ec2_ebs_intermediate_metadata.yaml b/.doc_gen/metadata/ec2_ebs_intermediate_metadata.yaml new file mode 100644 index 00000000..9ce5a07c --- /dev/null +++ b/.doc_gen/metadata/ec2_ebs_intermediate_metadata.yaml @@ -0,0 +1,21 @@ +ec2_GettingStarted_022: + title: Working with Amazon EBS encryption, snapshots, and volume initialization + title_abbrev: Working with Amazon EBS encryption, snapshots, and volume initialization + synopsis_list: + - Enable Amazon EBS encryption by default + - Create an EBS snapshot + - Create and initialize a volume from a snapshot + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/022-ebs-intermediate + excerpts: + - description: + snippet_files: + - tuts/022-ebs-intermediate/ebs-intermediate.sh + services: + ec2: {CreateSnapshot, CreateVolume, DeleteSnapshot, DeleteVolume, DescribeAvailabilityZones, DescribeVolumes, DetachVolume, DisableEbsEncryptionByDefault, EnableEbsEncryptionByDefault, GetEbsDefaultKmsKeyId, GetEbsEncryptionByDefault, Wait} diff --git a/.doc_gen/metadata/ec2_ec2_basics_metadata.yaml b/.doc_gen/metadata/ec2_ec2_basics_metadata.yaml new file mode 100644 index 00000000..5598deb5 --- /dev/null +++ b/.doc_gen/metadata/ec2_ec2_basics_metadata.yaml @@ -0,0 +1,23 @@ +ec2_GettingStarted_013: + title: Getting started with Amazon EC2 + title_abbrev: Getting started with Amazon EC2 + synopsis_list: + - Create a key pair + - Create a security group + - Stop and start your instance + - Test Elastic IP persistence + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/013-ec2-basics + excerpts: + - description: + snippet_files: + - tuts/013-ec2-basics/ec2-basics.sh + services: + ec2: {AllocateAddress, AssociateAddress, AuthorizeSecurityGroupIngress, CreateKeyPair, CreateSecurityGroup, DeleteKeyPair, DeleteSecurityGroup, DescribeImages, DescribeInstances, DisassociateAddress, ReleaseAddress, RunInstances, StartInstances, StopInstances, TerminateInstances, Wait} + ssm: {GetParametersByPath} diff --git a/.doc_gen/metadata/ec2_marketplace_buyer_metadata.yaml b/.doc_gen/metadata/ec2_marketplace_buyer_metadata.yaml new file mode 100644 index 00000000..ad5a05d0 --- /dev/null +++ b/.doc_gen/metadata/ec2_marketplace_buyer_metadata.yaml @@ -0,0 +1,20 @@ +ec2_GettingStarted_030: + title: Get started with Marketplace Buyer using the CLI + title_abbrev: Get started with Marketplace Buyer + synopsis_list: + - Use ec2 AuthorizeSecurityGroupIngress + - Use ec2 CreateKeyPair + - Use ec2 CreateSecurityGroup + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/030-marketplace-buyer-gs + excerpts: + - description: + snippet_files: + - tuts/030-marketplace-buyer-gs/marketplace-buyer-getting-started.sh + services: + ec2: {AuthorizeSecurityGroupIngress, CreateKeyPair, CreateSecurityGroup, DeleteKeyPair, DeleteSecurityGroup, DescribeImages, DescribeInstances, RunInstances, TerminateInstances, Wait} diff --git a/.doc_gen/metadata/ec2_vpc_peering_metadata.yaml b/.doc_gen/metadata/ec2_vpc_peering_metadata.yaml new file mode 100644 index 00000000..d866cb2a --- /dev/null +++ b/.doc_gen/metadata/ec2_vpc_peering_metadata.yaml @@ -0,0 +1,22 @@ +ec2_GettingStarted_015: + title: Working with VPC peering connections + title_abbrev: Working with VPC peering connections + synopsis_list: + - Create VPCs for peering + - Create a VPC peering connection + - Update route tables + - Verify the VPC peering connection + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/015-vpc-peering + excerpts: + - description: + snippet_files: + - tuts/015-vpc-peering/vpc-peering.sh + services: + ec2: {AcceptVpcPeeringConnection, AssociateRouteTable, CreateRoute, CreateRouteTable, CreateSubnet, CreateVpc, CreateVpcPeeringConnection, DeleteRouteTable, DeleteSubnet, DeleteVpc, DeleteVpcPeeringConnection, DescribeVpcPeeringConnections, DescribeVpcs, DisassociateRouteTable, Wait} diff --git a/.doc_gen/metadata/ecr_amazon_elastic_metadata.yaml b/.doc_gen/metadata/ecr_amazon_elastic_metadata.yaml new file mode 100644 index 00000000..c7296c50 --- /dev/null +++ b/.doc_gen/metadata/ecr_amazon_elastic_metadata.yaml @@ -0,0 +1,21 @@ +ecr_GettingStarted_078: + title: Getting started with Amazon ECR + title_abbrev: Getting started with Amazon ECR + synopsis_list: + - Create a Docker image + - Create an Amazon ECR repository + - Delete resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/078-amazon-elastic-container-registry-gs + excerpts: + - description: + snippet_files: + - tuts/078-amazon-elastic-container-registry-gs/amazon-elastic-container-registry-gs.sh + services: + ecr: {BatchDeleteImage, CreateRepository, DeleteRepository, GetLoginPassword} + sts: {GetCallerIdentity} diff --git a/.doc_gen/metadata/ecs_amazon_ecs_metadata.yaml b/.doc_gen/metadata/ecs_amazon_ecs_metadata.yaml new file mode 100644 index 00000000..d8ef379e --- /dev/null +++ b/.doc_gen/metadata/ecs_amazon_ecs_metadata.yaml @@ -0,0 +1,24 @@ +ecs_GettingStarted_086: + title: Create an Amazon ECS Linux task for the Fargate launch type + title_abbrev: Create an Amazon ECS Linux task for the Fargate launch type + synopsis_list: + - Create the cluster + - Create a task definition + - Create the service + - Clean up + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/086-amazon-ecs-fargate-linux + excerpts: + - description: + snippet_files: + - tuts/086-amazon-ecs-fargate-linux/amazon-ecs-fargate-linux.sh + services: + ec2: {AuthorizeSecurityGroupIngress, CreateSecurityGroup, DeleteSecurityGroup, DescribeNetworkInterfaces, DescribeSecurityGroups, DescribeSubnets, DescribeVpcs} + ecs: {CreateCluster, CreateService, DeleteCluster, DeleteService, DeregisterTaskDefinition, DescribeServices, DescribeTasks, ListTaskDefinitions, ListTasks, RegisterTaskDefinition, UpdateService, Wait} + iam: {AttachRolePolicy, CreateRole, GetRole} + sts: {GetCallerIdentity} diff --git a/.doc_gen/metadata/ecs_ecs_ec2_metadata.yaml b/.doc_gen/metadata/ecs_ecs_ec2_metadata.yaml new file mode 100644 index 00000000..290f66df --- /dev/null +++ b/.doc_gen/metadata/ecs_ecs_ec2_metadata.yaml @@ -0,0 +1,24 @@ +ecs_GettingStarted_018: + title: Creating an Amazon ECS service for the EC2 launch type + title_abbrev: Creating an Amazon ECS service for the EC2 launch type + synopsis_list: + - Create an ECS cluster + - Create and monitor a service + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/018-ecs-ec2 + excerpts: + - description: + snippet_files: + - tuts/018-ecs-ec2/ecs-ec2-getting-started.sh + services: + ec2: {AuthorizeSecurityGroupIngress, CreateKeyPair, CreateSecurityGroup, DeleteKeyPair, DeleteSecurityGroup, DescribeInstances, DescribeSubnets, DescribeVpcs, RunInstances, TerminateInstances, Wait} + ecs: {CreateCluster, CreateService, DeleteCluster, DeleteService, DeregisterTaskDefinition, DescribeContainerInstances, DescribeServices, DescribeTasks, ListContainerInstances, ListServices, ListTasks, RegisterTaskDefinition, StopTask, UpdateService, Wait} + iam: {AddRoleToInstanceProfile, AttachRolePolicy, CreateInstanceProfile, CreateRole, GetRole, Wait} + ssm: {GetParameters} + sts: {GetCallerIdentity} diff --git a/.doc_gen/metadata/ecs_service_connect_metadata.yaml b/.doc_gen/metadata/ecs_service_connect_metadata.yaml new file mode 100644 index 00000000..a691a1d9 --- /dev/null +++ b/.doc_gen/metadata/ecs_service_connect_metadata.yaml @@ -0,0 +1,29 @@ +ecs_ServiceConnect_085: + title: Configure Amazon ECS Service Connect + title_abbrev: Configure Amazon ECS Service Connect + synopsis_list: + - Create the VPC infrastructure + - Set up logging + - Create the ECS cluster + - Configure IAM roles + - Create the service with Service Connect + - Verify the deployment + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/085-amazon-ecs-service-connect + excerpts: + - description: + snippet_files: + - tuts/085-amazon-ecs-service-connect/amazon-ecs-service-connect.sh + services: + cloudwatch-logs: {CreateLogGroup, DeleteLogGroup} + ec2: {AuthorizeSecurityGroupIngress, CreateSecurityGroup, DeleteSecurityGroup, DescribeSubnets, DescribeVpcs, Wait} + ecs: {CreateCluster, CreateService, DeleteCluster, DeleteService, DeregisterTaskDefinition, DescribeClusters, DescribeServices, DescribeTasks, ListTaskDefinitions, ListTasks, RegisterTaskDefinition, UpdateService, Wait} + iam: {AttachRolePolicy, CreateRole, DeleteRole, DetachRolePolicy, GetRole} + servicediscovery: {DeleteNamespace, DeleteService, ListNamespaces, ListServices} + sts: {GetCallerIdentity} diff --git a/.doc_gen/metadata/eks_eks_gs_metadata.yaml b/.doc_gen/metadata/eks_eks_gs_metadata.yaml new file mode 100644 index 00000000..849b9f79 --- /dev/null +++ b/.doc_gen/metadata/eks_eks_gs_metadata.yaml @@ -0,0 +1,26 @@ +eks_GettingStarted_034: + title: Getting started with Amazon EKS + title_abbrev: Getting started with Amazon EKS + synopsis_list: + - Create a VPC for your EKS cluster + - Create IAM roles for your EKS cluster + - Create your EKS cluster + - Configure kubectl to communicate with your cluster + - Create a managed node group + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/034-eks-gs + excerpts: + - description: + snippet_files: + - tuts/034-eks-gs/eks-gs.sh + services: + cloudformation: {CreateStack, DeleteStack, DescribeStacks, Wait} + eks: {CreateCluster, CreateNodegroup, DeleteCluster, DeleteNodegroup, DescribeCluster, DescribeNodegroup, ListNodegroups, UpdateKubeconfig, Wait} + iam: {AttachRolePolicy, CreateRole, DeleteRole, DetachRolePolicy, GetRole} + sts: {GetCallerIdentity} diff --git a/.doc_gen/metadata/elastic_load_balancing_v2_elastic_load_metadata.yaml b/.doc_gen/metadata/elastic_load_balancing_v2_elastic_load_metadata.yaml new file mode 100644 index 00000000..2ce2ddb6 --- /dev/null +++ b/.doc_gen/metadata/elastic_load_balancing_v2_elastic_load_metadata.yaml @@ -0,0 +1,25 @@ +elastic_load_balancing_v2_GettingStarted_058: + title: Getting started with Elastic Load Balancing + title_abbrev: Getting started with Elastic Load Balancing + synopsis_list: + - Create an Application Load Balancer + - Create a target group + - Create a listener + - Verify your configuration + - Add an HTTPS listener (optional) + - Add path-based routing (optional) + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/058-elastic-load-balancing-gs + excerpts: + - description: + snippet_files: + - tuts/058-elastic-load-balancing-gs/elastic-load-balancing-gs.sh + services: + ec2: {AuthorizeSecurityGroupIngress, CreateSecurityGroup, DeleteSecurityGroup, DescribeInstances, DescribeSubnets, DescribeVpcs} + elastic-load-balancing-v2: {CreateListener, CreateLoadBalancer, CreateTargetGroup, DeleteListener, DeleteLoadBalancer, DeleteTargetGroup, DescribeLoadBalancers, DescribeTargetHealth, Help, RegisterTargets, Wait} diff --git a/.doc_gen/metadata/emr_emr_gs_metadata.yaml b/.doc_gen/metadata/emr_emr_gs_metadata.yaml new file mode 100644 index 00000000..3efe6273 --- /dev/null +++ b/.doc_gen/metadata/emr_emr_gs_metadata.yaml @@ -0,0 +1,22 @@ +emr_GettingStarted_037: + title: Getting started with Amazon EMR + title_abbrev: Getting started with Amazon EMR + synopsis_list: + - Create an EC2 key pair + - Set up storage and prepare your application + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/037-emr-gs + excerpts: + - description: + snippet_files: + - tuts/037-emr-gs/emr-gs.sh + services: + ec2: {CreateKeyPair, DescribeKeyPairs} + emr: {AddSteps, CreateCluster, CreateDefaultRoles, DescribeCluster, DescribeStep, Ssh, TerminateClusters, Wait} + s3: {Cp, Ls, Mb, Rb, Rm} diff --git a/.doc_gen/metadata/fargate_metadata.yaml b/.doc_gen/metadata/fargate_metadata.yaml index 1caf4efe..63734357 100644 --- a/.doc_gen/metadata/fargate_metadata.yaml +++ b/.doc_gen/metadata/fargate_metadata.yaml @@ -1,14 +1,12 @@ fargate_GettingStarted: - title: Get started with Batch and Fargate using the CLI - title_abbrev: Get started with Batch and Fargate + title: Getting started with Batch and Fargate + title_abbrev: Getting started with Batch and Fargate synopsis_list: - - Create an IAM execution role for ECS tasks - - Create a managed Fargate compute environment - - Create a job queue with priority settings - - Register a job definition for containerized workloads - - Submit and monitor a batch job execution - - View job output in CloudWatch Logs - - Clean up resources in proper dependency order + - Create an IAM execution role + - Create a compute environment + - Create a job queue + - Create a job definition + - Clean up resources category: Scenarios languages: Bash: diff --git a/.doc_gen/metadata/glue_glue_gs_metadata.yaml b/.doc_gen/metadata/glue_glue_gs_metadata.yaml new file mode 100644 index 00000000..e8addda0 --- /dev/null +++ b/.doc_gen/metadata/glue_glue_gs_metadata.yaml @@ -0,0 +1,20 @@ +glue_GettingStarted_024: + title: Getting started with the Glue Data Catalog + title_abbrev: Getting started with the Glue Data Catalog + synopsis_list: + - Create a database + - Create a table + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/024-glue-gs + excerpts: + - description: + snippet_files: + - tuts/024-glue-gs/glue-gs.sh + services: + glue: {CreateDatabase, CreateTable, DeleteDatabase, DeleteTable, GetDatabase, GetTable} diff --git a/.doc_gen/metadata/iam_amazon_managed_metadata.yaml b/.doc_gen/metadata/iam_amazon_managed_metadata.yaml new file mode 100644 index 00000000..9f06b1f3 --- /dev/null +++ b/.doc_gen/metadata/iam_amazon_managed_metadata.yaml @@ -0,0 +1,24 @@ +iam_GettingStarted_044: + title: Creating an Amazon Managed Grafana workspace + title_abbrev: Creating an Amazon Managed Grafana workspace + synopsis_list: + - Create an IAM role for your workspace + - Create a Grafana workspace + - Configure authentication + - Configure optional settings + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/044-amazon-managed-grafana-gs + excerpts: + - description: + snippet_files: + - tuts/044-amazon-managed-grafana-gs/amazon-managed-grafana-gs.sh + services: + grafana: {CreateWorkspace, DeleteWorkspace, DescribeWorkspace} + iam: {AttachRolePolicy, CreatePolicy, CreateRole, DeletePolicy, DeleteRole, DetachRolePolicy} + sts: {GetCallerIdentity} diff --git a/.doc_gen/metadata/iam_aws_fault_metadata.yaml b/.doc_gen/metadata/iam_aws_fault_metadata.yaml new file mode 100644 index 00000000..5e2dfc81 --- /dev/null +++ b/.doc_gen/metadata/iam_aws_fault_metadata.yaml @@ -0,0 +1,27 @@ +iam_GettingStarted_069: + title: Run CPU stress tests on EC2 instances using FIS + title_abbrev: Run CPU stress tests on EC2 instances using FIS + synopsis_list: + - Create IAM roles + - Create a CloudWatch alarm + - Create an experiment template + - Run the experiment + - Verify the results + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/069-aws-fault-injection-service-gs + excerpts: + - description: + snippet_files: + - tuts/069-aws-fault-injection-service-gs/aws-fault-injection-service-getting-started.sh + services: + cloudwatch: {DeleteAlarms, DescribeAlarms, GetMetricData, PutMetricAlarm} + ec2: {DescribeImages, MonitorInstances, RunInstances, TerminateInstances, Wait} + fis: {CreateExperimentTemplate, DeleteExperimentTemplate, GetExperiment, StartExperiment, StopExperiment} + iam: {AddRoleToInstanceProfile, AttachRolePolicy, CreateInstanceProfile, CreateRole, DeleteInstanceProfile, DeleteRole, DeleteRolePolicy, DetachRolePolicy, GetRole, PutRolePolicy, RemoveRoleFromInstanceProfile} + sts: {GetCallerIdentity} diff --git a/.doc_gen/metadata/iam_aws_step_metadata.yaml b/.doc_gen/metadata/iam_aws_step_metadata.yaml new file mode 100644 index 00000000..733a9a72 --- /dev/null +++ b/.doc_gen/metadata/iam_aws_step_metadata.yaml @@ -0,0 +1,22 @@ +iam_GettingStarted_080: + title: Getting started with Step Functions + title_abbrev: Getting started with Step Functions + synopsis_list: + - Create an IAM role for Step Functions + - Create your first state machine + - Start your state machine execution + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/080-aws-step-functions-gs + excerpts: + - description: + snippet_files: + - tuts/080-aws-step-functions-gs/aws-step-functions-gs.sh + services: + iam: {AttachRolePolicy, CreatePolicy, CreateRole, DeletePolicy, DeleteRole, DetachRolePolicy} + sfn: {CreateStateMachine, DeleteStateMachine, DescribeExecution, StartExecution, UpdateStateMachine} diff --git a/.doc_gen/metadata/iam_aws_systems_metadata.yaml b/.doc_gen/metadata/iam_aws_systems_metadata.yaml new file mode 100644 index 00000000..05cb40d0 --- /dev/null +++ b/.doc_gen/metadata/iam_aws_systems_metadata.yaml @@ -0,0 +1,24 @@ +iam_GettingStarted_046: + title: Setting up Systems Manager + title_abbrev: Setting up Systems Manager + synopsis_list: + - Create IAM permissions for Systems Manager + - Create an IAM role for Systems Manager + - Configure Systems Manager + - Verify the setup + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/046-aws-systems-manager-gs + excerpts: + - description: + snippet_files: + - tuts/046-aws-systems-manager-gs/aws-systems-manager-gs.sh + services: + iam: {AttachRolePolicy, CreatePolicy, CreateRole, DeletePolicy, DeleteRole, DetachRolePolicy} + ssm: {CreateConfigurationManager, DeleteConfigurationManager, GetConfigurationManager} + sts: {GetCallerIdentity} diff --git a/.doc_gen/metadata/iam_cloudwatch_streams_metadata.yaml b/.doc_gen/metadata/iam_cloudwatch_streams_metadata.yaml new file mode 100644 index 00000000..422b72ed --- /dev/null +++ b/.doc_gen/metadata/iam_cloudwatch_streams_metadata.yaml @@ -0,0 +1,23 @@ +iam_GettingStarted_032: + title: Using property variables in CloudWatch dashboards to monitor multiple Lambda functions + title_abbrev: Using property variables in CloudWatch dashboards to monitor multiple Lambda functions + synopsis_list: + - Create Lambda functions for monitoring + - Create a CloudWatch dashboard + - Add a property variable to the dashboard + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/032-cloudwatch-streams + excerpts: + - description: + snippet_files: + - tuts/032-cloudwatch-streams/cloudwatch-streams.sh + services: + cloudwatch: {DeleteDashboards, GetDashboard, PutDashboard} + iam: {AttachRolePolicy, CreateRole, DeleteRole, DetachRolePolicy} + lambda: {CreateFunction, DeleteFunction, Invoke} diff --git a/.doc_gen/metadata/iam_sagemaker_featurestore_metadata.yaml b/.doc_gen/metadata/iam_sagemaker_featurestore_metadata.yaml new file mode 100644 index 00000000..549f092f --- /dev/null +++ b/.doc_gen/metadata/iam_sagemaker_featurestore_metadata.yaml @@ -0,0 +1,24 @@ +iam_GettingStarted_028: + title: Getting started with Amazon SageMaker Feature Store + title_abbrev: Getting started with Amazon SageMaker Feature Store + synopsis_list: + - Set up IAM permissions + - Create a SageMaker execution role + - Create feature groups + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/028-sagemaker-featurestore + excerpts: + - description: + snippet_files: + - tuts/028-sagemaker-featurestore/sagemaker-featurestore.sh + services: + iam: {AttachRolePolicy, CreateRole, DeleteRole, DetachRolePolicy, GetRole} + s3: {CreateBucket, DeleteBucket, PutPublicAccessBlock, Rm} + sagemaker: {CreateFeatureGroup, DeleteFeatureGroup, DescribeFeatureGroup, ListFeatureGroups} + sts: {GetCallerIdentity} diff --git a/.doc_gen/metadata/iot_aws_iot_metadata.yaml b/.doc_gen/metadata/iot_aws_iot_metadata.yaml new file mode 100644 index 00000000..995c15c6 --- /dev/null +++ b/.doc_gen/metadata/iot_aws_iot_metadata.yaml @@ -0,0 +1,26 @@ +iot_GettingStarted_079: + title: Getting Started with IoT Device Defender + title_abbrev: Getting Started with IoT Device Defender + synopsis_list: + - Create Required IAM Roles + - Enable IoT Device Defender Audit Checks + - Run an On-Demand Audit + - Create a Mitigation Action + - Apply Mitigation Actions to Findings + - Set Up SNS Notifications (Optional) + - Enable IoT Logging + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/079-aws-iot-device-defender-gs + excerpts: + - description: + snippet_files: + - tuts/079-aws-iot-device-defender-gs/aws-iot-device-defender-gs.sh + services: + iam: {AttachRolePolicy, CreateRole, DeleteRole, DeleteRolePolicy, DetachRolePolicy, GetRole, ListRolePolicies, PutRolePolicy} + iot: {CreateMitigationAction, DeleteAccountAuditConfiguration, DeleteMitigationAction, DescribeAccountAuditConfiguration, DescribeAuditTask, GetLoggingOptions, GetV2LoggingOptions, ListAuditFindings, ListAuditMitigationActionsTasks, ListMitigationActions, SetLoggingOptions, SetV2LoggingOptions, StartAuditMitigationActionsTask, StartOnDemandAuditTask, UpdateAccountAuditConfiguration} + sns: {CreateTopic, DeleteTopic, ListTopics} diff --git a/.doc_gen/metadata/iot_core_gs_metadata.yaml b/.doc_gen/metadata/iot_core_gs_metadata.yaml new file mode 100644 index 00000000..67cd80c5 --- /dev/null +++ b/.doc_gen/metadata/iot_core_gs_metadata.yaml @@ -0,0 +1,22 @@ +iot_GettingStarted_063: + title: Getting started with IoT Core + title_abbrev: Getting started with IoT Core + synopsis_list: + - Create IoT resources + - Configure your device + - Run the sample application + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/063-aws-iot-core-gs + excerpts: + - description: + snippet_files: + - tuts/063-aws-iot-core-gs/aws-iot-core-gs.sh + services: + iot: {AttachPolicy, AttachThingPrincipal, CreateKeysAndCertificate, CreatePolicy, CreateThing, DeleteCertificate, DeletePolicy, DeleteThing, DescribeEndpoint, DetachPolicy, DetachThingPrincipal, UpdateCertificate} + sts: {GetCallerIdentity} diff --git a/.doc_gen/metadata/lambda_lambda_gettingstarted_metadata.yaml b/.doc_gen/metadata/lambda_lambda_gettingstarted_metadata.yaml new file mode 100644 index 00000000..6d5b5109 --- /dev/null +++ b/.doc_gen/metadata/lambda_lambda_gettingstarted_metadata.yaml @@ -0,0 +1,24 @@ +lambda_GettingStarted_019: + title: Creating your first Lambda function + title_abbrev: Creating your first Lambda function + synopsis_list: + - Create an IAM role for Lambda + - Create function code + - Create a Lambda function + - Test your Lambda function + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/019-lambda-gettingstarted + excerpts: + - description: + snippet_files: + - tuts/019-lambda-gettingstarted/lambda-gettingstarted.sh + services: + cloudwatch-logs: {DeleteLogGroup, DescribeLogStreams, GetLogEvents} + iam: {AttachRolePolicy, CreateRole, DeleteRole, DetachRolePolicy} + lambda: {CreateFunction, DeleteFunction, GetFunction, GetFunctionConfiguration, Invoke} diff --git a/.doc_gen/metadata/lightsail_metadata.yaml b/.doc_gen/metadata/lightsail_metadata.yaml index 6648b1f9..2a152fe9 100644 --- a/.doc_gen/metadata/lightsail_metadata.yaml +++ b/.doc_gen/metadata/lightsail_metadata.yaml @@ -1,14 +1,11 @@ lightsail_GettingStarted: - title: Get started with Amazon Lightsail using the CLI - title_abbrev: Get started with Lightsail + title: Getting started with Amazon Lightsail + title_abbrev: Getting started with Amazon Lightsail synopsis_list: - - Explore available blueprints and bundles for instance creation - - Create a Lightsail instance with Amazon Linux 2023 - - Monitor instance status until running - - Download default key pair for SSH access - - Create and attach additional block storage disk - - Create an instance snapshot for backup - - Clean up resources to avoid ongoing charges + - Create an instance + - Add storage to your instance + - Create a snapshot + - Clean up resources category: Scenarios languages: Bash: diff --git a/.doc_gen/metadata/mediaconnect_aws_elemental_metadata.yaml b/.doc_gen/metadata/mediaconnect_aws_elemental_metadata.yaml new file mode 100644 index 00000000..201f3a1a --- /dev/null +++ b/.doc_gen/metadata/mediaconnect_aws_elemental_metadata.yaml @@ -0,0 +1,22 @@ +mediaconnect_GettingStarted_081: + title: Getting started with Elemental MediaConnect + title_abbrev: Getting started with Elemental MediaConnect + synopsis_list: + - Verify access to Elemental MediaConnect + - Create a flow + - Add an output + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/081-aws-elemental-mediaconnect-gs + excerpts: + - description: + snippet_files: + - tuts/081-aws-elemental-mediaconnect-gs/aws-elemental-mediaconnect-gs.sh + services: + ec2: {DescribeAvailabilityZones} + mediaconnect: {AddFlowOutputs, CreateFlow, DeleteFlow, DescribeFlow, GrantFlowEntitlements, ListFlows, StopFlow} diff --git a/.doc_gen/metadata/opensearch_opensearch_service_metadata.yaml b/.doc_gen/metadata/opensearch_opensearch_service_metadata.yaml new file mode 100644 index 00000000..1a4cd691 --- /dev/null +++ b/.doc_gen/metadata/opensearch_opensearch_service_metadata.yaml @@ -0,0 +1,21 @@ +opensearch_GettingStarted_016: + title: Getting started with Amazon OpenSearch Service + title_abbrev: Getting started with Amazon OpenSearch Service + synopsis_list: + - Create an OpenSearch Service domain + - Upload data to your domain + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/016-opensearch-service-gs + excerpts: + - description: + snippet_files: + - tuts/016-opensearch-service-gs/opensearch-service-gs.sh + services: + opensearch: {CreateDomain, DeleteDomain, DescribeDomain} + sts: {GetCallerIdentity} diff --git a/.doc_gen/metadata/payment_cryptography_aws_payment_metadata.yaml b/.doc_gen/metadata/payment_cryptography_aws_payment_metadata.yaml new file mode 100644 index 00000000..0e4c9c7f --- /dev/null +++ b/.doc_gen/metadata/payment_cryptography_aws_payment_metadata.yaml @@ -0,0 +1,20 @@ +payment_cryptography_GettingStarted_067: + title: Getting started with Payment Cryptography + title_abbrev: Getting started with Payment Cryptography + synopsis_list: + - Create a key + - Verify the CVV2 value + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/067-aws-payment-cryptography-gs + excerpts: + - description: + snippet_files: + - tuts/067-aws-payment-cryptography-gs/aws-payment-cryptography-gs.sh + services: + payment-cryptography: {CreateKey, DeleteKey, RestoreKey} diff --git a/.doc_gen/metadata/pinpoint_aws_end_metadata.yaml b/.doc_gen/metadata/pinpoint_aws_end_metadata.yaml new file mode 100644 index 00000000..d3d0b73f --- /dev/null +++ b/.doc_gen/metadata/pinpoint_aws_end_metadata.yaml @@ -0,0 +1,22 @@ +pinpoint_GettingStarted_049: + title: Getting started with End User Messaging Push + title_abbrev: Getting started with End User Messaging Push + synopsis_list: + - Create an application + - Enable push notification channels + - Send a push notification + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/049-aws-end-user-messaging-gs + excerpts: + - description: + snippet_files: + - tuts/049-aws-end-user-messaging-gs/aws-end-user-messaging-gs.sh + services: + pinpoint: {CreateApp, DeleteApp, GetApp, GetApps, SendMessages, UpdateApnsChannel, UpdateGcmChannel} + sts: {GetCallerIdentity} diff --git a/.doc_gen/metadata/polly_amazon_polly_metadata.yaml b/.doc_gen/metadata/polly_amazon_polly_metadata.yaml new file mode 100644 index 00000000..b52e08be --- /dev/null +++ b/.doc_gen/metadata/polly_amazon_polly_metadata.yaml @@ -0,0 +1,18 @@ +polly_GettingStarted_082: + title: Getting started with Amazon Polly + title_abbrev: Getting started with Amazon Polly + synopsis_list: + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/082-amazon-polly-gs + excerpts: + - description: + snippet_files: + - tuts/082-amazon-polly-gs/amazon-polly-getting-started.sh + services: + polly: {DeleteLexicon, DescribeVoices, GetLexicon, Help, ListLexicons, PutLexicon, SynthesizeSpeech} diff --git a/.doc_gen/metadata/rds_rds_gs_metadata.yaml b/.doc_gen/metadata/rds_rds_gs_metadata.yaml new file mode 100644 index 00000000..ba5b1f79 --- /dev/null +++ b/.doc_gen/metadata/rds_rds_gs_metadata.yaml @@ -0,0 +1,23 @@ +rds_GettingStarted_036: + title: Creating an Amazon RDS DB instance + title_abbrev: Creating an Amazon RDS DB instance + synopsis_list: + - Set up networking components + - Create a DB subnet group + - Create a DB instance + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/036-rds-gs + excerpts: + - description: + snippet_files: + - tuts/036-rds-gs/rds-gs.sh + services: + ec2: {AuthorizeSecurityGroupIngress, CreateSecurityGroup, DeleteSecurityGroup, DescribeSubnets, DescribeVpcs} + rds: {CreateDbInstance, CreateDbSubnetGroup, DeleteDbInstance, DeleteDbSubnetGroup, DescribeDbInstances, Wait} + secrets-manager: {CreateSecret, DeleteSecret, GetSecretValue} diff --git a/.doc_gen/metadata/redshift_redshift_provisioned_metadata.yaml b/.doc_gen/metadata/redshift_redshift_provisioned_metadata.yaml new file mode 100644 index 00000000..2ac23ed1 --- /dev/null +++ b/.doc_gen/metadata/redshift_redshift_provisioned_metadata.yaml @@ -0,0 +1,23 @@ +redshift_GettingStarted_039: + title: Getting started with Amazon Redshift provisioned clusters + title_abbrev: Getting started with Amazon Redshift provisioned clusters + synopsis_list: + - Create a Redshift cluster + - Create an IAM role for S3 access + - Create tables and load data + - Run example queries + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/039-redshift-provisioned + excerpts: + - description: + snippet_files: + - tuts/039-redshift-provisioned/redshift-provisioned.sh + services: + iam: {CreateRole, DeleteRole, DeleteRolePolicy, GetRole, PutRolePolicy} + redshift: {CreateCluster, DeleteCluster, DescribeClusters, ModifyClusterIamRoles, Wait} diff --git a/.doc_gen/metadata/redshift_redshift_serverless_metadata.yaml b/.doc_gen/metadata/redshift_redshift_serverless_metadata.yaml new file mode 100644 index 00000000..c33cee98 --- /dev/null +++ b/.doc_gen/metadata/redshift_redshift_serverless_metadata.yaml @@ -0,0 +1,26 @@ +redshift_GettingStarted_038: + title: Get started with Redshift Serverless using the CLI + title_abbrev: Get started with Redshift Serverless + synopsis_list: + - Use secrets-manager CreateSecret + - Use secrets-manager DeleteSecret + - Use secrets-manager GetSecretValue + - Use redshift CreateNamespace + - Use redshift CreateWorkgroup + - Use redshift DeleteNamespace + - Use iam CreateRole + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/038-redshift-serverless + excerpts: + - description: + snippet_files: + - tuts/038-redshift-serverless/redshift-serverless.sh + services: + iam: {CreateRole, DeleteRole, DeleteRolePolicy, GetRole, PutRolePolicy} + redshift: {CreateNamespace, CreateWorkgroup, DeleteNamespace, DeleteWorkgroup, GetNamespace, GetWorkgroup, UpdateNamespace} + secrets-manager: {CreateSecret, DeleteSecret, GetSecretValue} diff --git a/.doc_gen/metadata/s3_amazon_textract_metadata.yaml b/.doc_gen/metadata/s3_amazon_textract_metadata.yaml new file mode 100644 index 00000000..7a9d7323 --- /dev/null +++ b/.doc_gen/metadata/s3_amazon_textract_metadata.yaml @@ -0,0 +1,21 @@ +s3_GettingStarted_074: + title: Getting started with Amazon Textract + title_abbrev: Getting started with Amazon Textract + synopsis_list: + - Create an S3 bucket + - Upload a document to S3 + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/074-amazon-textract-gs + excerpts: + - description: + snippet_files: + - tuts/074-amazon-textract-gs/amazon-textract-getting-started.sh + services: + s3: {Cp, Mb, Rb, Rm} + textract: {AnalyzeDocument, Help} diff --git a/.doc_gen/metadata/s3_metadata.yaml b/.doc_gen/metadata/s3_metadata.yaml index aee37ea7..0923ebf6 100644 --- a/.doc_gen/metadata/s3_metadata.yaml +++ b/.doc_gen/metadata/s3_metadata.yaml @@ -1,16 +1,14 @@ s3_GettingStarted: - title: Get started with Amazon S3 using the CLI - title_abbrev: Get started with S3 + title: Getting started with Amazon S3 + title_abbrev: Getting started with Amazon S3 synopsis_list: - - Create an S3 bucket with unique naming and regional configuration - - Configure bucket security settings including public access blocking - - Enable versioning and default encryption for data protection - - Upload objects with and without custom metadata - - Download objects from the bucket to local storage - - Copy objects within the bucket to organize data in folders - - List bucket contents and objects with specific prefixes - - Add tags to buckets for resource management - - Clean up all resources including versioned objects + - Create your first S3 bucket + - Upload an object + - Enable versioning + - Configure default encryption + - Add tags to your bucket + - List objects and versions + - Clean up resources category: Scenarios languages: Bash: diff --git a/.doc_gen/metadata/secrets_manager_aws_secrets_metadata.yaml b/.doc_gen/metadata/secrets_manager_aws_secrets_metadata.yaml new file mode 100644 index 00000000..89a91f37 --- /dev/null +++ b/.doc_gen/metadata/secrets_manager_aws_secrets_metadata.yaml @@ -0,0 +1,24 @@ +secrets_manager_GettingStarted_073: + title: Moving hardcoded secrets to Secrets Manager + title_abbrev: Moving hardcoded secrets to Secrets Manager + synopsis_list: + - Create IAM roles + - Create a secret in Secrets Manager + - Update your application code + - Update the secret + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/073-aws-secrets-manager-gs + excerpts: + - description: + snippet_files: + - tuts/073-aws-secrets-manager-gs/aws-secrets-manager-gs.sh + services: + iam: {AttachRolePolicy, CreateRole, DeleteRole, DetachRolePolicy} + secrets-manager: {CreateSecret, DeleteSecret, GetSecretValue, PutResourcePolicy, UpdateSecret} + sts: {GetCallerIdentity} diff --git a/.doc_gen/metadata/ses_ses_gs_metadata.yaml b/.doc_gen/metadata/ses_ses_gs_metadata.yaml new file mode 100644 index 00000000..ac6e14e5 --- /dev/null +++ b/.doc_gen/metadata/ses_ses_gs_metadata.yaml @@ -0,0 +1,22 @@ +ses_GettingStarted_033: + title: Setting up Amazon Simple Email Service (SES) + title_abbrev: Setting up Amazon Simple Email Service (SES) + synopsis_list: + - Verify an email address + - Verify a domain (optional) + - Check your sending limits + - Send a test email + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/033-ses-gs + excerpts: + - description: + snippet_files: + - tuts/033-ses-gs/ses-gs.sh + services: + ses: {DeleteIdentity, GetIdentityVerificationAttributes, GetSendQuota, ListIdentities, SendEmail, VerifyDomainDkim, VerifyDomainIdentity, VerifyEmailIdentity} diff --git a/.doc_gen/metadata/sns_amazon_simple_metadata.yaml b/.doc_gen/metadata/sns_amazon_simple_metadata.yaml new file mode 100644 index 00000000..955def85 --- /dev/null +++ b/.doc_gen/metadata/sns_amazon_simple_metadata.yaml @@ -0,0 +1,22 @@ +sns_GettingStarted_048: + title: Create an Amazon SNS topic and publish messages + title_abbrev: Create an Amazon SNS topic and publish messages + synopsis_list: + - Create an Amazon SNS topic + - Subscribe an email endpoint to the topic + - Verify your subscription + - Publish a message to the topic + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/048-amazon-simple-notification-service-gs + excerpts: + - description: + snippet_files: + - tuts/048-amazon-simple-notification-service-gs/amazon-simple-notification-service-gs.sh + services: + sns: {CreateTopic, DeleteTopic, ListSubscriptionsByTopic, Publish, Subscribe, Unsubscribe} diff --git a/.doc_gen/metadata/support_aws_support_metadata.yaml b/.doc_gen/metadata/support_aws_support_metadata.yaml new file mode 100644 index 00000000..0e45fea9 --- /dev/null +++ b/.doc_gen/metadata/support_aws_support_metadata.yaml @@ -0,0 +1,20 @@ +support_GettingStarted_062: + title: Getting started with Support + title_abbrev: Getting started with Support + synopsis_list: + - Check available services and severity levels + - Create a support case + - Add communications to a case + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/062-aws-support-gs + excerpts: + - description: + snippet_files: + - tuts/062-aws-support-gs/aws-support-gs.sh + services: + support: {AddCommunicationToCase, CreateCase, DescribeCases, DescribeCommunications, DescribeServices, DescribeSeverityLevels, ResolveCase} diff --git a/.doc_gen/metadata/vpc_gs_metadata.yaml b/.doc_gen/metadata/vpc_gs_metadata.yaml index 4db43d4d..fc338b79 100644 --- a/.doc_gen/metadata/vpc_gs_metadata.yaml +++ b/.doc_gen/metadata/vpc_gs_metadata.yaml @@ -1,16 +1,14 @@ vpc_GettingStartedCLI: - title: Get started using Amazon VPC using the CLI - title_abbrev: Get started with Amazon VPC + title: Getting started with Amazon VPC + title_abbrev: Create a basic VPC synopsis_list: - - Set up your account - - Create and configure a VPC - - Configure your network - - Configure security - - Deploy resources - - Test and verify - - Clean up resources - - Consider production implications - - Consider security implications + - Create a VPC + - Create subnets + - Configure internet connectivity + - Create a NAT Gateway + - Configure subnet settings + - Create security groups + - Verify your VPC configuration category: Scenarios languages: Bash: @@ -28,7 +26,7 @@ vpc_GettingStartedCLI: vpc_GettingStartedIpam: title: Get started using Amazon VPC IPAM using the CLI - title_abbrev: Get started with VPC IPAM + title_abbrev: VPC with IPAM synopsis_list: - Set up and configure Amazon VPC IP Address Manager (IPAM) using the CLI. - Create an IPAM with operating regions (e.g., us-east-1, us-west-2). @@ -57,7 +55,7 @@ vpc_GettingStartedIpam: vpc_GettingStartedPrivate: title: Create a VPC with private subnets and NAT gateways using the CLI - title_abbrev: Create a VPC with private subnets and NAT gateways + title_abbrev: VPC with private servers synopsis_list: - Create a VPC with private subnets and NAT gateways using the CLI. - Set up the necessary components including VPC, subnets, route tables, and NAT gateways. diff --git a/.doc_gen/metadata/vpc_lattice_amazon_vpc_metadata.yaml b/.doc_gen/metadata/vpc_lattice_amazon_vpc_metadata.yaml new file mode 100644 index 00000000..e672c767 --- /dev/null +++ b/.doc_gen/metadata/vpc_lattice_amazon_vpc_metadata.yaml @@ -0,0 +1,25 @@ +vpc_lattice_GettingStarted_055: + title: Creating and managing a VPC Lattice service network + title_abbrev: Creating and managing a VPC Lattice service network + synopsis_list: + - Create a service network + - Create a service + - List available VPCs + - List security groups for the selected VPC + - List service associations + - List VPC associations + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/055-amazon-vpc-lattice-gs + excerpts: + - description: + snippet_files: + - tuts/055-amazon-vpc-lattice-gs/amazon-vpc-lattice-getting-started.sh + services: + ec2: {DescribeSecurityGroups, DescribeVpcs} + vpc-lattice: {CreateService, CreateServiceNetwork, CreateServiceNetworkServiceAssociation, CreateServiceNetworkVpcAssociation, DeleteService, DeleteServiceNetwork, DeleteServiceNetworkServiceAssociation, DeleteServiceNetworkVpcAssociation, GetService, GetServiceNetwork, GetServiceNetworkServiceAssociation, GetServiceNetworkVpcAssociation, ListServiceNetworkServiceAssociations, ListServiceNetworkVpcAssociations} diff --git a/.doc_gen/metadata/vpc_transit_gateway_metadata.yaml b/.doc_gen/metadata/vpc_transit_gateway_metadata.yaml index 3db6411b..52875b03 100644 --- a/.doc_gen/metadata/vpc_transit_gateway_metadata.yaml +++ b/.doc_gen/metadata/vpc_transit_gateway_metadata.yaml @@ -1,14 +1,12 @@ vpc_TransitGatewayGettingStarted: - title: Get started with Transit Gateway using the CLI - title_abbrev: Get started with Transit Gateway + title: Getting started with Amazon VPC Transit Gateway + title_abbrev: Getting started with Amazon VPC Transit Gateway synopsis_list: - - Create a transit gateway with DNS support and default route table settings - - Wait for the transit gateway to become available - - Attach two VPCs to the transit gateway using subnets - - Wait for VPC attachments to become available - - Add routes between VPCs through the transit gateway - - Test connectivity between VPC resources - - Clean up resources including routes, attachments, and transit gateway + - Create a transit gateway + - Attach your VPCs to your transit gateway + - Add routes between the transit gateway and your VPCs + - Test the transit gateway + - Clean up resources category: Scenarios languages: Bash: diff --git a/.doc_gen/metadata/wafv2_aws_waf_metadata.yaml b/.doc_gen/metadata/wafv2_aws_waf_metadata.yaml new file mode 100644 index 00000000..f02f79c1 --- /dev/null +++ b/.doc_gen/metadata/wafv2_aws_waf_metadata.yaml @@ -0,0 +1,24 @@ +wafv2_GettingStarted_052: + title: Getting started with WAF + title_abbrev: Getting started with WAF + synopsis_list: + - Create a web ACL + - Add a string match rule + - Add managed rules + - Configure logging + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/052-aws-waf-gs + excerpts: + - description: + snippet_files: + - tuts/052-aws-waf-gs/aws-waf-gs.sh + services: + cloudfront: {ListDistributions} + sts: {GetCallerIdentity} + wafv2: {AssociateWebAcl, CreateWebAcl, DeleteWebAcl, DisassociateWebAcl, GetWebAcl, UpdateWebAcl} diff --git a/.doc_gen/metadata/workspaces_workspaces_personal_metadata.yaml b/.doc_gen/metadata/workspaces_workspaces_personal_metadata.yaml new file mode 100644 index 00000000..9c98fe4c --- /dev/null +++ b/.doc_gen/metadata/workspaces_workspaces_personal_metadata.yaml @@ -0,0 +1,22 @@ +workspaces_GettingStarted_035: + title: Creating and managing Amazon WorkSpaces Personal + title_abbrev: Creating and managing Amazon WorkSpaces Personal + synopsis_list: + - Verify WorkSpaces availability in your region + - List available WorkSpaces bundles + - Create a WorkSpace + - Check the status of your WorkSpace + - Clean up resources + category: Scenarios + languages: + Bash: + versions: + - sdk_version: 2 + github_name: "Sample developer tutorials" + github: https://github.com/aws-samples/sample-developer-tutorials/tree/main/tuts/035-workspaces-personal + excerpts: + - description: + snippet_files: + - tuts/035-workspaces-personal/workspaces-personal.sh + services: + workspaces: {CreateWorkspaces, DeregisterWorkspaceDirectory, DescribeWorkspaceBundles, DescribeWorkspaceDirectories, DescribeWorkspaces, RegisterWorkspaceDirectory, TerminateWorkspaces} diff --git a/.doc_gen/validation.yaml b/.doc_gen/validation.yaml new file mode 100644 index 00000000..128a0caa --- /dev/null +++ b/.doc_gen/validation.yaml @@ -0,0 +1,5 @@ +allow_list: + - "bPxRfiCYEXAMPLEKEY/wJalrXUtnFEMI/K7MDENG" + - "role/AmazonEC2ContainerServiceforEC2Role" +sample_files: + - "README.md" diff --git a/cfn/cleanup-bucket.sh b/cfn/cleanup-bucket.sh new file mode 100755 index 00000000..38c6d712 --- /dev/null +++ b/cfn/cleanup-bucket.sh @@ -0,0 +1,50 @@ +#!/bin/bash +# Empty and delete the shared tutorial S3 bucket, then delete the CloudFormation stack. +# Usage: ./cfn/cleanup-bucket.sh +set -eo pipefail + +STACK_NAME="tutorial-prereqs-bucket" + +BUCKET_NAME=$(aws cloudformation describe-stacks --stack-name "$STACK_NAME" \ + --query 'Stacks[0].Outputs[?OutputKey==`BucketName`].OutputValue' --output text 2>/dev/null) + +if [ -z "$BUCKET_NAME" ] || [ "$BUCKET_NAME" = "None" ]; then + echo "No bucket stack found." + exit 0 +fi + +echo "Bucket: $BUCKET_NAME" +echo "" +echo "Contents:" +aws s3 ls "s3://$BUCKET_NAME/" 2>/dev/null || echo " (empty)" +echo "" +echo "This will permanently delete all objects and the bucket itself." +read -rp "Type the bucket name to confirm: " CONFIRM + +if [ "$CONFIRM" != "$BUCKET_NAME" ]; then + echo "Bucket name does not match. Aborting." + exit 1 +fi + +echo "" +echo "Emptying bucket..." +aws s3 rm "s3://$BUCKET_NAME" --recursive --quiet + +aws s3api list-object-versions --bucket "$BUCKET_NAME" \ + --query '{Objects: Versions[].{Key:Key,VersionId:VersionId}, Quiet: true}' \ + --output json 2>/dev/null | \ + aws s3api delete-objects --bucket "$BUCKET_NAME" --delete file:///dev/stdin > /dev/null 2>&1 || true + +aws s3api list-object-versions --bucket "$BUCKET_NAME" \ + --query '{Objects: DeleteMarkers[].{Key:Key,VersionId:VersionId}, Quiet: true}' \ + --output json 2>/dev/null | \ + aws s3api delete-objects --bucket "$BUCKET_NAME" --delete file:///dev/stdin > /dev/null 2>&1 || true + +echo "Deleting bucket: $BUCKET_NAME" +aws s3api delete-bucket --bucket "$BUCKET_NAME" + +echo "Deleting stack: $STACK_NAME" +aws cloudformation delete-stack --stack-name "$STACK_NAME" +aws cloudformation wait stack-delete-complete --stack-name "$STACK_NAME" + +echo "Done." diff --git a/cfn/prereq-bucket.yaml b/cfn/prereq-bucket.yaml new file mode 100644 index 00000000..065440a0 --- /dev/null +++ b/cfn/prereq-bucket.yaml @@ -0,0 +1,26 @@ +AWSTemplateFormatVersion: '2010-09-09' +Description: >- + Shared S3 bucket reference for tutorials. The bucket is created and deleted + by setup-bucket.sh and cleanup-bucket.sh. This stack just exports the name + so other tutorial stacks can import it. + +Parameters: + BucketName: + Type: String + Description: Name of the bucket created by setup-bucket.sh + +Resources: + Placeholder: + Type: AWS::CloudFormation::WaitConditionHandle + +Outputs: + BucketName: + Description: Name of the shared tutorial bucket + Value: !Ref BucketName + Export: + Name: !Sub '${AWS::StackName}-BucketName' + BucketArn: + Description: ARN of the shared tutorial bucket + Value: !Sub 'arn:aws:s3:::${BucketName}' + Export: + Name: !Sub '${AWS::StackName}-BucketArn' diff --git a/cfn/prereq-vpc-private.yaml b/cfn/prereq-vpc-private.yaml new file mode 100644 index 00000000..3a9b88f3 --- /dev/null +++ b/cfn/prereq-vpc-private.yaml @@ -0,0 +1,83 @@ +AWSTemplateFormatVersion: '2010-09-09' +Description: >- + Shared VPC with private subnets only across two AZs. + No internet gateway or NAT gateway. Use VPC endpoints for service access. + Deploy once, reference from tutorial stacks via cross-stack exports. + +Resources: + VPC: + Type: AWS::EC2::VPC + Properties: + CidrBlock: 10.1.0.0/16 + EnableDnsSupport: true + EnableDnsHostnames: true + Tags: + - Key: Name + Value: !Sub '${AWS::StackName}' + + PrivateSubnet1: + Type: AWS::EC2::Subnet + Properties: + VpcId: !Ref VPC + CidrBlock: 10.1.1.0/24 + AvailabilityZone: !Select [0, !GetAZs ''] + Tags: + - Key: Name + Value: !Sub '${AWS::StackName}-private-1' + + PrivateSubnet2: + Type: AWS::EC2::Subnet + Properties: + VpcId: !Ref VPC + CidrBlock: 10.1.2.0/24 + AvailabilityZone: !Select [1, !GetAZs ''] + Tags: + - Key: Name + Value: !Sub '${AWS::StackName}-private-2' + + PrivateRouteTable: + Type: AWS::EC2::RouteTable + Properties: + VpcId: !Ref VPC + + PrivateSubnet1RouteAssoc: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + SubnetId: !Ref PrivateSubnet1 + RouteTableId: !Ref PrivateRouteTable + + PrivateSubnet2RouteAssoc: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + SubnetId: !Ref PrivateSubnet2 + RouteTableId: !Ref PrivateRouteTable + + S3Endpoint: + Type: AWS::EC2::VPCEndpoint + Properties: + VpcId: !Ref VPC + ServiceName: !Sub 'com.amazonaws.${AWS::Region}.s3' + RouteTableIds: + - !Ref PrivateRouteTable + +Outputs: + VpcId: + Value: !Ref VPC + Export: + Name: !Sub '${AWS::StackName}-VpcId' + PrivateSubnet1Id: + Value: !Ref PrivateSubnet1 + Export: + Name: !Sub '${AWS::StackName}-PrivateSubnet1' + PrivateSubnet2Id: + Value: !Ref PrivateSubnet2 + Export: + Name: !Sub '${AWS::StackName}-PrivateSubnet2' + PrivateSubnets: + Value: !Join [',', [!Ref PrivateSubnet1, !Ref PrivateSubnet2]] + Export: + Name: !Sub '${AWS::StackName}-PrivateSubnets' + PrivateRouteTableId: + Value: !Ref PrivateRouteTable + Export: + Name: !Sub '${AWS::StackName}-PrivateRouteTable' diff --git a/cfn/prereq-vpc-public.yaml b/cfn/prereq-vpc-public.yaml new file mode 100644 index 00000000..52a350ca --- /dev/null +++ b/cfn/prereq-vpc-public.yaml @@ -0,0 +1,159 @@ +AWSTemplateFormatVersion: '2010-09-09' +Description: >- + Shared VPC with public and private subnets across two AZs. + Includes internet gateway, NAT gateway, and route tables. + Deploy once, reference from tutorial stacks via cross-stack exports. + +Resources: + VPC: + Type: AWS::EC2::VPC + Properties: + CidrBlock: 10.0.0.0/16 + EnableDnsSupport: true + EnableDnsHostnames: true + Tags: + - Key: Name + Value: !Sub '${AWS::StackName}' + + InternetGateway: + Type: AWS::EC2::InternetGateway + + GatewayAttachment: + Type: AWS::EC2::VPCGatewayAttachment + Properties: + VpcId: !Ref VPC + InternetGatewayId: !Ref InternetGateway + + PublicSubnet1: + Type: AWS::EC2::Subnet + Properties: + VpcId: !Ref VPC + CidrBlock: 10.0.1.0/24 + AvailabilityZone: !Select [0, !GetAZs ''] + MapPublicIpOnLaunch: true + Tags: + - Key: Name + Value: !Sub '${AWS::StackName}-public-1' + + PublicSubnet2: + Type: AWS::EC2::Subnet + Properties: + VpcId: !Ref VPC + CidrBlock: 10.0.2.0/24 + AvailabilityZone: !Select [1, !GetAZs ''] + MapPublicIpOnLaunch: true + Tags: + - Key: Name + Value: !Sub '${AWS::StackName}-public-2' + + PrivateSubnet1: + Type: AWS::EC2::Subnet + Properties: + VpcId: !Ref VPC + CidrBlock: 10.0.3.0/24 + AvailabilityZone: !Select [0, !GetAZs ''] + Tags: + - Key: Name + Value: !Sub '${AWS::StackName}-private-1' + + PrivateSubnet2: + Type: AWS::EC2::Subnet + Properties: + VpcId: !Ref VPC + CidrBlock: 10.0.4.0/24 + AvailabilityZone: !Select [1, !GetAZs ''] + Tags: + - Key: Name + Value: !Sub '${AWS::StackName}-private-2' + + NatEip: + Type: AWS::EC2::EIP + DependsOn: GatewayAttachment + + NatGateway: + Type: AWS::EC2::NatGateway + Properties: + AllocationId: !GetAtt NatEip.AllocationId + SubnetId: !Ref PublicSubnet1 + Tags: + - Key: Name + Value: !Sub '${AWS::StackName}-nat' + + PublicRouteTable: + Type: AWS::EC2::RouteTable + Properties: + VpcId: !Ref VPC + + PublicRoute: + Type: AWS::EC2::Route + DependsOn: GatewayAttachment + Properties: + RouteTableId: !Ref PublicRouteTable + DestinationCidrBlock: 0.0.0.0/0 + GatewayId: !Ref InternetGateway + + PublicSubnet1RouteAssoc: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + SubnetId: !Ref PublicSubnet1 + RouteTableId: !Ref PublicRouteTable + + PublicSubnet2RouteAssoc: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + SubnetId: !Ref PublicSubnet2 + RouteTableId: !Ref PublicRouteTable + + PrivateRouteTable: + Type: AWS::EC2::RouteTable + Properties: + VpcId: !Ref VPC + + PrivateRoute: + Type: AWS::EC2::Route + Properties: + RouteTableId: !Ref PrivateRouteTable + DestinationCidrBlock: 0.0.0.0/0 + NatGatewayId: !Ref NatGateway + + PrivateSubnet1RouteAssoc: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + SubnetId: !Ref PrivateSubnet1 + RouteTableId: !Ref PrivateRouteTable + + PrivateSubnet2RouteAssoc: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + SubnetId: !Ref PrivateSubnet2 + RouteTableId: !Ref PrivateRouteTable + +Outputs: + VpcId: + Value: !Ref VPC + Export: + Name: !Sub '${AWS::StackName}-VpcId' + PublicSubnet1Id: + Value: !Ref PublicSubnet1 + Export: + Name: !Sub '${AWS::StackName}-PublicSubnet1' + PublicSubnet2Id: + Value: !Ref PublicSubnet2 + Export: + Name: !Sub '${AWS::StackName}-PublicSubnet2' + PrivateSubnet1Id: + Value: !Ref PrivateSubnet1 + Export: + Name: !Sub '${AWS::StackName}-PrivateSubnet1' + PrivateSubnet2Id: + Value: !Ref PrivateSubnet2 + Export: + Name: !Sub '${AWS::StackName}-PrivateSubnet2' + PublicSubnets: + Value: !Join [',', [!Ref PublicSubnet1, !Ref PublicSubnet2]] + Export: + Name: !Sub '${AWS::StackName}-PublicSubnets' + PrivateSubnets: + Value: !Join [',', [!Ref PrivateSubnet1, !Ref PrivateSubnet2]] + Export: + Name: !Sub '${AWS::StackName}-PrivateSubnets' diff --git a/cfn/setup-bucket.sh b/cfn/setup-bucket.sh new file mode 100755 index 00000000..92b87371 --- /dev/null +++ b/cfn/setup-bucket.sh @@ -0,0 +1,46 @@ +#!/bin/bash +# Create the shared tutorial S3 bucket and register it with CloudFormation. +# Usage: ./cfn/setup-bucket.sh +set -eo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +STACK_NAME="tutorial-prereqs-bucket" +ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text) +REGION=$(aws configure get region 2>/dev/null || echo "us-east-1") +BUCKET_NAME="tutorial-bucket-${ACCOUNT_ID}-${REGION}" + +# Check if stack already exists +STATUS=$(aws cloudformation describe-stacks --stack-name "$STACK_NAME" \ + --query 'Stacks[0].StackStatus' --output text 2>/dev/null || echo "NONE") + +if [ "$STATUS" = "CREATE_COMPLETE" ] || [ "$STATUS" = "UPDATE_COMPLETE" ]; then + EXISTING=$(aws cloudformation describe-stacks --stack-name "$STACK_NAME" \ + --query 'Stacks[0].Outputs[?OutputKey==`BucketName`].OutputValue' --output text) + echo "Bucket already exists: $EXISTING" + exit 0 +fi + +echo "Creating bucket: $BUCKET_NAME" +if [ "$REGION" = "us-east-1" ]; then + aws s3api create-bucket --bucket "$BUCKET_NAME" +else + aws s3api create-bucket --bucket "$BUCKET_NAME" \ + --create-bucket-configuration LocationConstraint="$REGION" +fi + +aws s3api put-bucket-encryption --bucket "$BUCKET_NAME" \ + --server-side-encryption-configuration \ + '{"Rules":[{"ApplyServerSideEncryptionByDefault":{"SSEAlgorithm":"AES256"}}]}' + +aws s3api put-public-access-block --bucket "$BUCKET_NAME" \ + --public-access-block-configuration \ + 'BlockPublicAcls=true,BlockPublicPolicy=true,IgnorePublicAcls=true,RestrictPublicBuckets=true' + +echo "Registering bucket with CloudFormation stack: $STACK_NAME" +aws cloudformation deploy \ + --template-file "$SCRIPT_DIR/prereq-bucket.yaml" \ + --stack-name "$STACK_NAME" \ + --parameter-overrides "BucketName=$BUCKET_NAME" + +echo "Done. Bucket: $BUCKET_NAME" +echo "Other stacks can import: !ImportValue ${STACK_NAME}-BucketName" diff --git a/cleanup.sh b/cleanup.sh new file mode 100755 index 00000000..4c35a206 --- /dev/null +++ b/cleanup.sh @@ -0,0 +1,113 @@ +#!/bin/bash +# Delete a tutorial's CloudFormation stack and optionally clean up prerequisites. +# Usage: ./cleanup.sh +# ./cleanup.sh --prereqs # delete prerequisite stacks +set -eo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +PREREQ_STACK="tutorial-prereqs" + +if [ "$1" = "--prereqs" ]; then + echo "=== Prerequisite stacks ===" + for STACK in $(aws cloudformation list-stacks --stack-status-filter CREATE_COMPLETE UPDATE_COMPLETE \ + --query "StackSummaries[?starts_with(StackName, '$PREREQ_STACK')].StackName" --output text 2>/dev/null); do + echo " $STACK" + done + + echo "" + echo "Prerequisite stacks are shared across tutorials." + echo "Only delete them when you're done with all tutorials." + read -rp "Delete all prerequisite stacks? (y/n): " CHOICE + [[ ! "$CHOICE" =~ ^[Yy]$ ]] && exit 0 + + # Handle bucket prereq — must empty first + BUCKET_NAME=$(aws cloudformation describe-stacks --stack-name "$PREREQ_STACK-bucket" \ + --query 'Stacks[0].Outputs[?OutputKey==`BucketName`].OutputValue' --output text 2>/dev/null) + if [ -n "$BUCKET_NAME" ] && [ "$BUCKET_NAME" != "None" ]; then + OBJ_COUNT=$(aws s3api list-objects-v2 --bucket "$BUCKET_NAME" --query 'KeyCount' --output text 2>/dev/null || echo "0") + if [ "$OBJ_COUNT" -gt 0 ] 2>/dev/null; then + echo "" + echo "Bucket $BUCKET_NAME contains $OBJ_COUNT objects." + read -rp "Empty the bucket? (y/n): " EMPTY + if [[ "$EMPTY" =~ ^[Yy]$ ]]; then + echo "Emptying bucket..." + aws s3 rm "s3://$BUCKET_NAME" --recursive --quiet + aws s3api list-object-versions --bucket "$BUCKET_NAME" \ + --query '{Objects: Versions[].{Key:Key,VersionId:VersionId}, Quiet: true}' \ + --output json 2>/dev/null | \ + aws s3api delete-objects --bucket "$BUCKET_NAME" --delete file:///dev/stdin > /dev/null 2>&1 || true + echo " Emptied" + else + echo "Cannot delete bucket stack while bucket has objects." + exit 1 + fi + fi + aws cloudformation delete-stack --stack-name "$PREREQ_STACK-bucket" + echo "Deleting $PREREQ_STACK-bucket..." + aws cloudformation wait stack-delete-complete --stack-name "$PREREQ_STACK-bucket" 2>/dev/null + echo " Deleted" + fi + + # Handle VPC prereqs — delete cleanly unless tutorial stacks still reference them + for VPC_TYPE in vpc-public vpc-private; do + VPC_STACK="$PREREQ_STACK-$VPC_TYPE" + STATUS=$(aws cloudformation describe-stacks --stack-name "$VPC_STACK" --query 'Stacks[0].StackStatus' --output text 2>/dev/null || echo "NONE") + if [ "$STATUS" != "NONE" ] && [ "$STATUS" != "DELETE_COMPLETE" ]; then + echo "Deleting $VPC_STACK..." + aws cloudformation delete-stack --stack-name "$VPC_STACK" + aws cloudformation wait stack-delete-complete --stack-name "$VPC_STACK" 2>/dev/null && echo " Deleted" || echo " Failed (other stacks may still import from it)" + fi + done + exit 0 +fi + +# Delete a tutorial stack +TUT_DIR="$1" +[ -z "$TUT_DIR" ] && echo "Usage: $0 | --prereqs" && exit 1 + +STACK_NAME="tutorial-$(echo "$TUT_DIR" | sed 's/^[0-9]*-//')" + +# Check if stack exists +STATUS=$(aws cloudformation describe-stacks --stack-name "$STACK_NAME" \ + --query 'Stacks[0].StackStatus' --output text 2>/dev/null || echo "NONE") + +if [ "$STATUS" = "NONE" ] || [ "$STATUS" = "DELETE_COMPLETE" ]; then + echo "Stack $STACK_NAME does not exist." + echo "" + echo "Searching for leftover resources tagged with this stack name..." + echo "(Resources that may have been left behind from a failed deletion)" + echo "" + # Search by tag + aws resourcegroupstaggingapi get-resources \ + --tag-filters "Key=tutorial,Values=$STACK_NAME" \ + --query 'ResourceTagMappingList[].{ARN:ResourceARN}' --output table 2>/dev/null || true + # Also search by name prefix + aws resourcegroupstaggingapi get-resources \ + --tag-filters "Key=aws:cloudformation:stack-name,Values=$STACK_NAME" \ + --query 'ResourceTagMappingList[].{ARN:ResourceARN}' --output table 2>/dev/null || true + exit 0 +fi + +echo "Stack: $STACK_NAME (status: $STATUS)" +echo "" +echo "=== Stack Resources ===" +aws cloudformation list-stack-resources --stack-name "$STACK_NAME" \ + --query 'StackResourceSummaries[].{Type:ResourceType,LogicalId:LogicalResourceId,PhysicalId:PhysicalResourceId,Status:ResourceStatus}' --output table + +echo "" +echo "=== Stack Outputs ===" +aws cloudformation describe-stacks --stack-name "$STACK_NAME" \ + --query 'Stacks[0].Outputs[].{Key:OutputKey,Value:OutputValue}' --output table 2>/dev/null || echo " (none)" + +echo "" +read -rp "Delete stack $STACK_NAME? (y/n): " CHOICE +[[ ! "$CHOICE" =~ ^[Yy]$ ]] && exit 0 + +echo "Deleting..." +aws cloudformation delete-stack --stack-name "$STACK_NAME" +aws cloudformation wait stack-delete-complete --stack-name "$STACK_NAME" +echo "Stack $STACK_NAME deleted." + +echo "" +echo "Note: Prerequisite stacks are still running. To delete them:" +echo " $0 --prereqs" diff --git a/deploy.sh b/deploy.sh new file mode 100755 index 00000000..d57159e2 --- /dev/null +++ b/deploy.sh @@ -0,0 +1,143 @@ +#!/bin/bash +# Deploy a tutorial's CloudFormation stack, creating prerequisites if needed. +# Usage: ./deploy.sh [param=value ...] +# Example: ./deploy.sh 094-aws-cloudtrail-gs +# ./deploy.sh 026-kinesis-data-streams Runtime=python3.12 +set -eo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +CFN_DIR="$SCRIPT_DIR/cfn" +TUTS_DIR="$SCRIPT_DIR/tuts" +PREREQ_STACK="tutorial-prereqs" + +usage() { + echo "Usage: $0 [param=value ...]" + echo "" + echo "Tutorials with CloudFormation templates:" + for dir in "$TUTS_DIR"/*/; do + TEMPLATE=$(find "$dir" -name 'cfn-*.yaml' -o -name 'cfn-*.yml' 2>/dev/null | head -1) + [ -n "$TEMPLATE" ] && echo " $(basename "$dir")" + done + exit 0 +} + +[ $# -lt 1 ] && usage + +TUT_DIR="$1" +shift +OVERRIDES="$@" + +# Find the template +TEMPLATE=$(find "$TUTS_DIR/$TUT_DIR" -name 'cfn-*.yaml' -o -name 'cfn-*.yml' 2>/dev/null | head -1) +if [ -z "$TEMPLATE" ]; then + echo "No CloudFormation template found in tuts/$TUT_DIR/" + echo "Looking for files matching cfn-*.yaml" + exit 1 +fi + +STACK_NAME="tutorial-$(echo "$TUT_DIR" | sed 's/^[0-9]*-//')" +echo "Template: $TEMPLATE" +echo "Stack: $STACK_NAME" + +# Check if the template imports from prerequisite stacks +TEMPLATE_CONTENT=$(cat "$TEMPLATE") +NEEDS_BUCKET=false +NEEDS_VPC=false + +if echo "$TEMPLATE_CONTENT" | grep -q "Fn::ImportValue.*prereqs.*BucketName\|prereq-bucket"; then + NEEDS_BUCKET=true +fi +if echo "$TEMPLATE_CONTENT" | grep -q "Fn::ImportValue.*prereqs-vpc-public\|prereq-vpc-public"; then + NEEDS_VPC=true + VPC_TYPE="public" +fi +if echo "$TEMPLATE_CONTENT" | grep -q "Fn::ImportValue.*prereqs-vpc-private\|prereq-vpc-private"; then + NEEDS_VPC=true + VPC_TYPE="private" +fi + +# Deploy prerequisites if needed +if [ "$NEEDS_BUCKET" = true ]; then + echo "" + echo "This tutorial requires a shared S3 bucket." + BUCKET_STACK=$(aws cloudformation describe-stacks --stack-name "$PREREQ_STACK-bucket" --query 'Stacks[0].StackStatus' --output text 2>/dev/null || echo "NONE") + if [ "$BUCKET_STACK" = "NONE" ] || [ "$BUCKET_STACK" = "DELETE_COMPLETE" ]; then + echo "Prerequisite stack '$PREREQ_STACK-bucket' not found." + read -rp "Create it now? (y/n): " CHOICE + if [[ "$CHOICE" =~ ^[Yy]$ ]]; then + echo "Creating shared bucket..." + aws cloudformation deploy \ + --template-file "$CFN_DIR/prereq-bucket.yaml" \ + --stack-name "$PREREQ_STACK-bucket" + echo "Bucket created: $(aws cloudformation describe-stacks --stack-name "$PREREQ_STACK-bucket" --query 'Stacks[0].Outputs[?OutputKey==`BucketName`].OutputValue' --output text)" + else + echo "Cannot proceed without the bucket prerequisite." + exit 1 + fi + else + BUCKET_NAME=$(aws cloudformation describe-stacks --stack-name "$PREREQ_STACK-bucket" --query 'Stacks[0].Outputs[?OutputKey==`BucketName`].OutputValue' --output text) + echo "Using existing bucket: $BUCKET_NAME" + fi +fi + +if [ "$NEEDS_VPC" = true ]; then + echo "" + VPC_STACK_NAME="$PREREQ_STACK-vpc-$VPC_TYPE" + echo "This tutorial requires a VPC ($VPC_TYPE subnets)." + VPC_STACK=$(aws cloudformation describe-stacks --stack-name "$VPC_STACK_NAME" --query 'Stacks[0].StackStatus' --output text 2>/dev/null || echo "NONE") + if [ "$VPC_STACK" = "NONE" ] || [ "$VPC_STACK" = "DELETE_COMPLETE" ]; then + echo "Prerequisite stack '$VPC_STACK_NAME' not found." + read -rp "Create it now? (y/n): " CHOICE + if [[ "$CHOICE" =~ ^[Yy]$ ]]; then + echo "Creating VPC ($VPC_TYPE)..." + aws cloudformation deploy \ + --template-file "$CFN_DIR/prereq-vpc-$VPC_TYPE.yaml" \ + --stack-name "$VPC_STACK_NAME" + echo "VPC created: $(aws cloudformation describe-stacks --stack-name "$VPC_STACK_NAME" --query 'Stacks[0].Outputs[?OutputKey==`VpcId`].OutputValue' --output text)" + else + echo "Cannot proceed without the VPC prerequisite." + exit 1 + fi + else + VPC_ID=$(aws cloudformation describe-stacks --stack-name "$VPC_STACK_NAME" --query 'Stacks[0].Outputs[?OutputKey==`VpcId`].OutputValue' --output text) + echo "Using existing VPC: $VPC_ID" + fi +fi + +# Build capabilities argument +CAPA_ARG="" +if echo "$TEMPLATE_CONTENT" | grep -qE "AWS::IAM::Role|AWS::IAM::Policy|AWS::IAM::InstanceProfile"; then + CAPA_ARG="--capabilities CAPABILITY_IAM" +fi +if echo "$TEMPLATE_CONTENT" | grep -q "RoleName\|PolicyName"; then + CAPA_ARG="--capabilities CAPABILITY_NAMED_IAM" +fi + +# Build overrides argument +OVERRIDES_ARG="" +if [ -n "$OVERRIDES" ]; then + OVERRIDES_ARG="--parameter-overrides $OVERRIDES" +fi + +# Deploy +echo "" +echo "Deploying stack: $STACK_NAME" +aws cloudformation deploy \ + --template-file "$TEMPLATE" \ + --stack-name "$STACK_NAME" \ + $CAPA_ARG \ + $OVERRIDES_ARG \ + --no-fail-on-empty-changeset + +echo "" +echo "=== Stack Resources ===" +aws cloudformation list-stack-resources --stack-name "$STACK_NAME" \ + --query 'StackResourceSummaries[].{Type:ResourceType,LogicalId:LogicalResourceId,PhysicalId:PhysicalResourceId,Status:ResourceStatus}' --output table 2>/dev/null || echo " (none)" + +echo "" +echo "=== Stack Outputs ===" +aws cloudformation describe-stacks --stack-name "$STACK_NAME" \ + --query 'Stacks[0].Outputs[].{Key:OutputKey,Value:OutputValue}' --output table 2>/dev/null || echo " (none)" + +echo "" +echo "To delete: ./cleanup.sh $TUT_DIR" diff --git a/test-cfn.py b/test-cfn.py new file mode 100755 index 00000000..06b2378e --- /dev/null +++ b/test-cfn.py @@ -0,0 +1,278 @@ +#!/usr/bin/env python +"""Test all CloudFormation templates: validate, deploy, verify, delete. + +Usage: python3 test-cfn.py [--parallel N] [--skip-deploy] [--region REGION] +""" + +import argparse +import boto3 +import json +import os +import sys +import time +from concurrent.futures import ThreadPoolExecutor, as_completed +from dataclasses import dataclass, field +from pathlib import Path + +PREREQ_STACKS = { + "tutorial-prereqs-bucket": "cfn/prereq-bucket.yaml", + "tutorial-prereqs-vpc-public": "cfn/prereq-vpc-public.yaml", + "tutorial-prereqs-vpc-private": "cfn/prereq-vpc-private.yaml", +} + +@dataclass +class TestResult: + template: str + validate: str = "SKIP" + deploy: str = "SKIP" + delete: str = "SKIP" + duration: float = 0 + error: str = "" + stack_name: str = "" + +def find_templates(repo_root): + """Find all cfn-*.yaml templates in tutorial directories.""" + templates = {} + for p in sorted(Path(repo_root, "tuts").glob("*/cfn-*.yaml")): + tut = p.parent.name + templates[tut] = str(p) + return templates + +def detect_prereqs(template_path): + """Check which prerequisite stacks a template needs.""" + content = Path(template_path).read_text() + needed = [] + if "prereqs-bucket" in content or "prereq-bucket" in content: + needed.append("tutorial-prereqs-bucket") + if "prereqs-vpc-public" in content or "prereq-vpc-public" in content: + needed.append("tutorial-prereqs-vpc-public") + if "prereqs-vpc-private" in content or "prereq-vpc-private" in content: + needed.append("tutorial-prereqs-vpc-private") + return needed + +def needs_iam(template_path): + content = Path(template_path).read_text() + if "RoleName" in content or "PolicyName" in content: + return "CAPABILITY_NAMED_IAM" + if "AWS::IAM::" in content: + return "CAPABILITY_IAM" + return None + +def validate_template(cfn, template_path): + body = Path(template_path).read_text() + cfn.validate_template(TemplateBody=body) + +def deploy_stack(cfn, stack_name, template_path, timeout=600): + body = Path(template_path).read_text() + caps = [] + cap = needs_iam(template_path) + if cap: + caps = [cap] + + try: + cfn.create_stack( + StackName=stack_name, + TemplateBody=body, + Capabilities=caps, + Tags=[{"Key": "test-run", "Value": "cfn-test"}], + TimeoutInMinutes=10, + OnFailure="DELETE", + ) + except cfn.exceptions.AlreadyExistsException: + cfn.delete_stack(StackName=stack_name) + waiter = cfn.get_waiter("stack_delete_complete") + waiter.wait(StackName=stack_name, WaiterConfig={"Delay": 10, "MaxAttempts": 60}) + cfn.create_stack( + StackName=stack_name, + TemplateBody=body, + Capabilities=caps, + Tags=[{"Key": "test-run", "Value": "cfn-test"}], + TimeoutInMinutes=10, + OnFailure="DELETE", + ) + + waiter = cfn.get_waiter("stack_create_complete") + waiter.wait(StackName=stack_name, WaiterConfig={"Delay": 15, "MaxAttempts": int(timeout / 15)}) + +def delete_stack(cfn, stack_name, timeout=300): + cfn.delete_stack(StackName=stack_name) + waiter = cfn.get_waiter("stack_delete_complete") + waiter.wait(StackName=stack_name, WaiterConfig={"Delay": 10, "MaxAttempts": int(timeout / 10)}) + +def ensure_prereqs(cfn, repo_root, needed_stacks): + """Deploy prerequisite stacks if they don't exist. Returns set of failed prereqs.""" + failed = set() + for stack_name in needed_stacks: + try: + resp = cfn.describe_stacks(StackName=stack_name) + status = resp["Stacks"][0]["StackStatus"] + if status in ("CREATE_COMPLETE", "UPDATE_COMPLETE"): + print(f" Prereq {stack_name}: exists ({status})") + continue + elif "ROLLBACK" in status or "FAILED" in status: + print(f" Prereq {stack_name}: cleaning up failed stack...") + cfn.delete_stack(StackName=stack_name) + cfn.get_waiter("stack_delete_complete").wait( + StackName=stack_name, WaiterConfig={"Delay": 10, "MaxAttempts": 30}) + except cfn.exceptions.ClientError: + pass + + template_file = PREREQ_STACKS.get(stack_name) + if not template_file: + failed.add(stack_name) + continue + + template_path = os.path.join(repo_root, template_file) + print(f" Prereq {stack_name}: deploying...") + try: + caps = [] + if needs_iam(template_path): + caps = [needs_iam(template_path)] + body = Path(template_path).read_text() + cfn.create_stack( + StackName=stack_name, TemplateBody=body, Capabilities=caps, + Tags=[{"Key": "test-run", "Value": "cfn-test"}], + TimeoutInMinutes=10, OnFailure="DELETE", + ) + waiter = cfn.get_waiter("stack_create_complete") + waiter.wait(StackName=stack_name, WaiterConfig={"Delay": 15, "MaxAttempts": 40}) + print(f" Prereq {stack_name}: ready") + except Exception as e: + print(f" Prereq {stack_name}: CFN deploy failed ({e})") + print(f" Prereq {stack_name}: Run ./cfn/setup-bucket.sh first, then retry.") + failed.add(stack_name) + try: + cfn.delete_stack(StackName=stack_name) + except Exception: + pass + return failed + +def test_template(cfn, tut_name, template_path, skip_deploy): + """Test a single template: validate, deploy, delete.""" + result = TestResult(template=tut_name) + stack_name = f"cfn-test-{tut_name[:40]}" + result.stack_name = stack_name + start = time.time() + + # Validate + try: + validate_template(cfn, template_path) + result.validate = "PASS" + except Exception as e: + result.validate = "FAIL" + result.error = str(e)[:200] + result.duration = time.time() - start + return result + + if skip_deploy: + result.duration = time.time() - start + return result + + # Deploy + try: + deploy_stack(cfn, stack_name, template_path) + result.deploy = "PASS" + except Exception as e: + result.deploy = "FAIL" + result.error = str(e)[:200] + result.duration = time.time() - start + # Try cleanup + try: + delete_stack(cfn, stack_name) + except Exception: + pass + return result + + # Delete + try: + delete_stack(cfn, stack_name) + result.delete = "PASS" + except Exception as e: + result.delete = "FAIL" + result.error = f"Delete failed: {str(e)[:150]}" + + result.duration = time.time() - start + return result + +def main(): + parser = argparse.ArgumentParser(description="Test CloudFormation templates") + parser.add_argument("--parallel", type=int, default=3, help="Max parallel deployments") + parser.add_argument("--skip-deploy", action="store_true", help="Validate only, don't deploy") + parser.add_argument("--region", default="us-east-1") + parser.add_argument("--repo", default=".", help="Repo root directory") + args = parser.parse_args() + + repo_root = os.path.abspath(args.repo) + cfn = boto3.client("cloudformation", region_name=args.region) + + # Find templates + templates = find_templates(repo_root) + print(f"Found {len(templates)} templates") + + if not args.skip_deploy: + # Collect all needed prereqs + all_prereqs = set() + template_prereqs = {} + for tut, path in templates.items(): + prereqs = detect_prereqs(path) + template_prereqs[tut] = prereqs + all_prereqs.update(prereqs) + + failed_prereqs = set() + if all_prereqs: + print(f"\nDeploying prerequisites: {', '.join(sorted(all_prereqs))}") + failed_prereqs = ensure_prereqs(cfn, repo_root, sorted(all_prereqs)) + if failed_prereqs: + print(f"\nFailed prereqs: {', '.join(failed_prereqs)}") + + # Test templates in parallel + print(f"\nTesting {len(templates)} templates (parallel={args.parallel})...\n") + results = [] + + with ThreadPoolExecutor(max_workers=args.parallel) as pool: + futures = {} + for tut, path in templates.items(): + # Skip if prereqs failed + if not args.skip_deploy: + missing = set(template_prereqs.get(tut, [])) & failed_prereqs + if missing: + r = TestResult(template=tut, validate="PASS", deploy="SKIP", error=f"Prereq failed: {', '.join(missing)}") + results.append(r) + print(f" ⊘ {tut}: skipped (prereq failed)") + continue + # Each thread gets its own client + thread_cfn = boto3.client("cloudformation", region_name=args.region) + future = pool.submit(test_template, thread_cfn, tut, path, args.skip_deploy) + futures[future] = tut + + for future in as_completed(futures): + tut = futures[future] + result = future.result() + results.append(result) + status = "✓" if result.deploy in ("PASS", "SKIP") and result.validate == "PASS" else "✗" + print(f" {status} {result.template}: validate={result.validate} deploy={result.deploy} delete={result.delete} ({result.duration:.0f}s)") + if result.error: + print(f" Error: {result.error}") + + # Report + results.sort(key=lambda r: r.template) + passed = sum(1 for r in results if r.validate == "PASS" and r.deploy in ("PASS", "SKIP")) + failed = len(results) - passed + + print(f"\n{'='*70}") + print(f"RESULTS: {passed} passed, {failed} failed, {len(results)} total") + print(f"{'='*70}") + print(f"{'Template':<45} {'Validate':<10} {'Deploy':<10} {'Delete':<10} {'Time':<8}") + print(f"{'-'*45} {'-'*10} {'-'*10} {'-'*10} {'-'*8}") + for r in results: + print(f"{r.template:<45} {r.validate:<10} {r.deploy:<10} {r.delete:<10} {r.duration:<8.0f}s") + + # Cleanup prereqs if all tests passed + if not args.skip_deploy and failed == 0: + print(f"\nAll tests passed. Prerequisite stacks left running for reuse.") + print(f"To delete: python3 {sys.argv[0]} --cleanup-prereqs") + + return 1 if failed > 0 else 0 + +if __name__ == "__main__": + sys.exit(main()) diff --git a/tuts/001-lightsail-gs/README.md b/tuts/001-lightsail-gs/README.md index baac69af..269bc8c6 100644 --- a/tuts/001-lightsail-gs/README.md +++ b/tuts/001-lightsail-gs/README.md @@ -12,4 +12,31 @@ The script creates the following AWS resources in order: - Lightsail disk (8 GB block storage disk) - Lightsail instance snapshot (backup of the instance) -The script prompts you to clean up resources when you run it, including if there's an error part way through. If you need to clean up resources later, you can use the script log as a reference point for which resources were created. \ No newline at end of file +The script prompts you to clean up resources when you run it, including if there's an error part way through. If you need to clean up resources later, you can use the script log as a reference point for which resources were created. + + +## CloudFormation + +This tutorial includes a CloudFormation template that creates the same resources as the CLI script. + +**Resources created:** Lightsail instance and disk + +### Deploy with CloudFormation + +```bash +./deploy.sh 001-lightsail-gs +``` + +### Run the interactive steps + +Once deployed, run the interactive tutorial steps against the CloudFormation-created resources. Each command is displayed with resolved values so you can run them individually. + +```bash +bash tuts/001-lightsail-gs/lightsail-gs-cfn.sh +``` + +### Clean up + +```bash +./cleanup.sh 001-lightsail-gs +``` diff --git a/tuts/001-lightsail-gs/REVISION-HISTORY.md b/tuts/001-lightsail-gs/REVISION-HISTORY.md new file mode 100644 index 00000000..9a64d48a --- /dev/null +++ b/tuts/001-lightsail-gs/REVISION-HISTORY.md @@ -0,0 +1,28 @@ +# Revision History: 001-lightsail-gs + +## Shell (CLI script) + +### 2025-07-29 v-b1 initial attempt +- Type: functional +- AWS CLI tutorials and scripts + +### 2025-07-30 v-b2 revision +- Type: functional +- readme + +### 2025-08-05 v-b3 revision +- Type: functional +- project READMEs list resources created + +### 2025-09-10 v-b4 revision +- Type: functional +- fix tilde usage + +### 2025-09-12 v-b5 revision +- Type: functional +- unordered list bullets and trailing whitespace + +### 2026-04-13 v1 published +- Type: functional +- security and consistency updates + diff --git a/tuts/001-lightsail-gs/cfn-lightsail-gs.yaml b/tuts/001-lightsail-gs/cfn-lightsail-gs.yaml new file mode 100644 index 00000000..73fc3efd --- /dev/null +++ b/tuts/001-lightsail-gs/cfn-lightsail-gs.yaml @@ -0,0 +1,30 @@ +AWSTemplateFormatVersion: '2010-09-09' +Description: Lightsail getting started - instance with attached disk. + +Resources: + Instance: + Type: AWS::Lightsail::Instance + Properties: + InstanceName: !Sub '${AWS::StackName}-instance' + BlueprintId: amazon_linux_2023 + BundleId: nano_3_0 + AvailabilityZone: !Select [0, !GetAZs ''] + Tags: + - Key: tutorial + Value: !Ref AWS::StackName + + Disk: + Type: AWS::Lightsail::Disk + Properties: + DiskName: !Sub '${AWS::StackName}-disk' + SizeInGb: 8 + AvailabilityZone: !Select [0, !GetAZs ''] + Tags: + - Key: tutorial + Value: !Ref AWS::StackName + +Outputs: + InstanceName: + Value: !Ref Instance + DiskName: + Value: !Ref Disk diff --git a/tuts/001-lightsail-gs/lightsail-gs-cfn.sh b/tuts/001-lightsail-gs/lightsail-gs-cfn.sh new file mode 100755 index 00000000..8ee580e3 --- /dev/null +++ b/tuts/001-lightsail-gs/lightsail-gs-cfn.sh @@ -0,0 +1,58 @@ +#!/bin/bash +# Run the interactive tutorial steps against resources created by CloudFormation. +# If the stack does not exist, offers to deploy it first. +set -eo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +TUT_DIR="$(basename "$SCRIPT_DIR")" +STACK_NAME="tutorial-$(echo "$TUT_DIR" | sed 's/^[0-9]*-//')" + +get_output() { aws cloudformation describe-stacks --stack-name "$STACK_NAME" --query "Stacks[0].Outputs[?OutputKey==\`$1\`].OutputValue" --output text 2>/dev/null; } + +run_cmd() { + echo "" + echo "$ $@" + eval "$@" +} + +# Check if stack exists, offer to create +STATUS=$(aws cloudformation describe-stacks --stack-name "$STACK_NAME" --query 'Stacks[0].StackStatus' --output text 2>/dev/null || echo "NONE") +if [ "$STATUS" = "NONE" ] || [ "$STATUS" = "DELETE_COMPLETE" ]; then + echo "Stack $STACK_NAME does not exist." + read -rp "Deploy it now? (y/n): " CHOICE + if [[ "$CHOICE" =~ ^[Yy]$ ]]; then + "$REPO_ROOT/deploy.sh" "$TUT_DIR" + else + echo "Cannot proceed without the stack. Deploy with: ./deploy.sh $TUT_DIR" + exit 1 + fi +fi +echo "Stack: $STACK_NAME ($STATUS)" + +INSTANCE=$(get_output InstanceName) +DISK=$(get_output DiskName) +echo "Instance: $INSTANCE" +echo "Disk: $DISK" + +echo "" +echo "--- Step 1: Get instance state ---" +run_cmd aws lightsail get-instance-state --instance-name "$INSTANCE" + +echo "" +echo "--- Step 2: Get instance details ---" +run_cmd aws lightsail get-instance --instance-name "$INSTANCE" --query "'instance.{name:name,blueprint:blueprintId,bundle:bundleId,state:state.name,ip:publicIpAddress}'" --output table + +echo "" +echo "--- Step 3: Create a snapshot ---" +SNAP_NAME="${INSTANCE}-snapshot" +run_cmd aws lightsail create-instance-snapshot --instance-name "$INSTANCE" --instance-snapshot-name "$SNAP_NAME" + +echo "" +echo "--- Step 4: Delete the snapshot ---" +sleep 10 +run_cmd aws lightsail delete-instance-snapshot --instance-snapshot-name "$SNAP_NAME" + +echo "" +echo "Interactive steps complete." +echo "To delete stack: ./cleanup.sh $TUT_DIR" diff --git a/tuts/002-vpc-gs/README.md b/tuts/002-vpc-gs/README.md index c3edb739..c05801dc 100644 --- a/tuts/002-vpc-gs/README.md +++ b/tuts/002-vpc-gs/README.md @@ -25,4 +25,31 @@ The script creates the following AWS resources in order: - EC2 security group (web server security group allowing HTTP/HTTPS) - EC2 security group (database security group allowing MySQL from web servers) -The script prompts you to clean up resources when you run it, including if there's an error part way through. If you need to clean up resources later, you can use the script log as a reference point for which resources were created. \ No newline at end of file +The script prompts you to clean up resources when you run it, including if there's an error part way through. If you need to clean up resources later, you can use the script log as a reference point for which resources were created. + + +## CloudFormation + +This tutorial includes a CloudFormation template that creates the same resources as the CLI script. + +**Resources created:** VPC with public subnet and EC2 instance + +### Deploy with CloudFormation + +```bash +./deploy.sh 002-vpc-gs +``` + +### Run the interactive steps + +Once deployed, run the interactive tutorial steps against the CloudFormation-created resources. Each command is displayed with resolved values so you can run them individually. + +```bash +bash tuts/002-vpc-gs/vpc-gs-cfn.sh +``` + +### Clean up + +```bash +./cleanup.sh 002-vpc-gs +``` diff --git a/tuts/002-vpc-gs/REVISION-HISTORY.md b/tuts/002-vpc-gs/REVISION-HISTORY.md new file mode 100644 index 00000000..21a3cf7a --- /dev/null +++ b/tuts/002-vpc-gs/REVISION-HISTORY.md @@ -0,0 +1,28 @@ +# Revision History: 002-vpc-gs + +## Shell (CLI script) + +### 2025-07-29 v-b1 initial attempt +- Type: functional +- AWS CLI tutorials and scripts + +### 2025-07-30 v-b2 revision +- Type: functional +- readme + +### 2025-08-04 v-b3 revision +- Type: functional +- Tributary configs + +### 2025-08-05 v-b4 revision +- Type: functional +- project READMEs list resources created + +### 2025-08-06 v-b5 revision +- Type: functional +- Merge remote-tracking branch 'upstream/main' into tributary-config + +### 2025-09-12 v1 published +- Type: functional +- unordered list bullets and trailing whitespace + diff --git a/tuts/002-vpc-gs/cfn-vpc-gs.yaml b/tuts/002-vpc-gs/cfn-vpc-gs.yaml new file mode 100644 index 00000000..fdc04ac0 --- /dev/null +++ b/tuts/002-vpc-gs/cfn-vpc-gs.yaml @@ -0,0 +1,88 @@ +AWSTemplateFormatVersion: '2010-09-09' +Description: VPC getting started - VPC with public subnet, internet gateway, and EC2 instance. + +Parameters: + LatestAmiId: + Type: AWS::SSM::Parameter::Value + Default: /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64 + +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' + + InternetGateway: + Type: AWS::EC2::InternetGateway + + GatewayAttachment: + Type: AWS::EC2::VPCGatewayAttachment + Properties: + VpcId: !Ref VPC + InternetGatewayId: !Ref InternetGateway + + PublicSubnet: + Type: AWS::EC2::Subnet + Properties: + VpcId: !Ref VPC + CidrBlock: 10.0.1.0/24 + MapPublicIpOnLaunch: true + AvailabilityZone: !Select [0, !GetAZs ''] + + RouteTable: + Type: AWS::EC2::RouteTable + Properties: + VpcId: !Ref VPC + + PublicRoute: + Type: AWS::EC2::Route + DependsOn: GatewayAttachment + Properties: + RouteTableId: !Ref RouteTable + DestinationCidrBlock: 0.0.0.0/0 + GatewayId: !Ref InternetGateway + + SubnetRouteAssoc: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + SubnetId: !Ref PublicSubnet + RouteTableId: !Ref RouteTable + + SecurityGroup: + Type: AWS::EC2::SecurityGroup + Properties: + GroupDescription: Tutorial SSH access + VpcId: !Ref VPC + SecurityGroupIngress: + - IpProtocol: tcp + FromPort: 22 + ToPort: 22 + CidrIp: 0.0.0.0/0 + + Instance: + Type: AWS::EC2::Instance + Properties: + InstanceType: t2.micro + Tags: + - Key: tutorial + Value: !Ref AWS::StackName + ImageId: !Ref LatestAmiId + SubnetId: !Ref PublicSubnet + SecurityGroupIds: + - !Ref SecurityGroup + Tags: + - Key: Name + Value: !Sub '${AWS::StackName}-instance' + +Outputs: + VpcId: + Value: !Ref VPC + InstanceId: + Value: !Ref Instance + PublicIp: + Value: !GetAtt Instance.PublicIp diff --git a/tuts/002-vpc-gs/vpc-gs-cfn.sh b/tuts/002-vpc-gs/vpc-gs-cfn.sh new file mode 100755 index 00000000..226eaf43 --- /dev/null +++ b/tuts/002-vpc-gs/vpc-gs-cfn.sh @@ -0,0 +1,52 @@ +#!/bin/bash +# Run the interactive tutorial steps against resources created by CloudFormation. +# If the stack does not exist, offers to deploy it first. +set -eo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +TUT_DIR="$(basename "$SCRIPT_DIR")" +STACK_NAME="tutorial-$(echo "$TUT_DIR" | sed 's/^[0-9]*-//')" + +get_output() { aws cloudformation describe-stacks --stack-name "$STACK_NAME" --query "Stacks[0].Outputs[?OutputKey==\`$1\`].OutputValue" --output text 2>/dev/null; } + +run_cmd() { + echo "" + echo "$ $@" + eval "$@" +} + +# Check if stack exists, offer to create +STATUS=$(aws cloudformation describe-stacks --stack-name "$STACK_NAME" --query 'Stacks[0].StackStatus' --output text 2>/dev/null || echo "NONE") +if [ "$STATUS" = "NONE" ] || [ "$STATUS" = "DELETE_COMPLETE" ]; then + echo "Stack $STACK_NAME does not exist." + read -rp "Deploy it now? (y/n): " CHOICE + if [[ "$CHOICE" =~ ^[Yy]$ ]]; then + "$REPO_ROOT/deploy.sh" "$TUT_DIR" + else + echo "Cannot proceed without the stack. Deploy with: ./deploy.sh $TUT_DIR" + exit 1 + fi +fi +echo "Stack: $STACK_NAME ($STATUS)" + +VPC_ID=$(get_output VpcId) +INSTANCE_ID=$(get_output InstanceId) +PUBLIC_IP=$(get_output PublicIp) +echo "VPC: $VPC_ID | Instance: $INSTANCE_ID | IP: $PUBLIC_IP" + +echo "" +echo "--- Step 1: Describe the VPC ---" +run_cmd aws ec2 describe-vpcs --vpc-ids "$VPC_ID" --query "'Vpcs[0].{VpcId:VpcId,CIDR:CidrBlock,State:State}'" --output table + +echo "" +echo "--- Step 2: List subnets ---" +run_cmd aws ec2 describe-subnets --filters "Name=vpc-id,Values=$VPC_ID" --query "'Subnets[].{Id:SubnetId,CIDR:CidrBlock,AZ:AvailabilityZone}'" --output table + +echo "" +echo "--- Step 3: Check instance status ---" +run_cmd aws ec2 describe-instances --instance-ids "$INSTANCE_ID" --query "'Reservations[0].Instances[0].{State:State.Name,Type:InstanceType,IP:PublicIpAddress}'" --output table + +echo "" +echo "Interactive steps complete." +echo "To delete stack: ./cleanup.sh $TUT_DIR" diff --git a/tuts/003-s3-gettingstarted/README.md b/tuts/003-s3-gettingstarted/README.md index 54d45a38..0799165f 100644 --- a/tuts/003-s3-gettingstarted/README.md +++ b/tuts/003-s3-gettingstarted/README.md @@ -57,6 +57,33 @@ Free tier eligible. No charges expected for a few objects. --- + + +## CloudFormation + +This tutorial includes a CloudFormation template that creates the same resources as the CLI script. + +**Resources created:** S3 bucket (uses shared prereq bucket) + +### Deploy with CloudFormation + +```bash +./deploy.sh 003-s3-gettingstarted +``` + +### Run the interactive steps + +Once deployed, run the interactive tutorial steps against the CloudFormation-created resources. Each command is displayed with resolved values so you can run them individually. + +```bash +bash tuts/003-s3-gettingstarted/s3-gettingstarted-cfn.sh +``` + +### Clean up + +```bash +./cleanup.sh 003-s3-gettingstarted +``` ## Appendix: Generation details | Field | Value | diff --git a/tuts/003-s3-gettingstarted/REVISION-HISTORY.md b/tuts/003-s3-gettingstarted/REVISION-HISTORY.md new file mode 100644 index 00000000..4056cce7 --- /dev/null +++ b/tuts/003-s3-gettingstarted/REVISION-HISTORY.md @@ -0,0 +1,36 @@ +# Revision History: 003-s3-gettingstarted + +## Shell (CLI script) + +### 2025-07-29 v-b1 initial attempt +- Type: functional +- AWS CLI tutorials and scripts + +### 2025-07-30 v-b2 revision +- Type: functional +- readme + +### 2025-08-05 v-b3 revision +- Type: functional +- project READMEs list resources created + +### 2025-09-10 v-b4 revision +- Type: functional +- inline code formatting + +### 2025-09-12 v-b5 revision +- Type: functional +- unordered list bullets and trailing whitespace + +### 2026-04-13 v-b6 revision +- Type: functional +- revised scripts and readmes + +### 2026-04-13 v-b7 revision +- Type: functional +- related docs links, resource naming + +### 2026-04-14 v1 published +- Type: functional +- readmes + diff --git a/tuts/003-s3-gettingstarted/cfn-s3-gettingstarted.yaml b/tuts/003-s3-gettingstarted/cfn-s3-gettingstarted.yaml new file mode 100644 index 00000000..b1ffb6b2 --- /dev/null +++ b/tuts/003-s3-gettingstarted/cfn-s3-gettingstarted.yaml @@ -0,0 +1,19 @@ +AWSTemplateFormatVersion: '2010-09-09' +Description: >- + S3 getting started. Uses the shared tutorial bucket from the prereq stack. + Run the CLI script to practice S3 operations on the bucket. + +Parameters: + PrereqStackName: + Type: String + Default: tutorial-prereqs-bucket + +Resources: + BucketReadyCondition: + Type: AWS::CloudFormation::WaitConditionHandle + +Outputs: + BucketName: + Description: Use this bucket with the CLI tutorial + Value: !ImportValue + Fn::Sub: '${PrereqStackName}-BucketName' diff --git a/tuts/003-s3-gettingstarted/s3-gettingstarted-cfn.sh b/tuts/003-s3-gettingstarted/s3-gettingstarted-cfn.sh new file mode 100755 index 00000000..f7dca694 --- /dev/null +++ b/tuts/003-s3-gettingstarted/s3-gettingstarted-cfn.sh @@ -0,0 +1,62 @@ +#!/bin/bash +# Run the interactive tutorial steps against resources created by CloudFormation. +# If the stack does not exist, offers to deploy it first. +set -eo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +TUT_DIR="$(basename "$SCRIPT_DIR")" +STACK_NAME="tutorial-$(echo "$TUT_DIR" | sed 's/^[0-9]*-//')" + +get_output() { aws cloudformation describe-stacks --stack-name "$STACK_NAME" --query "Stacks[0].Outputs[?OutputKey==\`$1\`].OutputValue" --output text 2>/dev/null; } + +run_cmd() { + echo "" + echo "$ $@" + eval "$@" +} + +# Check if stack exists, offer to create +STATUS=$(aws cloudformation describe-stacks --stack-name "$STACK_NAME" --query 'Stacks[0].StackStatus' --output text 2>/dev/null || echo "NONE") +if [ "$STATUS" = "NONE" ] || [ "$STATUS" = "DELETE_COMPLETE" ]; then + echo "Stack $STACK_NAME does not exist." + read -rp "Deploy it now? (y/n): " CHOICE + if [[ "$CHOICE" =~ ^[Yy]$ ]]; then + "$REPO_ROOT/deploy.sh" "$TUT_DIR" + else + echo "Cannot proceed without the stack. Deploy with: ./deploy.sh $TUT_DIR" + exit 1 + fi +fi +echo "Stack: $STACK_NAME ($STATUS)" + +BUCKET=$(get_output BucketName) +echo "Bucket: $BUCKET" + +echo "" +echo "--- Step 1: Upload an object ---" +echo "Hello from the S3 tutorial" > /tmp/s3-tut-test.txt +run_cmd aws s3 cp /tmp/s3-tut-test.txt "s3://$BUCKET/tutorial/hello.txt" + +echo "" +echo "--- Step 2: List objects ---" +run_cmd aws s3api list-objects-v2 --bucket "$BUCKET" --prefix tutorial/ --query "'Contents[].{Key:Key,Size:Size}'" --output table + +echo "" +echo "--- Step 3: Download the object ---" +run_cmd aws s3 cp "s3://$BUCKET/tutorial/hello.txt" /tmp/s3-tut-download.txt +echo "Content: $(cat /tmp/s3-tut-download.txt)" + +echo "" +echo "--- Step 4: Copy the object ---" +run_cmd aws s3 cp "s3://$BUCKET/tutorial/hello.txt" "s3://$BUCKET/tutorial/backup/hello.txt" + +echo "" +echo "--- Step 5: List all objects ---" +run_cmd aws s3api list-objects-v2 --bucket "$BUCKET" --prefix tutorial/ --query "'Contents[].Key'" --output table + +echo "" +echo "--- Step 6: Clean up tutorial objects ---" +run_cmd aws s3 rm "s3://$BUCKET/tutorial/" --recursive +rm -f /tmp/s3-tut-test.txt /tmp/s3-tut-download.txt +echo "Bucket remains for other tutorials." diff --git a/tuts/004-cloudmap-custom-attributes/README.md b/tuts/004-cloudmap-custom-attributes/README.md index 367f64e5..3f4f5ce5 100644 --- a/tuts/004-cloudmap-custom-attributes/README.md +++ b/tuts/004-cloudmap-custom-attributes/README.md @@ -26,4 +26,31 @@ The script creates the following AWS resources in order: - Service Discovery instance (e) - Service Discovery instance (f) -The script prompts you to clean up resources when you run it, including if there's an error part way through. If you need to clean up resources later, you can use the script log as a reference point for which resources were created. \ No newline at end of file +The script prompts you to clean up resources when you run it, including if there's an error part way through. If you need to clean up resources later, you can use the script log as a reference point for which resources were created. + + +## CloudFormation + +This tutorial includes a CloudFormation template that creates the same resources as the CLI script. + +**Resources created:** Cloud Map namespace, DynamoDB table, Lambda function + +### Deploy with CloudFormation + +```bash +./deploy.sh 004-cloudmap-custom-attributes +``` + +### Run the interactive steps + +Once deployed, run the interactive tutorial steps against the CloudFormation-created resources. Each command is displayed with resolved values so you can run them individually. + +```bash +bash tuts/004-cloudmap-custom-attributes/cloudmap-custom-attributes-cfn.sh +``` + +### Clean up + +```bash +./cleanup.sh 004-cloudmap-custom-attributes +``` diff --git a/tuts/004-cloudmap-custom-attributes/REVISION-HISTORY.md b/tuts/004-cloudmap-custom-attributes/REVISION-HISTORY.md new file mode 100644 index 00000000..12dfc8d5 --- /dev/null +++ b/tuts/004-cloudmap-custom-attributes/REVISION-HISTORY.md @@ -0,0 +1,20 @@ +# Revision History: 004-cloudmap-custom-attributes + +## Shell (CLI script) + +### 2025-07-29 v-b1 initial attempt +- Type: functional +- AWS CLI tutorials and scripts + +### 2025-07-30 v-b2 revision +- Type: functional +- readme + +### 2025-08-05 v-b3 revision +- Type: functional +- project READMEs list resources created + +### 2025-09-12 v1 published +- Type: functional +- unordered list bullets and trailing whitespace + diff --git a/tuts/004-cloudmap-custom-attributes/cfn-cloudmap-custom-attributes.yaml b/tuts/004-cloudmap-custom-attributes/cfn-cloudmap-custom-attributes.yaml new file mode 100644 index 00000000..35076c46 --- /dev/null +++ b/tuts/004-cloudmap-custom-attributes/cfn-cloudmap-custom-attributes.yaml @@ -0,0 +1,72 @@ +AWSTemplateFormatVersion: '2010-09-09' +Description: Cloud Map custom attributes - namespace, DynamoDB table, and Lambda function. + +Resources: + Namespace: + Type: AWS::ServiceDiscovery::HttpNamespace + Properties: + Name: !Sub '${AWS::StackName}-ns' + + Table: + Type: AWS::DynamoDB::Table + DeletionPolicy: Delete + Properties: + TableName: !Sub '${AWS::StackName}-data' + BillingMode: PAY_PER_REQUEST + Tags: + - Key: tutorial + Value: !Ref AWS::StackName + AttributeDefinitions: + - AttributeName: id + AttributeType: S + KeySchema: + - AttributeName: id + KeyType: HASH + + LambdaRole: + Type: AWS::IAM::Role + Properties: + AssumeRolePolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Principal: + Service: lambda.amazonaws.com + Action: sts:AssumeRole + ManagedPolicyArns: + - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole + Policies: + - PolicyName: dynamodb-access + PolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Action: + - dynamodb:PutItem + - dynamodb:GetItem + - dynamodb:Query + Resource: !GetAtt Table.Arn + + Function: + Type: AWS::Lambda::Function + Properties: + Runtime: python3.12 + Handler: index.handler + Role: !GetAtt LambdaRole.Arn + Environment: + Variables: + TABLE_NAME: !Ref Table + Code: + ZipFile: | + import os, boto3 + def handler(event, context): + table = boto3.resource('dynamodb').Table(os.environ['TABLE_NAME']) + return {"statusCode": 200} + +Outputs: + NamespaceId: + Value: !GetAtt Namespace.Id + TableName: + Value: !Ref Table + FunctionName: + Value: !Ref Function diff --git a/tuts/004-cloudmap-custom-attributes/cloudmap-custom-attributes-cfn.sh b/tuts/004-cloudmap-custom-attributes/cloudmap-custom-attributes-cfn.sh new file mode 100755 index 00000000..4c52f078 --- /dev/null +++ b/tuts/004-cloudmap-custom-attributes/cloudmap-custom-attributes-cfn.sh @@ -0,0 +1,53 @@ +#!/bin/bash +# Run the interactive tutorial steps against resources created by CloudFormation. +# If the stack does not exist, offers to deploy it first. +set -eo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +TUT_DIR="$(basename "$SCRIPT_DIR")" +STACK_NAME="tutorial-$(echo "$TUT_DIR" | sed 's/^[0-9]*-//')" + +get_output() { aws cloudformation describe-stacks --stack-name "$STACK_NAME" --query "Stacks[0].Outputs[?OutputKey==\`$1\`].OutputValue" --output text 2>/dev/null; } + +run_cmd() { + echo "" + echo "$ $@" + eval "$@" +} + +# Check if stack exists, offer to create +STATUS=$(aws cloudformation describe-stacks --stack-name "$STACK_NAME" --query 'Stacks[0].StackStatus' --output text 2>/dev/null || echo "NONE") +if [ "$STATUS" = "NONE" ] || [ "$STATUS" = "DELETE_COMPLETE" ]; then + echo "Stack $STACK_NAME does not exist." + read -rp "Deploy it now? (y/n): " CHOICE + if [[ "$CHOICE" =~ ^[Yy]$ ]]; then + "$REPO_ROOT/deploy.sh" "$TUT_DIR" + else + echo "Cannot proceed without the stack. Deploy with: ./deploy.sh $TUT_DIR" + exit 1 + fi +fi +echo "Stack: $STACK_NAME ($STATUS)" + +NS_ID=$(get_output NamespaceId) +TABLE=$(get_output TableName) +FUNC=$(get_output FunctionName) +echo "Namespace: $NS_ID | Table: $TABLE | Function: $FUNC" + +echo "" +echo "--- Step 1: List services in namespace ---" +run_cmd aws servicediscovery list-services --filters "Name=NAMESPACE_ID,Values=$NS_ID" --query "'Services[].{Id:Id,Name:Name}'" --output table + +echo "" +echo "--- Step 2: Invoke the Lambda function ---" +run_cmd aws lambda invoke --function-name "$FUNC" --cli-binary-format raw-in-base64-out --payload "'{\"action\":\"test\"}'" /tmp/cfn-resp.json +cat /tmp/cfn-resp.json && rm -f /tmp/cfn-resp.json + +echo "" +echo "--- Step 3: Scan DynamoDB table ---" +run_cmd aws dynamodb scan --table-name "$TABLE" --select COUNT --query "'{Count:Count}'" --output table + +echo "" +echo "Interactive steps complete." +echo "To delete stack: ./cleanup.sh $TUT_DIR" diff --git a/tuts/005-cloudfront-gettingstarted/README.md b/tuts/005-cloudfront-gettingstarted/README.md index c79244fb..3ae91a9e 100644 --- a/tuts/005-cloudfront-gettingstarted/README.md +++ b/tuts/005-cloudfront-gettingstarted/README.md @@ -12,4 +12,31 @@ The script creates the following AWS resources in order: - CloudFront distribution - S3 bucket policy -The script prompts you to clean up resources when you run it, including if there's an error part way through. If you need to clean up resources later, you can use the script log as a reference point for which resources were created. \ No newline at end of file +The script prompts you to clean up resources when you run it, including if there's an error part way through. If you need to clean up resources later, you can use the script log as a reference point for which resources were created. + + +## CloudFormation + +This tutorial includes a CloudFormation template that creates the same resources as the CLI script. + +**Resources created:** CloudFront distribution with S3 origin + +### Deploy with CloudFormation + +```bash +./deploy.sh 005-cloudfront-gettingstarted +``` + +### Run the interactive steps + +Once deployed, run the interactive tutorial steps against the CloudFormation-created resources. Each command is displayed with resolved values so you can run them individually. + +```bash +bash tuts/005-cloudfront-gettingstarted/cloudfront-gettingstarted-cfn.sh +``` + +### Clean up + +```bash +./cleanup.sh 005-cloudfront-gettingstarted +``` diff --git a/tuts/005-cloudfront-gettingstarted/REVISION-HISTORY.md b/tuts/005-cloudfront-gettingstarted/REVISION-HISTORY.md new file mode 100644 index 00000000..abba333d --- /dev/null +++ b/tuts/005-cloudfront-gettingstarted/REVISION-HISTORY.md @@ -0,0 +1,20 @@ +# Revision History: 005-cloudfront-gettingstarted + +## Shell (CLI script) + +### 2025-07-29 v-b1 initial attempt +- Type: functional +- AWS CLI tutorials and scripts + +### 2025-07-30 v-b2 revision +- Type: functional +- readme + +### 2025-08-05 v-b3 revision +- Type: functional +- project READMEs list resources created + +### 2025-09-12 v1 published +- Type: functional +- unordered list bullets and trailing whitespace + diff --git a/tuts/005-cloudfront-gettingstarted/cfn-cloudfront-gettingstarted.yaml b/tuts/005-cloudfront-gettingstarted/cfn-cloudfront-gettingstarted.yaml new file mode 100644 index 00000000..2463b022 --- /dev/null +++ b/tuts/005-cloudfront-gettingstarted/cfn-cloudfront-gettingstarted.yaml @@ -0,0 +1,58 @@ +AWSTemplateFormatVersion: '2010-09-09' +Description: CloudFront getting started - distribution with S3 origin. + +Resources: + OriginBucket: + Type: AWS::S3::Bucket + DeletionPolicy: Delete + + OAC: + Type: AWS::CloudFront::OriginAccessControl + Properties: + OriginAccessControlConfig: + Name: !Sub '${AWS::StackName}-oac' + OriginAccessControlOriginType: s3 + SigningBehavior: always + SigningProtocol: sigv4 + + Distribution: + Type: AWS::CloudFront::Distribution + Properties: + Tags: + - Key: tutorial + Value: !Ref AWS::StackName + DistributionConfig: + Enabled: true + DefaultRootObject: index.html + Origins: + - Id: S3Origin + DomainName: !GetAtt OriginBucket.RegionalDomainName + OriginAccessControlId: !GetAtt OAC.Id + S3OriginConfig: + OriginAccessIdentity: '' + DefaultCacheBehavior: + TargetOriginId: S3Origin + ViewerProtocolPolicy: redirect-to-https + CachePolicyId: 658327ea-f89d-4fab-a63d-7e88639e58f6 + + BucketPolicy: + Type: AWS::S3::BucketPolicy + Properties: + Bucket: !Ref OriginBucket + PolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Principal: + Service: cloudfront.amazonaws.com + Action: s3:GetObject + Resource: !Sub '${OriginBucket.Arn}/*' + Condition: + StringEquals: + AWS:SourceArn: !Sub 'arn:aws:cloudfront::${AWS::AccountId}:distribution/${Distribution}' + +Outputs: + DistributionDomain: + Value: !GetAtt Distribution.DomainName + BucketName: + Value: !Ref OriginBucket diff --git a/tuts/005-cloudfront-gettingstarted/cloudfront-gettingstarted-cfn.sh b/tuts/005-cloudfront-gettingstarted/cloudfront-gettingstarted-cfn.sh new file mode 100755 index 00000000..918ffecc --- /dev/null +++ b/tuts/005-cloudfront-gettingstarted/cloudfront-gettingstarted-cfn.sh @@ -0,0 +1,54 @@ +#!/bin/bash +# Run the interactive tutorial steps against resources created by CloudFormation. +# If the stack does not exist, offers to deploy it first. +set -eo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +TUT_DIR="$(basename "$SCRIPT_DIR")" +STACK_NAME="tutorial-$(echo "$TUT_DIR" | sed 's/^[0-9]*-//')" + +get_output() { aws cloudformation describe-stacks --stack-name "$STACK_NAME" --query "Stacks[0].Outputs[?OutputKey==\`$1\`].OutputValue" --output text 2>/dev/null; } + +run_cmd() { + echo "" + echo "$ $@" + eval "$@" +} + +# Check if stack exists, offer to create +STATUS=$(aws cloudformation describe-stacks --stack-name "$STACK_NAME" --query 'Stacks[0].StackStatus' --output text 2>/dev/null || echo "NONE") +if [ "$STATUS" = "NONE" ] || [ "$STATUS" = "DELETE_COMPLETE" ]; then + echo "Stack $STACK_NAME does not exist." + read -rp "Deploy it now? (y/n): " CHOICE + if [[ "$CHOICE" =~ ^[Yy]$ ]]; then + "$REPO_ROOT/deploy.sh" "$TUT_DIR" + else + echo "Cannot proceed without the stack. Deploy with: ./deploy.sh $TUT_DIR" + exit 1 + fi +fi +echo "Stack: $STACK_NAME ($STATUS)" + +DOMAIN=$(get_output DistributionDomain) +BUCKET=$(get_output BucketName) +echo "Distribution: $DOMAIN | Bucket: $BUCKET" + +echo "" +echo "--- Step 1: Upload content to origin ---" +echo "

Hello from CloudFront

" > /tmp/cf-index.html +run_cmd aws s3 cp /tmp/cf-index.html "s3://$BUCKET/index.html" --content-type text/html + +echo "" +echo "--- Step 2: Access via CloudFront ---" +echo "URL: https://$DOMAIN/index.html" +run_cmd curl -s --max-time 10 "https://$DOMAIN/index.html" + +echo "" +echo "--- Step 3: Clean up content ---" +run_cmd aws s3 rm "s3://$BUCKET/index.html" +rm -f /tmp/cf-index.html + +echo "" +echo "Interactive steps complete." +echo "To delete stack: ./cleanup.sh $TUT_DIR" diff --git a/tuts/008-vpc-private-servers-gs/README.md b/tuts/008-vpc-private-servers-gs/README.md index f78fe9d3..3583b13a 100644 --- a/tuts/008-vpc-private-servers-gs/README.md +++ b/tuts/008-vpc-private-servers-gs/README.md @@ -29,4 +29,31 @@ The script creates the following AWS resources in order: - EC2 nat gateway (b) - EC2 route (b) -The script prompts you to clean up resources when you run it, including if there's an error part way through. If you need to clean up resources later, you can use the script log as a reference point for which resources were created. \ No newline at end of file +The script prompts you to clean up resources when you run it, including if there's an error part way through. If you need to clean up resources later, you can use the script log as a reference point for which resources were created. + + +## CloudFormation + +This tutorial includes a CloudFormation template that creates the same resources as the CLI script. + +**Resources created:** VPC with NAT gateway and Auto Scaling group + +### Deploy with CloudFormation + +```bash +./deploy.sh 008-vpc-private-servers-gs +``` + +### Run the interactive steps + +Once deployed, run the interactive tutorial steps against the CloudFormation-created resources. Each command is displayed with resolved values so you can run them individually. + +```bash +bash tuts/008-vpc-private-servers-gs/vpc-private-servers-gs-cfn.sh +``` + +### Clean up + +```bash +./cleanup.sh 008-vpc-private-servers-gs +``` diff --git a/tuts/008-vpc-private-servers-gs/REVISION-HISTORY.md b/tuts/008-vpc-private-servers-gs/REVISION-HISTORY.md new file mode 100644 index 00000000..bf33aa57 --- /dev/null +++ b/tuts/008-vpc-private-servers-gs/REVISION-HISTORY.md @@ -0,0 +1,28 @@ +# Revision History: 008-vpc-private-servers-gs + +## Shell (CLI script) + +### 2025-07-29 v-b1 initial attempt +- Type: functional +- AWS CLI tutorials and scripts + +### 2025-07-30 v-b2 revision +- Type: functional +- readme + +### 2025-08-05 v-b3 revision +- Type: functional +- project READMEs list resources created + +### 2025-08-06 v-b4 revision +- Type: functional +- Remove AWS mention + +### 2025-09-10 v-b5 revision +- Type: functional +- fix tilde usage + +### 2025-09-12 v1 published +- Type: functional +- unordered list bullets and trailing whitespace + diff --git a/tuts/008-vpc-private-servers-gs/cfn-vpc-private-servers.yaml b/tuts/008-vpc-private-servers-gs/cfn-vpc-private-servers.yaml new file mode 100644 index 00000000..0d92e5fb --- /dev/null +++ b/tuts/008-vpc-private-servers-gs/cfn-vpc-private-servers.yaml @@ -0,0 +1,116 @@ +AWSTemplateFormatVersion: '2010-09-09' +Description: VPC with private servers - NAT gateway, Auto Scaling group in private subnet. + +Parameters: + LatestAmiId: + Type: AWS::SSM::Parameter::Value + Default: /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64 + +Resources: + VPC: + Type: AWS::EC2::VPC + Properties: + CidrBlock: 10.0.0.0/16 + Tags: + - Key: tutorial + Value: !Ref AWS::StackName + EnableDnsSupport: true + EnableDnsHostnames: true + + PublicSubnet: + Type: AWS::EC2::Subnet + Properties: + VpcId: !Ref VPC + CidrBlock: 10.0.1.0/24 + MapPublicIpOnLaunch: true + AvailabilityZone: !Select [0, !GetAZs ''] + + PrivateSubnet: + Type: AWS::EC2::Subnet + Properties: + VpcId: !Ref VPC + CidrBlock: 10.0.2.0/24 + AvailabilityZone: !Select [0, !GetAZs ''] + + IGW: + Type: AWS::EC2::InternetGateway + IGWAttach: + Type: AWS::EC2::VPCGatewayAttachment + Properties: + VpcId: !Ref VPC + InternetGatewayId: !Ref IGW + + NatEip: + Type: AWS::EC2::EIP + DependsOn: IGWAttach + NatGateway: + Type: AWS::EC2::NatGateway + Properties: + AllocationId: !GetAtt NatEip.AllocationId + SubnetId: !Ref PublicSubnet + + PublicRT: + Type: AWS::EC2::RouteTable + Properties: + VpcId: !Ref VPC + PublicRoute: + Type: AWS::EC2::Route + DependsOn: IGWAttach + Properties: + RouteTableId: !Ref PublicRT + DestinationCidrBlock: 0.0.0.0/0 + GatewayId: !Ref IGW + PublicRTAssoc: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + SubnetId: !Ref PublicSubnet + RouteTableId: !Ref PublicRT + + PrivateRT: + Type: AWS::EC2::RouteTable + Properties: + VpcId: !Ref VPC + PrivateRoute: + Type: AWS::EC2::Route + Properties: + RouteTableId: !Ref PrivateRT + DestinationCidrBlock: 0.0.0.0/0 + NatGatewayId: !Ref NatGateway + PrivateRTAssoc: + Type: AWS::EC2::SubnetRouteTableAssociation + Properties: + SubnetId: !Ref PrivateSubnet + RouteTableId: !Ref PrivateRT + + SG: + Type: AWS::EC2::SecurityGroup + Properties: + GroupDescription: Private instances + VpcId: !Ref VPC + + LaunchTemplate: + Type: AWS::EC2::LaunchTemplate + Properties: + LaunchTemplateData: + ImageId: !Ref LatestAmiId + InstanceType: t2.micro + SecurityGroupIds: + - !Ref SG + + ASG: + Type: AWS::AutoScaling::AutoScalingGroup + Properties: + LaunchTemplate: + LaunchTemplateId: !Ref LaunchTemplate + Version: !GetAtt LaunchTemplate.LatestVersionNumber + MinSize: '1' + MaxSize: '2' + DesiredCapacity: '1' + VPCZoneIdentifier: + - !Ref PrivateSubnet + +Outputs: + VpcId: + Value: !Ref VPC + ASGName: + Value: !Ref ASG diff --git a/tuts/008-vpc-private-servers-gs/vpc-private-servers-gs-cfn.sh b/tuts/008-vpc-private-servers-gs/vpc-private-servers-gs-cfn.sh new file mode 100755 index 00000000..d204ccca --- /dev/null +++ b/tuts/008-vpc-private-servers-gs/vpc-private-servers-gs-cfn.sh @@ -0,0 +1,47 @@ +#!/bin/bash +# Run the interactive tutorial steps against resources created by CloudFormation. +# If the stack does not exist, offers to deploy it first. +set -eo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +TUT_DIR="$(basename "$SCRIPT_DIR")" +STACK_NAME="tutorial-$(echo "$TUT_DIR" | sed 's/^[0-9]*-//')" + +get_output() { aws cloudformation describe-stacks --stack-name "$STACK_NAME" --query "Stacks[0].Outputs[?OutputKey==\`$1\`].OutputValue" --output text 2>/dev/null; } + +run_cmd() { + echo "" + echo "$ $@" + eval "$@" +} + +# Check if stack exists, offer to create +STATUS=$(aws cloudformation describe-stacks --stack-name "$STACK_NAME" --query 'Stacks[0].StackStatus' --output text 2>/dev/null || echo "NONE") +if [ "$STATUS" = "NONE" ] || [ "$STATUS" = "DELETE_COMPLETE" ]; then + echo "Stack $STACK_NAME does not exist." + read -rp "Deploy it now? (y/n): " CHOICE + if [[ "$CHOICE" =~ ^[Yy]$ ]]; then + "$REPO_ROOT/deploy.sh" "$TUT_DIR" + else + echo "Cannot proceed without the stack. Deploy with: ./deploy.sh $TUT_DIR" + exit 1 + fi +fi +echo "Stack: $STACK_NAME ($STATUS)" + +VPC_ID=$(get_output VpcId) +ASG=$(get_output ASGName) +echo "VPC: $VPC_ID | ASG: $ASG" + +echo "" +echo "--- Step 1: Describe Auto Scaling group ---" +run_cmd aws autoscaling describe-auto-scaling-groups --auto-scaling-group-names "$ASG" --query "'AutoScalingGroups[0].{Min:MinSize,Max:MaxSize,Desired:DesiredCapacity,Instances:Instances|length(@)}'" --output table + +echo "" +echo "--- Step 2: Check NAT gateway ---" +run_cmd aws ec2 describe-nat-gateways --filter "Name=vpc-id,Values=$VPC_ID" --query "'NatGateways[0].{Id:NatGatewayId,State:State,IP:NatGatewayAddresses[0].PublicIp}'" --output table + +echo "" +echo "Interactive steps complete." +echo "To delete stack: ./cleanup.sh $TUT_DIR" diff --git a/tuts/009-vpc-ipam-gs/README.md b/tuts/009-vpc-ipam-gs/README.md index bdba9590..7ce81c9f 100644 --- a/tuts/009-vpc-ipam-gs/README.md +++ b/tuts/009-vpc-ipam-gs/README.md @@ -14,4 +14,31 @@ The script creates the following AWS resources in order: - EC2 ipam pool (c) - EC2 vpc -The script prompts you to clean up resources when you run it, including if there's an error part way through. If you need to clean up resources later, you can use the script log as a reference point for which resources were created. \ No newline at end of file +The script prompts you to clean up resources when you run it, including if there's an error part way through. If you need to clean up resources later, you can use the script log as a reference point for which resources were created. + + +## CloudFormation + +This tutorial includes a CloudFormation template that creates the same resources as the CLI script. + +**Resources created:** VPC IPAM with pool and CIDR + +### Deploy with CloudFormation + +```bash +./deploy.sh 009-vpc-ipam-gs +``` + +### Run the interactive steps + +Once deployed, run the interactive tutorial steps against the CloudFormation-created resources. Each command is displayed with resolved values so you can run them individually. + +```bash +bash tuts/009-vpc-ipam-gs/vpc-ipam-gs-cfn.sh +``` + +### Clean up + +```bash +./cleanup.sh 009-vpc-ipam-gs +``` diff --git a/tuts/009-vpc-ipam-gs/REVISION-HISTORY.md b/tuts/009-vpc-ipam-gs/REVISION-HISTORY.md new file mode 100644 index 00000000..7fea4cd1 --- /dev/null +++ b/tuts/009-vpc-ipam-gs/REVISION-HISTORY.md @@ -0,0 +1,24 @@ +# Revision History: 009-vpc-ipam-gs + +## Shell (CLI script) + +### 2025-07-29 v-b1 initial attempt +- Type: functional +- AWS CLI tutorials and scripts + +### 2025-07-30 v-b2 revision +- Type: functional +- readme + +### 2025-08-05 v-b3 revision +- Type: functional +- project READMEs list resources created + +### 2025-08-06 v-b4 revision +- Type: functional +- Remove AWS mention + +### 2025-09-12 v1 published +- Type: functional +- unordered list bullets and trailing whitespace + diff --git a/tuts/009-vpc-ipam-gs/cfn-vpc-ipam.yaml b/tuts/009-vpc-ipam-gs/cfn-vpc-ipam.yaml new file mode 100644 index 00000000..cfd60a06 --- /dev/null +++ b/tuts/009-vpc-ipam-gs/cfn-vpc-ipam.yaml @@ -0,0 +1,31 @@ +AWSTemplateFormatVersion: '2010-09-09' +Description: VPC IPAM getting started - IPAM with pool and VPC. + +Resources: + IPAM: + Type: AWS::EC2::IPAM + Properties: + Tags: + - Key: tutorial + Value: !Ref AWS::StackName + OperatingRegions: + - RegionName: !Ref AWS::Region + + Pool: + Type: AWS::EC2::IPAMPool + Properties: + IpamScopeId: !GetAtt IPAM.PrivateDefaultScopeId + AddressFamily: ipv4 + Locale: !Ref AWS::Region + + PoolCidr: + Type: AWS::EC2::IPAMPoolCidr + Properties: + IpamPoolId: !GetAtt Pool.IpamPoolId + Cidr: 10.0.0.0/16 + +Outputs: + IpamId: + Value: !GetAtt IPAM.IpamId + PoolId: + Value: !GetAtt Pool.IpamPoolId diff --git a/tuts/009-vpc-ipam-gs/vpc-ipam-gs-cfn.sh b/tuts/009-vpc-ipam-gs/vpc-ipam-gs-cfn.sh new file mode 100755 index 00000000..4cc5ff62 --- /dev/null +++ b/tuts/009-vpc-ipam-gs/vpc-ipam-gs-cfn.sh @@ -0,0 +1,47 @@ +#!/bin/bash +# Run the interactive tutorial steps against resources created by CloudFormation. +# If the stack does not exist, offers to deploy it first. +set -eo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +TUT_DIR="$(basename "$SCRIPT_DIR")" +STACK_NAME="tutorial-$(echo "$TUT_DIR" | sed 's/^[0-9]*-//')" + +get_output() { aws cloudformation describe-stacks --stack-name "$STACK_NAME" --query "Stacks[0].Outputs[?OutputKey==\`$1\`].OutputValue" --output text 2>/dev/null; } + +run_cmd() { + echo "" + echo "$ $@" + eval "$@" +} + +# Check if stack exists, offer to create +STATUS=$(aws cloudformation describe-stacks --stack-name "$STACK_NAME" --query 'Stacks[0].StackStatus' --output text 2>/dev/null || echo "NONE") +if [ "$STATUS" = "NONE" ] || [ "$STATUS" = "DELETE_COMPLETE" ]; then + echo "Stack $STACK_NAME does not exist." + read -rp "Deploy it now? (y/n): " CHOICE + if [[ "$CHOICE" =~ ^[Yy]$ ]]; then + "$REPO_ROOT/deploy.sh" "$TUT_DIR" + else + echo "Cannot proceed without the stack. Deploy with: ./deploy.sh $TUT_DIR" + exit 1 + fi +fi +echo "Stack: $STACK_NAME ($STATUS)" + +IPAM_ID=$(get_output IpamId) +POOL_ID=$(get_output PoolId) +echo "IPAM: $IPAM_ID | Pool: $POOL_ID" + +echo "" +echo "--- Step 1: Describe the IPAM ---" +run_cmd aws ec2 describe-ipams --ipam-ids "$IPAM_ID" --query "'Ipams[0].{Id:IpamId,Region:IpamRegion}'" --output table + +echo "" +echo "--- Step 2: Get pool CIDRs ---" +run_cmd aws ec2 get-ipam-pool-cidrs --ipam-pool-id "$POOL_ID" --query "'IpamPoolCidrs[].{Cidr:Cidr,State:State}'" --output table + +echo "" +echo "Interactive steps complete." +echo "To delete stack: ./cleanup.sh $TUT_DIR" diff --git a/tuts/010-cloudmap-service-discovery/README.md b/tuts/010-cloudmap-service-discovery/README.md index ace17da1..511c8717 100644 --- a/tuts/010-cloudmap-service-discovery/README.md +++ b/tuts/010-cloudmap-service-discovery/README.md @@ -14,4 +14,31 @@ The script creates the following AWS resources in order: - Service Discovery instance - Service Discovery instance (b) -The script prompts you to clean up resources when you run it, including if there's an error part way through. If you need to clean up resources later, you can use the script log as a reference point for which resources were created. \ No newline at end of file +The script prompts you to clean up resources when you run it, including if there's an error part way through. If you need to clean up resources later, you can use the script log as a reference point for which resources were created. + + +## CloudFormation + +This tutorial includes a CloudFormation template that creates the same resources as the CLI script. + +**Resources created:** Cloud Map HTTP namespace and service + +### Deploy with CloudFormation + +```bash +./deploy.sh 010-cloudmap-service-discovery +``` + +### Run the interactive steps + +Once deployed, run the interactive tutorial steps against the CloudFormation-created resources. Each command is displayed with resolved values so you can run them individually. + +```bash +bash tuts/010-cloudmap-service-discovery/cloudmap-service-discovery-cfn.sh +``` + +### Clean up + +```bash +./cleanup.sh 010-cloudmap-service-discovery +``` diff --git a/tuts/010-cloudmap-service-discovery/REVISION-HISTORY.md b/tuts/010-cloudmap-service-discovery/REVISION-HISTORY.md new file mode 100644 index 00000000..43104ce4 --- /dev/null +++ b/tuts/010-cloudmap-service-discovery/REVISION-HISTORY.md @@ -0,0 +1,20 @@ +# Revision History: 010-cloudmap-service-discovery + +## Shell (CLI script) + +### 2025-07-29 v-b1 initial attempt +- Type: functional +- AWS CLI tutorials and scripts + +### 2025-07-30 v-b2 revision +- Type: functional +- readme + +### 2025-08-05 v-b3 revision +- Type: functional +- project READMEs list resources created + +### 2025-09-12 v1 published +- Type: functional +- unordered list bullets and trailing whitespace + diff --git a/tuts/010-cloudmap-service-discovery/cfn-cloudmap-service-discovery.yaml b/tuts/010-cloudmap-service-discovery/cfn-cloudmap-service-discovery.yaml new file mode 100644 index 00000000..77e34164 --- /dev/null +++ b/tuts/010-cloudmap-service-discovery/cfn-cloudmap-service-discovery.yaml @@ -0,0 +1,23 @@ +AWSTemplateFormatVersion: '2010-09-09' +Description: Cloud Map service discovery - HTTP namespace with service. + +Resources: + Namespace: + Type: AWS::ServiceDiscovery::HttpNamespace + Properties: + Name: !Sub '${AWS::StackName}' + Tags: + - Key: tutorial + Value: !Ref AWS::StackName + + Service: + Type: AWS::ServiceDiscovery::Service + Properties: + Name: web + NamespaceId: !GetAtt Namespace.Id + +Outputs: + NamespaceId: + Value: !GetAtt Namespace.Id + ServiceId: + Value: !GetAtt Service.Id diff --git a/tuts/010-cloudmap-service-discovery/cloudmap-service-discovery-cfn.sh b/tuts/010-cloudmap-service-discovery/cloudmap-service-discovery-cfn.sh new file mode 100755 index 00000000..9adf2877 --- /dev/null +++ b/tuts/010-cloudmap-service-discovery/cloudmap-service-discovery-cfn.sh @@ -0,0 +1,52 @@ +#!/bin/bash +# Run the interactive tutorial steps against resources created by CloudFormation. +# If the stack does not exist, offers to deploy it first. +set -eo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +TUT_DIR="$(basename "$SCRIPT_DIR")" +STACK_NAME="tutorial-$(echo "$TUT_DIR" | sed 's/^[0-9]*-//')" + +get_output() { aws cloudformation describe-stacks --stack-name "$STACK_NAME" --query "Stacks[0].Outputs[?OutputKey==\`$1\`].OutputValue" --output text 2>/dev/null; } + +run_cmd() { + echo "" + echo "$ $@" + eval "$@" +} + +# Check if stack exists, offer to create +STATUS=$(aws cloudformation describe-stacks --stack-name "$STACK_NAME" --query 'Stacks[0].StackStatus' --output text 2>/dev/null || echo "NONE") +if [ "$STATUS" = "NONE" ] || [ "$STATUS" = "DELETE_COMPLETE" ]; then + echo "Stack $STACK_NAME does not exist." + read -rp "Deploy it now? (y/n): " CHOICE + if [[ "$CHOICE" =~ ^[Yy]$ ]]; then + "$REPO_ROOT/deploy.sh" "$TUT_DIR" + else + echo "Cannot proceed without the stack. Deploy with: ./deploy.sh $TUT_DIR" + exit 1 + fi +fi +echo "Stack: $STACK_NAME ($STATUS)" + +NS_ID=$(get_output NamespaceId) +SVC_ID=$(get_output ServiceId) +echo "Namespace: $NS_ID | Service: $SVC_ID" + +echo "" +echo "--- Step 1: Register an instance ---" +INST_ID="i-$(openssl rand -hex 4)" +run_cmd aws servicediscovery register-instance --service-id "$SVC_ID" --instance-id "$INST_ID" --attributes AWS_INSTANCE_IPV4=10.0.0.1 + +echo "" +echo "--- Step 2: List instances ---" +run_cmd aws servicediscovery list-instances --service-id "$SVC_ID" --query "'Instances[].{Id:Id,IP:Attributes.AWS_INSTANCE_IPV4}'" --output table + +echo "" +echo "--- Step 3: Deregister the instance ---" +run_cmd aws servicediscovery deregister-instance --service-id "$SVC_ID" --instance-id "$INST_ID" + +echo "" +echo "Interactive steps complete." +echo "To delete stack: ./cleanup.sh $TUT_DIR" diff --git a/tuts/011-getting-started-batch-fargate/README.md b/tuts/011-getting-started-batch-fargate/README.md index 9b6f6dee..650de95d 100644 --- a/tuts/011-getting-started-batch-fargate/README.md +++ b/tuts/011-getting-started-batch-fargate/README.md @@ -14,4 +14,31 @@ The script creates the following AWS resources in order: - Batch job queue - Batch job definition -The script prompts you to clean up resources when you run it, including if there's an error part way through. If you need to clean up resources later, you can use the script log as a reference point for which resources were created. \ No newline at end of file +The script prompts you to clean up resources when you run it, including if there's an error part way through. If you need to clean up resources later, you can use the script log as a reference point for which resources were created. + + +## CloudFormation + +This tutorial includes a CloudFormation template that creates the same resources as the CLI script. + +**Resources created:** Batch compute environment and job queue on Fargate + +### Deploy with CloudFormation + +```bash +./deploy.sh 011-getting-started-batch-fargate +``` + +### Run the interactive steps + +Once deployed, run the interactive tutorial steps against the CloudFormation-created resources. Each command is displayed with resolved values so you can run them individually. + +```bash +bash tuts/011-getting-started-batch-fargate/batch-fargate-cfn.sh +``` + +### Clean up + +```bash +./cleanup.sh 011-getting-started-batch-fargate +``` diff --git a/tuts/011-getting-started-batch-fargate/REVISION-HISTORY.md b/tuts/011-getting-started-batch-fargate/REVISION-HISTORY.md new file mode 100644 index 00000000..219ac022 --- /dev/null +++ b/tuts/011-getting-started-batch-fargate/REVISION-HISTORY.md @@ -0,0 +1,24 @@ +# Revision History: 011-getting-started-batch-fargate + +## Shell (CLI script) + +### 2025-07-29 v-b1 initial attempt +- Type: functional +- AWS CLI tutorials and scripts + +### 2025-07-30 v-b2 revision +- Type: functional +- readme + +### 2025-08-05 v-b3 revision +- Type: functional +- project READMEs list resources created + +### 2025-09-12 v-b4 revision +- Type: functional +- unordered list bullets and trailing whitespace + +### 2026-04-13 v1 published +- Type: functional +- security and consistency updates + diff --git a/tuts/011-getting-started-batch-fargate/batch-fargate-cfn.sh b/tuts/011-getting-started-batch-fargate/batch-fargate-cfn.sh new file mode 100755 index 00000000..2a273067 --- /dev/null +++ b/tuts/011-getting-started-batch-fargate/batch-fargate-cfn.sh @@ -0,0 +1,48 @@ +#!/bin/bash +# Run the interactive tutorial steps against resources created by CloudFormation. +# If the stack does not exist, offers to deploy it first. +set -eo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +TUT_DIR="$(basename "$SCRIPT_DIR")" +STACK_NAME="tutorial-$(echo "$TUT_DIR" | sed 's/^[0-9]*-//')" + +get_output() { aws cloudformation describe-stacks --stack-name "$STACK_NAME" --query "Stacks[0].Outputs[?OutputKey==\`$1\`].OutputValue" --output text 2>/dev/null; } + +run_cmd() { + echo "" + echo "$ $@" + eval "$@" +} + +# Check if stack exists, offer to create +STATUS=$(aws cloudformation describe-stacks --stack-name "$STACK_NAME" --query 'Stacks[0].StackStatus' --output text 2>/dev/null || echo "NONE") +if [ "$STATUS" = "NONE" ] || [ "$STATUS" = "DELETE_COMPLETE" ]; then + echo "Stack $STACK_NAME does not exist." + read -rp "Deploy it now? (y/n): " CHOICE + if [[ "$CHOICE" =~ ^[Yy]$ ]]; then + "$REPO_ROOT/deploy.sh" "$TUT_DIR" + else + echo "Cannot proceed without the stack. Deploy with: ./deploy.sh $TUT_DIR" + exit 1 + fi +fi +echo "Stack: $STACK_NAME ($STATUS)" + +CE_ARN=$(get_output ComputeEnvironmentArn) +JQ_ARN=$(get_output JobQueueArn) +echo "Compute Env: $CE_ARN" +echo "Job Queue: $JQ_ARN" + +echo "" +echo "--- Step 1: Describe compute environment ---" +run_cmd aws batch describe-compute-environments --compute-environments "$CE_ARN" --query "'computeEnvironments[0].{name:computeEnvironmentName,state:state,status:status}'" --output table + +echo "" +echo "--- Step 2: Describe job queue ---" +run_cmd aws batch describe-job-queues --job-queues "$JQ_ARN" --query "'jobQueues[0].{name:jobQueueName,state:state,priority:priority}'" --output table + +echo "" +echo "Interactive steps complete." +echo "To delete stack: ./cleanup.sh $TUT_DIR" diff --git a/tuts/011-getting-started-batch-fargate/cfn-batch-fargate.yaml b/tuts/011-getting-started-batch-fargate/cfn-batch-fargate.yaml new file mode 100644 index 00000000..d477d321 --- /dev/null +++ b/tuts/011-getting-started-batch-fargate/cfn-batch-fargate.yaml @@ -0,0 +1,49 @@ +AWSTemplateFormatVersion: '2010-09-09' +Description: AWS Batch on Fargate - compute environment and job queue. + +Resources: + BatchServiceRole: + Type: AWS::IAM::Role + Properties: + AssumeRolePolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Principal: + Service: batch.amazonaws.com + Action: sts:AssumeRole + ManagedPolicyArns: + - arn:aws:iam::aws:policy/service-role/AWSBatchServiceRole + + ComputeEnvironment: + Type: AWS::Batch::ComputeEnvironment + Properties: + Type: MANAGED + ComputeResources: + Type: FARGATE + MaxvCpus: 4 + Subnets: + - !Select [0, !Split [',', !ImportValue tutorial-prereqs-vpc-public-PrivateSubnets]] + SecurityGroupIds: + - !Ref BatchSecurityGroup + ServiceRole: !GetAtt BatchServiceRole.Arn + + BatchSecurityGroup: + Type: AWS::EC2::SecurityGroup + Properties: + GroupDescription: Batch Fargate compute environment + VpcId: !ImportValue tutorial-prereqs-vpc-public-VpcId + + JobQueue: + Type: AWS::Batch::JobQueue + Properties: + Priority: 1 + ComputeEnvironmentOrder: + - Order: 1 + ComputeEnvironment: !Ref ComputeEnvironment + +Outputs: + ComputeEnvironmentArn: + Value: !Ref ComputeEnvironment + JobQueueArn: + Value: !Ref JobQueue diff --git a/tuts/012-transitgateway-gettingstarted/README.md b/tuts/012-transitgateway-gettingstarted/README.md index 98abdaf3..be3b1f26 100644 --- a/tuts/012-transitgateway-gettingstarted/README.md +++ b/tuts/012-transitgateway-gettingstarted/README.md @@ -20,4 +20,31 @@ The script creates the following AWS resources in order: - EC2 route - EC2 route (b) -The script prompts you to clean up resources when you run it, including if there's an error part way through. If you need to clean up resources later, you can use the script log as a reference point for which resources were created. \ No newline at end of file +The script prompts you to clean up resources when you run it, including if there's an error part way through. If you need to clean up resources later, you can use the script log as a reference point for which resources were created. + + +## CloudFormation + +This tutorial includes a CloudFormation template that creates the same resources as the CLI script. + +**Resources created:** Transit gateway with two VPCs + +### Deploy with CloudFormation + +```bash +./deploy.sh 012-transitgateway-gettingstarted +``` + +### Run the interactive steps + +Once deployed, run the interactive tutorial steps against the CloudFormation-created resources. Each command is displayed with resolved values so you can run them individually. + +```bash +bash tuts/012-transitgateway-gettingstarted/transitgateway-gettingstarted-cfn.sh +``` + +### Clean up + +```bash +./cleanup.sh 012-transitgateway-gettingstarted +``` diff --git a/tuts/012-transitgateway-gettingstarted/REVISION-HISTORY.md b/tuts/012-transitgateway-gettingstarted/REVISION-HISTORY.md new file mode 100644 index 00000000..d34a7c12 --- /dev/null +++ b/tuts/012-transitgateway-gettingstarted/REVISION-HISTORY.md @@ -0,0 +1,20 @@ +# Revision History: 012-transitgateway-gettingstarted + +## Shell (CLI script) + +### 2025-07-29 v-b1 initial attempt +- Type: functional +- AWS CLI tutorials and scripts + +### 2025-07-30 v-b2 revision +- Type: functional +- readme + +### 2025-08-05 v-b3 revision +- Type: functional +- project READMEs list resources created + +### 2025-09-12 v1 published +- Type: functional +- unordered list bullets and trailing whitespace + diff --git a/tuts/012-transitgateway-gettingstarted/cfn-transitgateway.yaml b/tuts/012-transitgateway-gettingstarted/cfn-transitgateway.yaml new file mode 100644 index 00000000..dccacf5c --- /dev/null +++ b/tuts/012-transitgateway-gettingstarted/cfn-transitgateway.yaml @@ -0,0 +1,71 @@ +AWSTemplateFormatVersion: '2010-09-09' +Description: Transit Gateway getting started - TGW with two VPCs. + +Resources: + VPC1: + Type: AWS::EC2::VPC + Properties: + CidrBlock: 10.0.0.0/16 + Tags: + - Key: Name + Value: !Sub '${AWS::StackName}-vpc1' + - Key: tutorial + Value: !Ref AWS::StackName + + VPC2: + Type: AWS::EC2::VPC + Properties: + CidrBlock: 10.1.0.0/16 + Tags: + - Key: Name + Value: !Sub '${AWS::StackName}-vpc2' + - Key: tutorial + Value: !Ref AWS::StackName + + Subnet1: + Type: AWS::EC2::Subnet + Properties: + VpcId: !Ref VPC1 + CidrBlock: 10.0.1.0/24 + AvailabilityZone: !Select [0, !GetAZs ''] + + Subnet2: + Type: AWS::EC2::Subnet + Properties: + VpcId: !Ref VPC2 + CidrBlock: 10.1.1.0/24 + AvailabilityZone: !Select [0, !GetAZs ''] + + TGW: + Type: AWS::EC2::TransitGateway + Properties: + Description: Tutorial transit gateway + Tags: + - Key: Name + Value: !Sub '${AWS::StackName}-tgw' + - Key: tutorial + Value: !Ref AWS::StackName + + TGWAttach1: + Type: AWS::EC2::TransitGatewayAttachment + Properties: + TransitGatewayId: !Ref TGW + VpcId: !Ref VPC1 + SubnetIds: + - !Ref Subnet1 + + TGWAttach2: + Type: AWS::EC2::TransitGatewayAttachment + Properties: + TransitGatewayId: !Ref TGW + VpcId: !Ref VPC2 + SubnetIds: + - !Ref Subnet2 + +Outputs: + TransitGatewayId: + Value: !Ref TGW + VPC1Id: + Value: !Ref VPC1 + VPC2Id: + Value: !Ref VPC2 diff --git a/tuts/012-transitgateway-gettingstarted/transitgateway-gettingstarted-cfn.sh b/tuts/012-transitgateway-gettingstarted/transitgateway-gettingstarted-cfn.sh new file mode 100755 index 00000000..efd27ed3 --- /dev/null +++ b/tuts/012-transitgateway-gettingstarted/transitgateway-gettingstarted-cfn.sh @@ -0,0 +1,48 @@ +#!/bin/bash +# Run the interactive tutorial steps against resources created by CloudFormation. +# If the stack does not exist, offers to deploy it first. +set -eo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +TUT_DIR="$(basename "$SCRIPT_DIR")" +STACK_NAME="tutorial-$(echo "$TUT_DIR" | sed 's/^[0-9]*-//')" + +get_output() { aws cloudformation describe-stacks --stack-name "$STACK_NAME" --query "Stacks[0].Outputs[?OutputKey==\`$1\`].OutputValue" --output text 2>/dev/null; } + +run_cmd() { + echo "" + echo "$ $@" + eval "$@" +} + +# Check if stack exists, offer to create +STATUS=$(aws cloudformation describe-stacks --stack-name "$STACK_NAME" --query 'Stacks[0].StackStatus' --output text 2>/dev/null || echo "NONE") +if [ "$STATUS" = "NONE" ] || [ "$STATUS" = "DELETE_COMPLETE" ]; then + echo "Stack $STACK_NAME does not exist." + read -rp "Deploy it now? (y/n): " CHOICE + if [[ "$CHOICE" =~ ^[Yy]$ ]]; then + "$REPO_ROOT/deploy.sh" "$TUT_DIR" + else + echo "Cannot proceed without the stack. Deploy with: ./deploy.sh $TUT_DIR" + exit 1 + fi +fi +echo "Stack: $STACK_NAME ($STATUS)" + +TGW_ID=$(get_output TransitGatewayId) +VPC1=$(get_output VPC1Id) +VPC2=$(get_output VPC2Id) +echo "TGW: $TGW_ID | VPC1: $VPC1 | VPC2: $VPC2" + +echo "" +echo "--- Step 1: Describe the transit gateway ---" +run_cmd aws ec2 describe-transit-gateways --transit-gateway-ids "$TGW_ID" --query "'TransitGateways[0].{Id:TransitGatewayId,State:State}'" --output table + +echo "" +echo "--- Step 2: List attachments ---" +run_cmd aws ec2 describe-transit-gateway-attachments --filters "Name=transit-gateway-id,Values=$TGW_ID" --query "'TransitGatewayAttachments[].{VPC:ResourceId,State:State}'" --output table + +echo "" +echo "Interactive steps complete." +echo "To delete stack: ./cleanup.sh $TUT_DIR" diff --git a/tuts/038-redshift-serverless/redshift-serverless.sh b/tuts/038-redshift-serverless/redshift-serverless.sh index c102c42b..93651d36 100755 --- a/tuts/038-redshift-serverless/redshift-serverless.sh +++ b/tuts/038-redshift-serverless/redshift-serverless.sh @@ -556,8 +556,8 @@ else fi fi -# Query 2: Find events in the 99.9 percentile in terms of all time gross sales -echo "Running query: Find events in the 99.9 percentile in terms of all time gross sales..." +# Query 2: Find events in the 99.9 percentile in terms of all time total sales +echo "Running query: Find events in the 99.9 percentile in terms of all time total sales..." QUERY2_OUTPUT=$(aws redshift-data execute-statement \ --database "$DB_NAME" \ --workgroup-name "$WORKGROUP_NAME" \