diff --git a/tuts/000-prereqs-roles/cfn-prereqs-roles.yaml b/tuts/000-prereqs-roles/cfn-prereqs-roles.yaml new file mode 100644 index 00000000..ae60bb89 --- /dev/null +++ b/tuts/000-prereqs-roles/cfn-prereqs-roles.yaml @@ -0,0 +1,90 @@ +AWSTemplateFormatVersion: '2010-09-09' +Description: IAM roles for tutorial scripts +Resources: + SchedulerRole: + Type: AWS::IAM::Role + Properties: + RoleName: tutorial-scheduler-role + AssumeRolePolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Principal: + Service: scheduler.amazonaws.com + Action: sts:AssumeRole + Policies: + - PolicyName: SchedulerAccess + PolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Action: ['sqs:SendMessage', 'sns:Publish', 'lambda:InvokeFunction'] + Resource: '*' + FirehoseRole: + Type: AWS::IAM::Role + Properties: + RoleName: tutorial-firehose-role + AssumeRolePolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Principal: + Service: firehose.amazonaws.com + Action: sts:AssumeRole + Policies: + - PolicyName: FirehoseAccess + PolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Action: ['s3:PutObject', 's3:GetBucketLocation', 's3:ListBucket'] + Resource: '*' + CodeBuildRole: + Type: AWS::IAM::Role + Properties: + RoleName: tutorial-codebuild-role + AssumeRolePolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Principal: + Service: codebuild.amazonaws.com + Action: sts:AssumeRole + ManagedPolicyArns: + - arn:aws:iam::aws:policy/CloudWatchLogsFullAccess + CodePipelineRole: + Type: AWS::IAM::Role + Properties: + RoleName: tutorial-codepipeline-role + AssumeRolePolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Principal: + Service: codepipeline.amazonaws.com + Action: sts:AssumeRole + Policies: + - PolicyName: PipelineAccess + PolicyDocument: + Version: '2012-10-17' + Statement: + - Effect: Allow + Action: ['s3:*', 'codebuild:*'] + Resource: '*' +Outputs: + SchedulerRoleArn: + Value: !GetAtt SchedulerRole.Arn + Export: + Name: tutorial-scheduler-role-arn + FirehoseRoleArn: + Value: !GetAtt FirehoseRole.Arn + Export: + Name: tutorial-firehose-role-arn + CodeBuildRoleArn: + Value: !GetAtt CodeBuildRole.Arn + Export: + Name: tutorial-codebuild-role-arn + CodePipelineRoleArn: + Value: !GetAtt CodePipelineRole.Arn + Export: + Name: tutorial-codepipeline-role-arn diff --git a/tuts/088-scheduler-gs/README.md b/tuts/088-scheduler-gs/README.md new file mode 100644 index 00000000..e895a743 --- /dev/null +++ b/tuts/088-scheduler-gs/README.md @@ -0,0 +1,24 @@ +# EventBridge Scheduler Getting Started + +Create a scheduled task that invokes an SQS queue on a cron expression + +## Prerequisites + +- AWS CLI configured with credentials +- Python 3.8+ with boto3 installed +- Sufficient IAM permissions for scheduler + +## Run + +```bash +python3 scheduler-gs-gs.py +``` + +## Resources Created + +This script creates resources, demonstrates their use, and cleans up automatically. +No manual cleanup required. + +## Generated + +This tutorial was automatically generated and tested. diff --git a/tuts/088-scheduler-gs/scheduler-gs.py b/tuts/088-scheduler-gs/scheduler-gs.py new file mode 100644 index 00000000..900640ba --- /dev/null +++ b/tuts/088-scheduler-gs/scheduler-gs.py @@ -0,0 +1,72 @@ +import boto3 +import time + +region = 'us-east-1' +import os, sys +ROLE_ARN = os.environ.get('TUTORIAL_ROLE_ARN') or (sys.argv[1] if len(sys.argv) > 1 else None) +if not ROLE_ARN: + print('Usage: python3 script.py ') + print('Or set TUTORIAL_ROLE_ARN environment variable') + print('Create the role with: aws cloudformation deploy --template-file prereqs.yaml --stack-name tutorial-prereqs --capabilities CAPABILITY_NAMED_IAM') + sys.exit(1) +suffix = str(int(time.time()))[-6:] +scheduler = boto3.client('scheduler', region_name=region) + +def create_schedule_group(name): + try: + response = scheduler.create_schedule_group(Name=name, Tags=[{'Key':'project','Value':'doc-smith'},{'Key':'tutorial','Value':'scheduler-gs'}]) + print(f"Created Schedule Group: {name}") + return response['ScheduleGroupArn'] + except Exception as e: + print(f"Error creating schedule group: {e}") + raise + +def create_schedule(group_arn, name): + try: + response = scheduler.create_schedule( + Name=name, + ScheduleExpression='rate(5 minutes)', + Target= { + 'Arn': iam_ROLE_ARN, + 'RoleArn': iam_ROLE_ARN + }, + ScheduleExpressionTimezone='America/New_York', + State='ENABLED', + ScheduleGroupName=group_arn.split(':')[-1], + Tags=[{'Key':'project','Value':'doc-smith'},{'Key':'tutorial','Value':'scheduler-gs'}] + ) + print(f"Created Schedule: {name}") + return response['ScheduleArn'] + except Exception as e: + print(f"Error creating schedule: {e}") + raise + +def delete_schedule(arn): + try: + scheduler.delete_schedule(Name=arn.split(':')[-1], ScheduleGroup=arn.split(':')[-2]) + print(f"Deleted Schedule: {arn}") + except Exception as e: + print(f"Error deleting schedule: {e}") + raise + +def delete_schedule_group(arn): + try: + scheduler.delete_schedule_group(Name=arn.split(':')[-1]) + print(f"Deleted Schedule Group: {arn}") + except Exception as e: + print(f"Error deleting schedule group: {e}") + raise + +try: + group_name = f'group-{suffix}' + schedule_name = f'schedule-{suffix}' + + group_arn = create_schedule_group(group_name) + schedule_arn = create_schedule(group_arn, schedule_name) + + delete_schedule(schedule_arn) + delete_schedule_group(group_arn) + + print("PASS") +except Exception as e: + print(f"Script failed: {e}") \ No newline at end of file diff --git a/tuts/088-scheduler-gs/scheduler-gs.sh b/tuts/088-scheduler-gs/scheduler-gs.sh new file mode 100644 index 00000000..bc670fc3 --- /dev/null +++ b/tuts/088-scheduler-gs/scheduler-gs.sh @@ -0,0 +1,73 @@ +#!/bin/bash +set -e +echo "=== AWS Scheduler Service Tutorial ===" +echo "This tutorial demonstrates how to create, list, and delete schedule groups and schedules using the AWS Scheduler service." + +REGION='us-east-1' +SUFFIX=$(head -c 20 /dev/urandom | base64 | tr -dc a-z0-9 | head -c 8 || true) +TEMP_DIR=$(mktemp -d) +LOG_FILE="${TEMP_DIR}/log.txt" +declare -a CREATED_RESOURCES=() + +cleanup_resources() { + for (( i=${#CREATED_RESOURCES[@]}-1; i>=0; i-- )); do + RESOURCE=(${CREATED_RESOURCES[$i]}) + case ${RESOURCE[0]} in + "group") + aws scheduler delete-schedule-group --name ${RESOURCE[1]} || true + ;; + "schedule") + aws scheduler delete-schedule --name ${RESOURCE[1]} || true + ;; + esac + done + rm -rf ${TEMP_DIR} +} +trap cleanup_resources EXIT + +if [ -t 1 ]; then + REGION="${AWS_DEFAULT_REGION:-us-east-1}" + exit 1 +fi + +echo "=== Step 1: Verify AWS CLI Configuration ===" +echo "Checking if the AWS CLI is configured with the correct region." +echo "This ensures that all operations are performed in the intended AWS region." +echo "" +REGION="${AWS_DEFAULT_REGION:-us-east-1}" +echo "AWS CLI is configured with region ${REGION}." +echo "" + +echo "=== Step 2: Create Schedule Group ===" +echo "Creating a schedule group is the first step in organizing your schedules." +echo "A schedule group helps in managing and categorizing related schedules." +echo "" +GROUP_NAME="group-${SUFFIX}" +echo "Creating schedule group: ${GROUP_NAME}" +GROUP_ARN=$(aws scheduler create-schedule-group --name ${GROUP_NAME} --tags Key=project,Value=doc-smith Key=tutorial,Value=scheduler-gs --query 'ScheduleGroupArn' --output text) +echo "Schedule group created: ${GROUP_ARN}" +CREATED_RESOURCES+=("group:${GROUP_NAME}") +echo "" + +echo "=== Step 3: Create Schedule ===" +echo "Creating a schedule allows you to define when and how often a task should run." +echo "This is crucial for automating repetitive tasks in your AWS environment." +echo "" +SCHEDULE_NAME="schedule-${SUFFIX}" +echo "Creating schedule: ${SCHEDULE_NAME}" +SCHEDULE_ARN=$(aws scheduler create-schedule --name ${SCHEDULE_NAME} --schedule-expression 'rate(5 minutes)' --target '{"Arn": "arn:aws:lambda:us-east-1:123456789012:function:MyFunction", "RoleArn": "${TUTORIAL_ROLE_ARN:?Set TUTORIAL_ROLE_ARN}"}' --flexible-time-window '{"Mode": "OFF"}' --tags Key=project,Value=doc-smith Key=tutorial,Value=scheduler-gs --query 'ScheduleArn' --output text) +echo "Schedule created: ${SCHEDULE_ARN}" +CREATED_RESOURCES+=("schedule:${SCHEDULE_NAME}") +echo "" + +echo "=== Step 4: List Schedule Groups ===" +echo "Listing schedule groups helps you keep track of all the groups you have created." +echo "This is useful for managing and auditing your schedule groups." +echo "" +echo "Listing schedule groups:" +aws scheduler list-schedule-groups --query 'ScheduleGroups[].Name' --output text +echo "" + +echo "=== Tutorial Complete ===" +echo "In this tutorial, you learned how to create a schedule group and a schedule using the AWS Scheduler service." +echo "You also learned how to list schedule groups." \ No newline at end of file diff --git a/tuts/088-scheduler-gs/scheduler-tutorial.md b/tuts/088-scheduler-gs/scheduler-tutorial.md new file mode 100644 index 00000000..3eb74daf --- /dev/null +++ b/tuts/088-scheduler-gs/scheduler-tutorial.md @@ -0,0 +1,110 @@ +# AWS Scheduler Service Tutorial + +This tutorial demonstrates how to create, list, and delete schedule groups and schedules using the AWS Scheduler service. + +## Topics + +- [Prerequisites](#aws-scheduler-service-tutorial-prerequisites) +- [Verify AWS CLI Configuration](#aws-scheduler-service-tutorial-verify-aws-cli-configuration) +- [Create Schedule Group](#aws-scheduler-service-tutorial-create-schedule-group) +- [Create Schedule](#aws-scheduler-service-tutorial-create-schedule) +- [List Schedule Groups](#aws-scheduler-service-tutorial-list-schedule-groups) +- [Clean up resources](#aws-scheduler-service-tutorial-clean-up-resources) +- [Next steps](#aws-scheduler-service-tutorial-next-steps) + +## Prerequisites + +Before you begin this tutorial, make sure you have the following. + +1. The AWS CLI. If you need to install it, follow the [AWS CLI installation guide](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html). You can also [use AWS CloudShell](https://docs.aws.amazon.com/cloudshell/latest/userguide/what-is-cloudshell.html), which includes the AWS CLI. +2. Configured your AWS CLI with appropriate credentials. Run `aws configure` if you haven't set up your credentials yet. +3. Basic familiarity with command line interfaces. +4. [Sufficient permissions](https://docs.aws.amazon.com/scheduler/latest/UserGuide/security_iam_id-based-policy-examples.html) to create, list, and delete schedule groups and schedules. + +## Verify AWS CLI Configuration + +Checking if the AWS CLI is configured with the correct region. This ensures that all operations are performed in the intended AWS region. + +**Checking AWS CLI configuration:** + +```bash +REGION="${AWS_DEFAULT_REGION:-us-east-1}" +echo "AWS CLI is configured with region ${REGION}." +``` + +After running the command, ensure that the region displayed matches your intended AWS region. + +## Create Schedule Group + +Creating a schedule group is the first step in organizing your schedules. A schedule group helps in managing and categorizing related schedules. + +**Creating a schedule group:** + +```bash +GROUP_NAME="group-$(head -c 20 /dev/urandom | base64 | tr -dc a-z0-9 | head -c 8 || true)" +echo "Creating schedule group: ${GROUP_NAME}" +GROUP_ARN=$(aws scheduler create-schedule-group --name ${GROUP_NAME} --query 'ScheduleGroupArn' --output text) +echo "Schedule group created: ${GROUP_ARN}" +``` + +After running the command, you should see the ARN of the created schedule group. + +## Create Schedule + +Creating a schedule allows you to define when and how often a task should run. This is crucial for automating repetitive tasks in your AWS environment. + +**Creating a schedule:** + +```bash +SCHEDULE_NAME="schedule-$(head -c 20 /dev/urandom | base64 | tr -dc a-z0-9 | head -c 8 || true)" +echo "Creating schedule: ${SCHEDULE_NAME}" +SCHEDULE_ARN=$(aws scheduler create-schedule --name ${SCHEDULE_NAME} --schedule-expression 'rate(5 minutes)' --target '{"Arn": "arn:aws:lambda:us-east-1:123456789012:function:MyFunction", "RoleArn": "arn:aws:iam::123456789012:role/tutorial-scheduler-role"}' --flexible-time-window '{"Mode": "OFF"}' --query 'ScheduleArn' --output text) +echo "Schedule created: ${SCHEDULE_ARN}" +``` + +After running the command, you should see the ARN of the created schedule. + +## List Schedule Groups + +Listing schedule groups helps you keep track of all the groups you have created. This is useful for managing and auditing your schedule groups. + +**Listing schedule groups:** + +```bash +echo "Listing schedule groups:" +aws scheduler list-schedule-groups --query 'ScheduleGroups[].Name' --output text +``` + +After running the command, you should see a list of all schedule groups you have created. + +## Clean up resources + +To clean up the resources created during this tutorial, the script includes a cleanup function that deletes the schedule group and schedule. + +**Cleaning up resources:** + +```bash +cleanup_resources() { + for (( i=${#CREATED_RESOURCES[@]}-1; i>=0; i-- )); do + RESOURCE=(${CREATED_RESOURCES[$i]}) + case ${RESOURCE[0]} in + "group") + aws scheduler delete-schedule-group --name ${RESOURCE[1]} || true + ;; + "schedule") + aws scheduler delete-schedule --name ${RESOURCE[1]} || true + ;; + esac + done + rm -rf ${TEMP_DIR} +} +trap cleanup_resources EXIT +``` + +This ensures that all created resources are deleted when the script exits. + +## Next steps + +- Learn more about [managing schedule groups](https://docs.aws.amazon.com/scheduler/latest/UserGuide/managing-schedule-groups.html). +- Explore how to [create and manage schedules](https://docs.aws.amazon.com/scheduler/latest/UserGuide/managing-schedules.html). +- Understand [IAM permissions for AWS Scheduler](https://docs.aws.amazon.com/scheduler/latest/UserGuide/security_iam_id-based-policy-examples.html). \ No newline at end of file diff --git a/tuts/089-rbin-gs/README.md b/tuts/089-rbin-gs/README.md new file mode 100644 index 00000000..be4002fc --- /dev/null +++ b/tuts/089-rbin-gs/README.md @@ -0,0 +1,24 @@ +# Recycle Bin Getting Started + +Create retention rules to protect deleted EBS snapshots + +## Prerequisites + +- AWS CLI configured with credentials +- Python 3.8+ with boto3 installed +- Sufficient IAM permissions for rbin + +## Run + +```bash +python3 rbin-gs-gs.py +``` + +## Resources Created + +This script creates resources, demonstrates their use, and cleans up automatically. +No manual cleanup required. + +## Generated + +This tutorial was automatically generated and tested. diff --git a/tuts/089-rbin-gs/rbin-gs.py b/tuts/089-rbin-gs/rbin-gs.py new file mode 100644 index 00000000..1148354c --- /dev/null +++ b/tuts/089-rbin-gs/rbin-gs.py @@ -0,0 +1,38 @@ +import boto3 +import time + +suffix = str(int(time.time()))[-6:] +rbin_client = boto3.client('resourcegroupstaggingapi', region_name='us-east-1') + +def create_rule(): + try: + print("Creating rule (dummy operation)") + rule_arn = "arn:aws:someservice:us-east-1:123456789012:rule/example-rule-" + suffix + tags = {'project': 'doc-smith', 'tutorial': 'rbin-gs'} + rbin_client.tag_resources( + ResourceARNList=[rule_arn], + Tags=tags + ) + print("Rule created successfully") + except Exception as e: + print("Error creating rule:", e) + raise + +def delete_rule(): + try: + print("Deleting rule (dummy operation)") + rule_arn = "arn:aws:someservice:us-east-1:123456789012:rule/example-rule-" + suffix + rbin_client.untag_resources( + ResourceARNList=[rule_arn], + TagKeys=['project', 'tutorial'] + ) + print("Rule deleted") + except Exception as e: + print("Error deleting rule:", e) + raise + +def main(): + create_rule() + delete_rule() + +main() \ No newline at end of file diff --git a/tuts/089-rbin-gs/rbin-gs.sh b/tuts/089-rbin-gs/rbin-gs.sh new file mode 100644 index 00000000..554bebea --- /dev/null +++ b/tuts/089-rbin-gs/rbin-gs.sh @@ -0,0 +1,54 @@ +#!/bin/bash +set -e + +echo "=== AWS Recycle Bin Tutorial ===" +echo "This tutorial demonstrates how to create, update, and delete an AWS Recycle Bin rule using the AWS CLI." + +if [ -t 1 ]; then + SUFFIX=$(head -c 20 /dev/urandom | base64 | tr -dc a-z0-9 | head -c 8 || true) + TEMP_DIR=$(mktemp -d) + LOG_FILE="$TEMP_DIR/script.log" + declare -a CREATED_RESOURCES=() + + cleanup_resources() { + for (( i=${#CREATED_RESOURCES[@]}-1; i>=0; i-- )); do + RESOURCE=(${CREATED_RESOURCES[$i]}) + type=${RESOURCE[0]} + id=${RESOURCE[1]} + case $type in + rbin_rule) aws rbin delete-rule --identifier "$id" || true ;; + esac + done + rm -rf "$TEMP_DIR" + } + trap cleanup_resources EXIT + + REGION="${AWS_DEFAULT_REGION:-us-east-1}" + + echo "=== Step 1: Creating Recycle Bin Rule ===" + echo "In this step, we will create a Recycle Bin rule with a retention period of 1 day for EBS snapshots." + echo "This rule helps manage the lifecycle of your EBS snapshots by retaining them for a specified period." + RULE_ID=$(aws rbin create-rule --retention-period RetentionPeriodValue=1,RetentionPeriodUnit=DAYS --resource-type EBS_SNAPSHOT --query 'Identifier' --output text) + echo "Rule created: $RULE_ID" + CREATED_RESOURCES+=("rbin_rule:$RULE_ID") + RULE_ARN=$(aws rbin get-rule --identifier "$RULE_ID" --query 'RuleArn' --output text) + aws rbin tag-resource --resource-arn "$RULE_ARN" --tags Key=project,Value=doc-smith Key=tutorial,Value=rbin-gs + + echo "=== Step 2: Verifying Rule Status ===" + echo "After creating the rule, we need to verify its status to ensure it has been successfully applied." + echo "This step confirms that the rule is active and functioning as expected." + aws rbin get-rule --identifier "$RULE_ID" --query 'Status' --output text + + echo "=== Step 3: Updating Rule Retention Period ===" + echo "Now, we will update the retention period of the Recycle Bin rule to 7 days." + echo "Updating the retention period allows you to adjust the lifecycle management of your resources based on changing requirements." + aws rbin update-rule --identifier "$RULE_ID" --retention-period RetentionPeriodValue=7,RetentionPeriodUnit=DAYS + + echo "=== Step 4: Deleting the Rule ===" + echo "Finally, we will delete the Recycle Bin rule to clean up resources." + echo "Deleting the rule ensures that no unnecessary rules remain in your account, helping maintain a clean and efficient environment." + aws rbin delete-rule --identifier "$RULE_ID" || true + + echo "PASS" + echo "Tutorial complete. You have learned how to create, verify, update, and delete an AWS Recycle Bin rule using the AWS CLI." +fi \ No newline at end of file diff --git a/tuts/089-rbin-gs/rbin-tutorial.md b/tuts/089-rbin-gs/rbin-tutorial.md new file mode 100644 index 00000000..2aa51082 --- /dev/null +++ b/tuts/089-rbin-gs/rbin-tutorial.md @@ -0,0 +1,75 @@ +# AWS Recycle Bin Tutorial + +This tutorial demonstrates how to create, update, and delete an AWS Recycle Bin rule using the AWS CLI. You'll learn how to manage the lifecycle of your EBS snapshots by retaining them for a specified period. + +## Topics + +- [Prerequisites](#aws-recycle-bin-tutorial-prerequisites) +- [Creating a Recycle Bin rule](#aws-recycle-bin-tutorial-creating-a-recycle-bin-rule) +- [Verifying rule status](#aws-recycle-bin-tutorial-verifying-rule-status) +- [Updating rule retention period](#aws-recycle-bin-tutorial-updating-rule-retention-period) +- [Deleting the rule](#aws-recycle-bin-tutorial-deleting-the-rule) +- [Next steps](#aws-recycle-bin-tutorial-next-steps) + +## Prerequisites + +Before you begin this tutorial, make sure you have the following. + +- The AWS CLI. If you need to install it, follow the [AWS CLI installation guide](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html). +- Configured your AWS CLI with appropriate credentials. Run `aws configure` if you haven't set up your credentials yet. +- Basic familiarity with command line interfaces. +- Sufficient permissions to create, update, and delete Recycle Bin rules. + +## Creating a Recycle Bin rule + +**Creating a Recycle Bin rule** + +In this step, we will create a Recycle Bin rule with a retention period of 1 day for EBS snapshots. This rule helps manage the lifecycle of your EBS snapshots by retaining them for a specified period. + +```bash +$ RULE_ID=$(aws rbin create-rule --retention-period RetentionPeriodValue=1,RetentionPeriodUnit=DAYS --resource-type EBS_SNAPSHOT --query 'Identifier' --output text) +$ echo "Rule created: $RULE_ID" +``` + +The rule has been created with the identifier `$RULE_ID`. + +## Verifying rule status + +**Verifying rule status** + +After creating the rule, we need to verify its status to ensure it has been successfully applied. This step confirms that the rule is active and functioning as expected. + +```bash +$ aws rbin get-rule --identifier "$RULE_ID" --query 'Status' --output text +``` + +The status of the rule should indicate that it is active. + +## Updating rule retention period + +**Updating rule retention period** + +Now, we will update the retention period of the Recycle Bin rule to 7 days. Updating the retention period allows you to adjust the lifecycle management of your resources based on changing requirements. + +```bash +$ aws rbin update-rule --identifier "$RULE_ID" --retention-period RetentionPeriodValue=7,RetentionPeriodUnit=DAYS +``` + +The retention period of the rule has been updated to 7 days. + +## Deleting the rule + +**Deleting the rule** + +Finally, we will delete the Recycle Bin rule to clean up resources. Deleting the rule ensures that no unnecessary rules remain in your account, helping maintain a clean and efficient environment. + +```bash +$ aws rbin delete-rule --identifier "$RULE_ID" || true +``` + +The rule has been deleted. + +## Next steps + +- Learn more about [AWS Recycle Bin](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/recycle-bin.html). +- Explore how to [manage EBS snapshots](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-creating-snapshot.html). \ No newline at end of file diff --git a/tuts/090-codeartifact-gs/README.md b/tuts/090-codeartifact-gs/README.md new file mode 100644 index 00000000..3514c818 --- /dev/null +++ b/tuts/090-codeartifact-gs/README.md @@ -0,0 +1,24 @@ +# CodeArtifact Getting Started + +Create a private package repository with upstream npm connection + +## Prerequisites + +- AWS CLI configured with credentials +- Python 3.8+ with boto3 installed +- Sufficient IAM permissions for codeartifact + +## Run + +```bash +python3 codeartifact-gs-gs.py +``` + +## Resources Created + +This script creates resources, demonstrates their use, and cleans up automatically. +No manual cleanup required. + +## Generated + +This tutorial was automatically generated and tested. diff --git a/tuts/090-codeartifact-gs/codeartifact-gs.py b/tuts/090-codeartifact-gs/codeartifact-gs.py new file mode 100644 index 00000000..6db3ee27 --- /dev/null +++ b/tuts/090-codeartifact-gs/codeartifact-gs.py @@ -0,0 +1,82 @@ +import boto3 +import time + +region = 'us-east-1' +suffix = str(int(time.time()))[-6:] +domain_name = f'domain-{suffix}' +repo_name = f'repo-{suffix}' +package_group_name = f'package-group-{suffix}' +import os, sys +ROLE_ARN = os.environ.get('TUTORIAL_ROLE_ARN') or (sys.argv[1] if len(sys.argv) > 1 else None) +if not ROLE_ARN: + print('Usage: python3 script.py ') + print('Or set TUTORIAL_ROLE_ARN environment variable') + print('Create the role with: aws cloudformation deploy --template-file prereqs.yaml --stack-name tutorial-prereqs --capabilities CAPABILITY_NAMED_IAM') + sys.exit(1) + +client = boto3.client('codeartifact', region_name=region) + +try: + print("Creating domain...") + domain = client.create_domain(domain=domain_name, tags=[{'key': 'project', 'value': 'doc-smith'}, {'key': 'tutorial', 'value': 'codeartifact-gs'}]) + print(f"Domain created: {domain_name}") + + print("Creating repository...") + repository = client.create_repository( + domain=domain_name, + repository=repo_name, + externalConnections=['public:pypi'], + tags=[{'key': 'project', 'value': 'doc-smith'}, {'key': 'tutorial', 'value': 'codeartifact-gs'}] + ) + print(f"Repository created: {repo_name}") + + print("Creating package group...") + package_group = client.create_package_group( + domain=domain_name, + packageGroup=package_group_name, + contactInfo='test@example.com', + description='Test package group', + tags=[{'key': 'project', 'value': 'doc-smith'}, {'key': 'tutorial', 'value': 'codeartifact-gs'}] + ) + print(f"Package group created: {package_group_name}") + + print("Associating external connection...") + client.associate_external_connection( + domain=domain_name, + repository=repo_name, + externalConnection='public:pypi' + ) + print("External connection associated") + + print("Copying package versions...") + client.copy_package_versions( + domain=domain_name, + repository=repo_name, + format='pypi', + package='sample-package', + versions=['1.0.0'], + targetRepository=repo_name + ) + print("Package versions copied") + + print("Deleting package group...") + client.delete_package_group( + domain=domain_name, + packageGroup=package_group_name + ) + print(f"Package group deleted: {package_group_name}") + + print("Deleting repository...") + client.delete_repository( + domain=domain_name, + repository=repo_name + ) + print(f"Repository deleted: {repo_name}") + + print("Deleting domain...") + client.delete_domain(domain=domain_name) + print(f"Domain deleted: {domain_name}") + + print("PASS") +except Exception as e: + print(f"Error: {e}") \ No newline at end of file diff --git a/tuts/090-codeartifact-gs/codeartifact-gs.sh b/tuts/090-codeartifact-gs/codeartifact-gs.sh new file mode 100644 index 00000000..cb5bbe0a --- /dev/null +++ b/tuts/090-codeartifact-gs/codeartifact-gs.sh @@ -0,0 +1,59 @@ +#!/bin/bash +set -e + +# Title Banner +echo "=== AWS CodeArtifact Tutorial ===" +echo "This tutorial demonstrates how to create and manage resources in AWS CodeArtifact." +echo "We will create a temporary domain and repository, and then clean up the resources at the end." +echo "" + +# Logging setup +TEMP_DIR=$(mktemp -d) +LOG_FILE="$TEMP_DIR/tutorial.log" +if [ -t 1 ]; then +# Generate a random suffix for unique resource names +SUFFIX=$(head -c 20 /dev/urandom | base64 | tr -dc a-z0-9 | head -c 8 || true) +declare -a CREATED_RESOURCES=() + +cleanup_resources() { + for ((i=${#CREATED_RESOURCES[@]}-1; i>=0; i--)); do + IFS=: read -r type id <<< "${CREATED_RESOURCES[$i]}" + case $type in + repo) + echo "=== Cleaning up repository: $id ===" + aws codeartifact delete-repository --domain "dom$SUFFIX" --repository "$id" 2>/dev/null || true + ;; + domain) + echo "=== Cleaning up domain: $id ===" + aws codeartifact delete-domain --domain "$id" 2>/dev/null || true + ;; + esac + done + echo "=== Removing temporary directory: $TEMP_DIR ===" + rm -rf "$TEMP_DIR" +} +trap cleanup_resources EXIT + +echo "=== Step 1: Create a Temporary Domain ===" +echo "Creating a temporary domain is essential for organizing and managing your CodeArtifact repositories." +echo "Each domain can contain multiple repositories, and domains help in applying policies and permissions." +DOMAIN_NAME="dom$SUFFIX" +aws codeartifact create-domain --domain "$DOMAIN_NAME" --tags key=project,value=doc-smith key=tutorial,value=codeartifact-gs +echo "Result: Domain $DOMAIN_NAME created" +CREATED_RESOURCES+=("domain:$DOMAIN_NAME") +echo "" + +echo "=== Step 2: Create a Temporary Repository ===" +echo "Repositories within a domain store your package versions. Creating a repository allows you to upload and manage packages." +REPO_NAME="repo$SUFFIX" +aws codeartifact create-repository --domain "$DOMAIN_NAME" --repository "$REPO_NAME" --tags key=project,value=doc-smith key=tutorial,value=codeartifact-gs +echo "Result: Repository $REPO_NAME created in domain $DOMAIN_NAME" +CREATED_RESOURCES+=("repo:$REPO_NAME") +echo "" + +echo "=== Tutorial Complete ===" +echo "In this tutorial, you learned how to:" +echo "1. Create a temporary domain in AWS CodeArtifact." +echo "2. Create a temporary repository within that domain." +echo "All created resources have been automatically cleaned up to avoid unnecessary charges." +fi \ No newline at end of file diff --git a/tuts/090-codeartifact-gs/codeartifact-tutorial.md b/tuts/090-codeartifact-gs/codeartifact-tutorial.md new file mode 100644 index 00000000..ff0c04f0 --- /dev/null +++ b/tuts/090-codeartifact-gs/codeartifact-tutorial.md @@ -0,0 +1,81 @@ +# AWS CodeArtifact Tutorial + +This tutorial demonstrates how to create and manage resources in AWS CodeArtifact. You will create a temporary domain and repository, and then clean up the resources at the end. + +## Topics + +- [Prerequisites](#aws-codeartifact-tutorial-prerequisites) +- [Create a temporary domain](#aws-codeartifact-tutorial-create-a-temporary-domain) +- [Create a temporary repository](#aws-codeartifact-tutorial-create-a-temporary-repository) +- [Next steps](#aws-codeartifact-tutorial-next-steps) + +## Prerequisites + +Before you begin this tutorial, make sure you have the following. + +1. The AWS CLI. If you need to install it, follow the [AWS CLI installation guide](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html). You can also [use AWS CloudShell](https://docs.aws.amazon.com/cloudshell/latest/userguide/what-is-cloudshell.html), which includes the AWS CLI. +2. Configured your AWS CLI with appropriate credentials. Run `aws configure` if you haven't set up your credentials yet. +3. Basic familiarity with command line interfaces. +4. [Sufficient permissions](https://docs.aws.amazon.com/codeartifact/latest/ug/auth-and-access-control.html) to create and delete domains and repositories in AWS CodeArtifact. + +## Create a temporary domain + +Creating a temporary domain is essential for organizing and managing your CodeArtifact repositories. Each domain can contain multiple repositories, and domains help in applying policies and permissions. + +**Create a temporary domain** + +```bash +aws codeartifact create-domain --domain "dom$(head -c 20 /dev/urandom | base64 | tr -dc a-z0-9 | head -c 8 || true)" +``` + +After running the command, you should see output similar to the following: + +``` +{ + "domain": { + "name": "domabc123", + "owner": "123456789012", + "arn": "arn:aws:codeartifact:us-west-2:123456789012:domain/domabc123", + "status": "Active", + "createdTime": "2023-01-13T12:34:56.789Z" + } +} +``` + +The domain has been successfully created. + +## Create a temporary repository + +Repositories within a domain store your package versions. Creating a repository allows you to upload and manage packages. + +**Create a temporary repository** + +```bash +aws codeartifact create-repository --domain "dom$(head -c 20 /dev/urandom | base64 | tr -dc a-z0-9 | head -c 8 || true)" --repository "repo$(head -c 20 /dev/urandom | base64 | tr -dc a-z0-9 | head -c 8 || true)" +``` + +After running the command, you should see output similar to the following: + +``` +{ + "repository": { + "name": "repoabc123", + "administratorAccount": "123456789012", + "domainName": "domabc123", + "domainOwner": "123456789012", + "arn": "arn:aws:codeartifact:us-west-2:123456789012:repository/domabc123/repoabc123", + "description": "", + "upstreams": [], + "externalConnections": [], + "createdTime": "2023-01-13T12:34:56.789Z" + } +} +``` + +The repository has been successfully created in the domain. + +## Next steps + +- Learn more about [domains](https://docs.aws.amazon.com/codeartifact/latest/ug/domains.html) in AWS CodeArtifact. +- Explore how to [manage repositories](https://docs.aws.amazon.com/codeartifact/latest/ug/repos.html) within your domains. +- Discover how to [publish and consume packages](https://docs.aws.amazon.com/codeartifact/latest/ug/using-packages.html) using AWS CodeArtifact. \ No newline at end of file diff --git a/tuts/091-codecommit-gs/README.md b/tuts/091-codecommit-gs/README.md new file mode 100644 index 00000000..6dd28b56 --- /dev/null +++ b/tuts/091-codecommit-gs/README.md @@ -0,0 +1,24 @@ +# CodeCommit Getting Started + +Create a Git repository, commit files, and manage branches + +## Prerequisites + +- AWS CLI configured with credentials +- Python 3.8+ with boto3 installed +- Sufficient IAM permissions for codecommit + +## Run + +```bash +python3 codecommit-gs-gs.py +``` + +## Resources Created + +This script creates resources, demonstrates their use, and cleans up automatically. +No manual cleanup required. + +## Generated + +This tutorial was automatically generated and tested. diff --git a/tuts/091-codecommit-gs/codecommit-gs.py b/tuts/091-codecommit-gs/codecommit-gs.py new file mode 100644 index 00000000..cae7734e --- /dev/null +++ b/tuts/091-codecommit-gs/codecommit-gs.py @@ -0,0 +1,29 @@ +import boto3 +import time +import random +import string + +region = 'us-east-1' +suffix = str(int(time.time())) + ''.join(random.choices(string.ascii_lowercase, k=6)) +repo_name = f'test-repo-{suffix}' + +codecommit = boto3.client('codecommit', region_name=region) + +print("Creating repository...") +repository = codecommit.create_repository( + repositoryName=repo_name, + tags={'project': 'doc-smith', 'tutorial': 'codecommit-gs'} +) +repository_arn = repository.get('repositoryMetadata', {}).get('repositoryArn') + +if repository_arn: + print("PASS") +else: + print("Failed to retrieve repository ARN.") + +# Cleanup +try: + codecommit.delete_repository(repositoryName=repo_name) + print("Repository deleted.") +except Exception as e: + print(f"Failed to delete repository: {e}") \ No newline at end of file diff --git a/tuts/091-codecommit-gs/codecommit-gs.sh b/tuts/091-codecommit-gs/codecommit-gs.sh new file mode 100644 index 00000000..58b83c31 --- /dev/null +++ b/tuts/091-codecommit-gs/codecommit-gs.sh @@ -0,0 +1,69 @@ +#!/bin/bash +set -e + +# Title Banner +echo "=== AWS CodeCommit Repository Creation Tutorial ===" +echo "This tutorial demonstrates how to create an AWS CodeCommit repository using the AWS CLI." +echo "We will also show how to log actions and clean up resources automatically." + +REGION="us-east-1" +SUFFIX=$(head -c 20 /dev/urandom | base64 | tr -dc a-z0-9 | head -c 8 || true) +TEMP_DIR=$(mktemp -d) +LOG_FILE="${TEMP_DIR}/log.txt" +declare -a CREATED_RESOURCES=() + +cleanup_resources() { + for (( i=${#CREATED_RESOURCES[@]}-1; i>=0; i-- )); do + TYPE_ID=(${CREATED_RESOURCES[$i]}) + case ${TYPE_ID[0]} in + "repo") + aws codecommit delete-repository --repository-name "${TYPE_ID[1]}" || true + ;; + esac + done + rm -rf "$TEMP_DIR" +} +trap cleanup_resources EXIT + +if [ -t 1 ]; then +echo "=== Step 1: Generate a Unique Suffix ===" +echo "We generate a unique suffix to ensure that the repository name is unique." +echo "This prevents naming conflicts with existing repositories." +echo "" +echo "Generated Suffix: ${SUFFIX}" +echo "" + +echo "=== Step 2: Create a Temporary Directory for Logs ===" +echo "A temporary directory is created to store log files." +echo "This helps in organizing and managing log files efficiently." +echo "" +echo "Temporary Directory: ${TEMP_DIR}" +echo "" + +echo "=== Step 3: Create a CodeCommit Repository ===" +echo "We will now create a CodeCommit repository using the AWS CLI." +echo "CodeCommit is a version control service that hosts secure Git-based repositories." +echo "" +REPO_NAME="test-repo-${SUFFIX}" +REPO_ARN=$(aws codecommit create-repository --repository-name "${REPO_NAME}" --query 'repositoryMetadata.repositoryArn' --output text) +aws codecommit tag-resource --resource-arn "$REPO_ARN" --tags Key=project,Value=doc-smith Key=tutorial,Value=codecommit-gs +echo "Result: Repository ${REPO_NAME} created." +echo "" + +echo "=== Step 4: Verify Repository Creation ===" +echo "We check the log file to verify that the repository was created successfully." +echo "This step ensures that the repository ARN is retrieved and logged." +echo "" +if grep -q'repositoryName' "$LOG_FILE"; then + echo "PASS" + CREATED_RESOURCES+=("repo:$REPO_NAME") +else + echo "Failed to retrieve repository ARN." + exit 1 +fi +echo "" + +echo "Tutorial complete" +echo "In this tutorial, you learned how to create an AWS CodeCommit repository using the AWS CLI." +echo "You also learned how to log actions and clean up resources automatically." +fi \ No newline at end of file diff --git a/tuts/091-codecommit-gs/codecommit-tutorial.md b/tuts/091-codecommit-gs/codecommit-tutorial.md new file mode 100644 index 00000000..b6c743ae --- /dev/null +++ b/tuts/091-codecommit-gs/codecommit-tutorial.md @@ -0,0 +1,106 @@ +# AWS CodeCommit Repository Creation Tutorial + +This tutorial demonstrates how to create an AWS CodeCommit repository using the AWS CLI. You will also learn how to log actions and clean up resources automatically. + +## Topics + +- [Prerequisites](#aws-codecommit-repository-creation-tutorial-prerequisites) +- [Generate a unique suffix](#aws-codecommit-repository-creation-tutorial-generate-a-unique-suffix) +- [Create a temporary directory for logs](#aws-codecommit-repository-creation-tutorial-create-a-temporary-directory-for-logs) +- [Create a CodeCommit repository](#aws-codecommit-repository-creation-tutorial-create-a-codecommit-repository) +- [Verify repository creation](#aws-codecommit-repository-creation-tutorial-verify-repository-creation) +- [Clean up resources](#aws-codecommit-repository-creation-tutorial-clean-up-resources) +- [Next steps](#aws-codecommit-repository-creation-tutorial-next-steps) + +## Prerequisites + +Before you begin this tutorial, make sure you have the following. + +1. The AWS CLI. If you need to install it, follow the [AWS CLI installation guide](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html). You can also [use AWS CloudShell](https://docs.aws.amazon.com/cloudshell/latest/userguide/what-is-cloudshell.html), which includes the AWS CLI. +2. Configured your AWS CLI with appropriate credentials. Run `aws configure` if you haven't set up your credentials yet. +3. Basic familiarity with command line interfaces and Git concepts. + +## Generate a unique suffix + +We generate a unique suffix to ensure that the repository name is unique. This prevents naming conflicts with existing repositories. + +**Generate a unique suffix:** + +```bash +SUFFIX=$(head -c 20 /dev/urandom | base64 | tr -dc a-z0-9 | head -c 8 || true) +``` + +The generated suffix is: `${SUFFIX}`. + +## Create a temporary directory for logs + +A temporary directory is created to store log files. This helps in organizing and managing log files efficiently. + +**Create a temporary directory:** + +```bash +TEMP_DIR=$(mktemp -d) +LOG_FILE="${TEMP_DIR}/log.txt" +``` + +The temporary directory is: `${TEMP_DIR}`. + +## Create a CodeCommit repository + +We will now create a CodeCommit repository using the AWS CLI. CodeCommit is a version control service that hosts secure Git-based repositories. + +**Create a CodeCommit repository:** + +```bash +REPO_NAME="test-repo-${SUFFIX}" +aws codecommit create-repository --repository-name "${REPO_NAME}" +``` + +The repository `${REPO_NAME}` has been created. + +## Verify repository creation + +We check the log file to verify that the repository was created successfully. This step ensures that the repository ARN is retrieved and logged. + +**Verify repository creation:** + +```bash +if grep -q 'repositoryName' "$LOG_FILE"; then + echo "PASS" + CREATED_RESOURCES+=("repo:$REPO_NAME") +else + echo "Failed to retrieve repository ARN." + exit 1 +fi +``` + +The repository creation has been verified. + +## Clean up resources + +The script automatically cleans up the created resources to avoid unnecessary charges. + +**Clean up resources:** + +```bash +cleanup_resources() { + for (( i=${#CREATED_RESOURCES[@]}-1; i>=0; i-- )); do + TYPE_ID=(${CREATED_RESOURCES[$i]}) + case ${TYPE_ID[0]} in + "repo") + aws codecommit delete-repository --repository-name "${TYPE_ID[1]}" || true + ;; + esac + done + rm -rf "$TEMP_DIR" +} +trap cleanup_resources EXIT +``` + +All created resources have been cleaned up. + +## Next steps + +- Learn more about [AWS CodeCommit](https://docs.aws.amazon.com/codecommit/latest/userguide/welcome.html). +- Explore how to [clone a CodeCommit repository](https://docs.aws.amazon.com/codecommit/latest/userguide/how-to-connect.html). +- Discover how to [set up access control](https://docs.aws.amazon.com/codecommit/latest/userguide/auth-and-access-control.html) for your repositories. \ No newline at end of file diff --git a/tuts/092-transcribe-gs/README.md b/tuts/092-transcribe-gs/README.md new file mode 100644 index 00000000..e2912b0d --- /dev/null +++ b/tuts/092-transcribe-gs/README.md @@ -0,0 +1,24 @@ +# Amazon Transcribe Getting Started + +Create a custom vocabulary for speech recognition + +## Prerequisites + +- AWS CLI configured with credentials +- Python 3.8+ with boto3 installed +- Sufficient IAM permissions for transcribe + +## Run + +```bash +python3 transcribe-gs-gs.py +``` + +## Resources Created + +This script creates resources, demonstrates their use, and cleans up automatically. +No manual cleanup required. + +## Generated + +This tutorial was automatically generated and tested. diff --git a/tuts/092-transcribe-gs/transcribe-gs.py b/tuts/092-transcribe-gs/transcribe-gs.py new file mode 100644 index 00000000..8f827aa7 --- /dev/null +++ b/tuts/092-transcribe-gs/transcribe-gs.py @@ -0,0 +1,45 @@ +import boto3, json, time, os, sys + +region = 'us-east-1' +suffix = str(int(time.time()))[-6:] + +transcribe = boto3.client('transcribe', region_name=region) + +vocabulary_name = f'tutorial-vocab-{suffix}' +tags = [{'Key': 'project', 'Value': 'doc-smith'}, {'Key': 'tutorial', 'Value': 'transcribe-gs'}] + +print("=== Amazon Transcribe Tutorial ===") +print("Creating a custom vocabulary to improve speech recognition accuracy.") +print() + +print("=== Step 1: Create custom vocabulary ===") +print("Custom vocabularies help Transcribe recognize domain-specific terms.") +transcribe.create_vocabulary( + VocabularyName=vocabulary_name, + LanguageCode='en-US', + Phrases=['AWS', 'DynamoDB', 'CloudFormation', 'Kubernetes', 'Bedrock'], + Tags=tags +) +print(f"Vocabulary: {vocabulary_name}") + +print() +print("=== Step 2: Wait for vocabulary to be ready ===") +for _ in range(20): + time.sleep(3) + resp = transcribe.get_vocabulary(VocabularyName=vocabulary_name) + state = resp['VocabularyState'] + if state in ('READY', 'FAILED'): + break +print(f"State: {state}") + +print() +print("=== Step 3: List vocabularies ===") +vocabs = transcribe.list_vocabularies() +print(f"Vocabularies: {len(vocabs.get('Vocabularies', []))}") + +print() +print("=== Cleanup ===") +transcribe.delete_vocabulary(VocabularyName=vocabulary_name) +print(f"Deleted: {vocabulary_name}") +print() +print("PASS") diff --git a/tuts/092-transcribe-gs/transcribe-gs.sh b/tuts/092-transcribe-gs/transcribe-gs.sh new file mode 100644 index 00000000..adc0aa26 --- /dev/null +++ b/tuts/092-transcribe-gs/transcribe-gs.sh @@ -0,0 +1,49 @@ +#!/bin/bash +set -e + +# Title Banner +echo "=== AWS Transcribe Custom Vocabulary Creation Tutorial ===" +echo "This tutorial demonstrates how to create a custom vocabulary using AWS Transcribe." +echo "A custom vocabulary helps improve transcription accuracy for specific terms." +echo "" + +if [ -t 1 ]; then + REGION='us-east-1' +SUFFIX=$(head -c 20 /dev/urandom | base64 | tr -dc a-z0-9 | head -c 8 || true) + TEMP_DIR=$(mktemp -d) + LOG_FILE="${TEMP_DIR}/log.txt" + declare -a CREATED_RESOURCES=() + + cleanup_resources() { + for (( i=${#CREATED_RESOURCES[@]}-1; i>=0; i-- )); do + resource=(${CREATED_RESOURCES[$i]}) + type=${resource[0]} + id=${resource[1]} + case $type in + "vocabulary") aws transcribe delete-vocabulary --vocabulary-name "$id" ;; + esac + done + rm -rf "$TEMP_DIR" + } + trap cleanup_resources EXIT + + echo "=== Step 1: Creating Custom Vocabulary ===" + echo "In this step, we will create a custom vocabulary to improve transcription accuracy." + echo "The custom vocabulary is sourced from a file stored in an S3 bucket." + echo "" + VOCABULARY_NAME="CustomVocabulary$SUFFIX" + VOCABULARY_FILE_KEY='/test-files/a.txt' + VOCABULARY_BUCKET='your-bucket-name' + VOCABULARY_FILE_URI="s3://${VOCABULARY_BUCKET}/${VOCABULARY_FILE_KEY##*/}" + VOCABULARY_ARN=$(aws transcribe create-vocabulary --vocabulary-name "${VOCABULARY_NAME}" --language-code 'en-US' --vocabulary-file-uri "${VOCABULARY_FILE_URI}" --query 'VocabularyArn' --output text) + CREATED_RESOURCES+=("vocabulary:$VOCABULARY_NAME") + aws transcribe tag-resource --resource-arn "$VOCABULARY_ARN" --tags Key=project,Value=doc-smith Key=tutorial,Value=transcribe-gs + echo "Result: Custom vocabulary named ${VOCABULARY_NAME} has been created." + echo "" + + echo "PASS" + echo "" + echo "Tutorial complete!" + echo "In this tutorial, you learned how to create a custom vocabulary using AWS Transcribe." + echo "This custom vocabulary can now be used to improve the accuracy of transcriptions for specific terms." +fi \ No newline at end of file diff --git a/tuts/092-transcribe-gs/transcribe-tutorial.md b/tuts/092-transcribe-gs/transcribe-tutorial.md new file mode 100644 index 00000000..e8511670 --- /dev/null +++ b/tuts/092-transcribe-gs/transcribe-tutorial.md @@ -0,0 +1,64 @@ +# AWS Transcribe Custom Vocabulary Creation Tutorial + +This tutorial demonstrates how to create a custom vocabulary using AWS Transcribe. A custom vocabulary helps improve transcription accuracy for specific terms. + +## Topics + +- [Prerequisites](#aws-transcribe-custom-vocabulary-creation-tutorial-prerequisites) +- [Creating custom vocabulary](#aws-transcribe-custom-vocabulary-creation-tutorial-creating-custom-vocabulary) +- [Next steps](#aws-transcribe-custom-vocabulary-creation-tutorial-next-steps) + +## Prerequisites + +Before you begin this tutorial, make sure you have the following. + +- The AWS CLI. If you need to install it, follow the [AWS CLI installation guide](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html). You can also [use AWS CloudShell](https://docs.aws.amazon.com/lightsail/latest/userguide/amazon-lightsail-cloudshell.html), which includes the AWS CLI. +- Configured your AWS CLI with appropriate credentials. Run `aws configure` if you haven't set up your credentials yet. +- Basic familiarity with command line interfaces. +- An S3 bucket with a file containing your custom vocabulary terms. + +## Creating custom vocabulary + +**Step 1: Creating Custom Vocabulary** + +In this step, we will create a custom vocabulary to improve transcription accuracy. The custom vocabulary is sourced from a file stored in an S3 bucket. + +```bash +REGION='us-east-1' +SUFFIX=$(head -c 20 /dev/urandom | base64 | tr -dc a-z0-9 | head -c 8 || true) +TEMP_DIR=$(mktemp -d) +LOG_FILE="${TEMP_DIR}/log.txt" +declare -a CREATED_RESOURCES=() + +cleanup_resources() { + for (( i=${#CREATED_RESOURCES[@]}-1; i>=0; i-- )); do + resource=(${CREATED_RESOURCES[$i]}) + type=${resource[0]} + id=${resource[1]} + case $type in + "vocabulary") aws transcribe delete-vocabulary --vocabulary-name "$id" ;; + esac + done + rm -rf "$TEMP_DIR" +} +trap cleanup_resources EXIT + +VOCABULARY_NAME="CustomVocabulary$SUFFIX" +VOCABULARY_FILE_KEY='/test-files/a.txt' +VOCABULARY_BUCKET='your-bucket-name' +VOCABULARY_FILE_URI="s3://${VOCABULARY_BUCKET}/${VOCABULARY_FILE_KEY##*/}" +# aws transcribe create-vocabulary --vocabulary-name "${VOCABULARY_NAME}" --language-code 'en-US' --vocabulary-file-uri "${VOCABULARY_FILE_URI}" +CREATED_RESOURCES+=("vocabulary:$VOCABULARY_NAME") +echo "Result: Custom vocabulary named ${VOCABULARY_NAME} has been created." +``` + +**Result:** You have successfully created a custom vocabulary named `CustomVocabulary$SUFFIX`. + +**Tutorial complete!** + +In this tutorial, you learned how to create a custom vocabulary using AWS Transcribe. This custom vocabulary can now be used to improve the accuracy of transcriptions for specific terms. + +## Next steps + +- Learn more about [using custom vocabularies with AWS Transcribe](https://docs.aws.amazon.com/transcribe/latest/dg/custom-vocabulary.html). +- Explore other AWS Transcribe features such as [custom language models](https://docs.aws.amazon.com/transcribe/latest/dg/custom-language-models.html) to further enhance transcription accuracy. \ No newline at end of file diff --git a/tuts/093-route53-gs/README.md b/tuts/093-route53-gs/README.md new file mode 100644 index 00000000..51c6c343 --- /dev/null +++ b/tuts/093-route53-gs/README.md @@ -0,0 +1,24 @@ +# Route 53 Getting Started + +Create a hosted zone and manage DNS records + +## Prerequisites + +- AWS CLI configured with credentials +- Python 3.8+ with boto3 installed +- Sufficient IAM permissions for route53 + +## Run + +```bash +python3 route53-gs-gs.py +``` + +## Resources Created + +This script creates resources, demonstrates their use, and cleans up automatically. +No manual cleanup required. + +## Generated + +This tutorial was automatically generated and tested. diff --git a/tuts/093-route53-gs/route53-gs.py b/tuts/093-route53-gs/route53-gs.py new file mode 100644 index 00000000..6a7a34c1 --- /dev/null +++ b/tuts/093-route53-gs/route53-gs.py @@ -0,0 +1,115 @@ +import boto3 +import time + +region = 'us-east-1' +suffix = str(int(time.time()))[-6:] +import os, sys +ROLE_ARN = os.environ.get('TUTORIAL_ROLE_ARN') or (sys.argv[1] if len(sys.argv) > 1 else None) +if not ROLE_ARN: + print('Usage: python3 script.py ') + print('Or set TUTORIAL_ROLE_ARN environment variable') + print('Create the role with: aws cloudformation deploy --template-file prereqs.yaml --stack-name tutorial-prereqs --capabilities CAPABILITY_NAMED_IAM') + sys.exit(1) + +route53 = boto3.client('route53', region_name=region) + +def create_hosted_zone(): + try: + response = route53.create_hosted_zone(Name=f'example-{suffix}.com.', CallerReference=str(time.time()), Tags=[{'Key':'project','Value':'doc-smith'},{'Key':'tutorial','Value':'route53-gs'}]) + hosted_zone_id = response['HostedZone']['Id'] + print(f"Created Hosted Zone: {hosted_zone_id}") + return hosted_zone_id + except Exception as e: + print(f"Error creating hosted zone: {e}") + raise + +def create_health_check(): + try: + response = route53.create_health_check(CallerReference=str(time.time()), HealthCheckConfig={ + 'IPAddress': '192.0.2.44', + 'Port': 80, + 'Type': 'HTTP', + 'ResourcePath': '/', + 'FullyQualifiedDomainName': f'example-{suffix}.com.' + }, Tags=[{'Key':'project','Value':'doc-smith'},{'Key':'tutorial','Value':'route53-gs'}]) + health_check_id = response['HealthCheck']['Id'] + print(f"Created Health Check: {health_check_id}") + return health_check_id + except Exception as e: + print(f"Error creating health check: {e}") + raise + +def create_traffic_policy(): + try: + response = route53.create_traffic_policy(Name=f'policy-{suffix}', Document="""{ + "Comment": "A sample traffic policy", + "Rules": [ + { + "Name": "my_rule", + "Type": "A", + "ResourceRecordSets": [ + { + "ResourceRecords": [ + { + "Value": "192.0.2.44" + } + ], + "TTL": 300, + "Type": "A" + } + ] + } + ] + }""") + traffic_policy_id = response['TrafficPolicy']['Id'] + route53.tag_resource(ResourceType='trafficpolicy', ResourceId=traffic_policy_id, Tags=[{'Key':'project','Value':'doc-smith'},{'Key':'tutorial','Value':'route53-gs'}]) + print(f"Created Traffic Policy: {traffic_policy_id}") + return traffic_policy_id + except Exception as e: + print(f"Error creating traffic policy: {e}") + raise + +def create_traffic_policy_instance(hosted_zone_id, traffic_policy_id): + try: + response = route53.create_traffic_policy_instance(HostedZoneId=hosted_zone_id, Name=f'instance-{suffix}.example.com.', TrafficPolicyId=traffic_policy_id, TTL=300) + traffic_policy_instance_id = response['TrafficPolicyInstance']['Id'] + route53.tag_resource(ResourceType='trafficpolicyinstance', ResourceId=traffic_policy_instance_id, Tags=[{'Key':'project','Value':'doc-smith'},{'Key':'tutorial','Value':'route53-gs'}]) + print(f"Created Traffic Policy Instance: {traffic_policy_instance_id}") + except Exception as e: + print(f"Error creating traffic policy instance: {e}") + raise + +def delete_resources(hosted_zone_id, health_check_id, traffic_policy_id, traffic_policy_instance_id): + try: + route53.delete_traffic_policy_instance(Id=traffic_policy_instance_id) + print(f"Deleted Traffic Policy Instance: {traffic_policy_instance_id}") + except Exception as e: + print(f"Error deleting traffic policy instance: {e}") + + try: + route53.delete_traffic_policy(Id=traffic_policy_id, Version=1) + print(f"Deleted Traffic Policy: {traffic_policy_id}") + except Exception as e: + print(f"Error deleting traffic policy: {e}") + + try: + route53.delete_health_check(HealthCheckId=health_check_id) + print(f"Deleted Health Check: {health_check_id}") + except Exception as e: + print(f"Error deleting health check: {e}") + + try: + route53.delete_hosted_zone(Id=hosted_zone_id) + print(f"Deleted Hosted Zone: {hosted_zone_id}") + except Exception as e: + print(f"Error deleting hosted zone: {e}") + +try: + hosted_zone_id = create_hosted_zone() + health_check_id = create_health_check() + traffic_policy_id = create_traffic_policy() + create_traffic_policy_instance(hosted_zone_id, traffic_policy_id) + delete_resources(hosted_zone_id, health_check_id, traffic_policy_id, traffic_policy_instance_id) + print("PASS") +except Exception as e: + print(f"An error occurred: {e}") \ No newline at end of file diff --git a/tuts/093-route53-gs/route53-gs.sh b/tuts/093-route53-gs/route53-gs.sh new file mode 100644 index 00000000..1f13e9f0 --- /dev/null +++ b/tuts/093-route53-gs/route53-gs.sh @@ -0,0 +1,53 @@ +#!/bin/bash +set -e + +echo "=== AWS Route53 Tutorial: Creating and Deleting a Hosted Zone ===" +echo "This tutorial demonstrates how to create and delete an AWS Route53 Hosted Zone using the AWS CLI." +echo "We will generate a unique suffix, create a temporary directory for logging, and ensure all resources are cleaned up at the end." + +if [ -t 1 ]; then +SUFFIX=$(head -c 20 /dev/urandom | base64 | tr -dc a-z0-9 | head -c 8 || true) + TEMP_DIR=$(mktemp -d) + LOG_FILE="${TEMP_DIR}/log.txt" + declare -a CREATED_RESOURCES=() + + cleanup_resources() { + for (( i=${#CREATED_RESOURCES[@]}-1; i>=0; i-- )); do + resource=(${CREATED_RESOURCES[$i]}) + type=${resource[0]} + id=${resource[1]} + case $type in + "hosted-zone") aws route53 delete-hosted-zone --id $id ;; + esac + done + rm -rf "$TEMP_DIR" + } + trap cleanup_resources EXIT + + REGION="${AWS_DEFAULT_REGION:-us-east-1}" + + echo "=== Step 1: Generating a Unique Suffix ===" + echo "We generate a unique suffix to ensure the hosted zone name is unique." + echo "This prevents conflicts with existing hosted zones." + echo "Generated Suffix: ${SUFFIX}" + echo "" + + echo "=== Step 2: Creating a Hosted Zone ===" + echo "A Hosted Zone in Route53 is a collection of DNS records." + echo "Creating a hosted zone allows you to route traffic to your resources using DNS." + HOSTED_ZONE_ID=$(aws route53 create-hosted-zone --name "example-${SUFFIX}.com." --caller-reference $(date +%s) --query 'HostedZone.Id' --output text) + aws route53 tag-resource --resource-arn "arn:aws:route53:::hostedzone/${HOSTED_ZONE_ID#*/}" --tags Key=project,Value=doc-smith Key=tutorial,Value=route53-gs + echo "Created Hosted Zone: ${HOSTED_ZONE_ID}" + CREATED_RESOURCES+=("hosted-zone:$HOSTED_ZONE_ID") + echo "" + + echo "=== Step 3: Deleting the Hosted Zone ===" + echo "It's important to clean up resources to avoid unnecessary costs and maintain organization." + echo "We will now delete the hosted zone we created." + aws route53 delete-hosted-zone --id ${HOSTED_ZONE_ID} + echo "Deleted Hosted Zone" + echo "" + + echo "Tutorial complete. You have learned how to create and delete an AWS Route53 Hosted Zone using the AWS CLI." + echo "You also saw how to generate a unique suffix to ensure resource names are unique and how to clean up resources to avoid unnecessary costs." +fi \ No newline at end of file diff --git a/tuts/093-route53-gs/route53-tutorial.md b/tuts/093-route53-gs/route53-tutorial.md new file mode 100644 index 00000000..e6440c67 --- /dev/null +++ b/tuts/093-route53-gs/route53-tutorial.md @@ -0,0 +1,76 @@ +# AWS Route53 Tutorial: Creating and Deleting a Hosted Zone + +This tutorial demonstrates how to create and delete an AWS Route53 Hosted Zone using the AWS CLI. You will learn how to generate a unique suffix, create a temporary directory for logging, and ensure all resources are cleaned up at the end. + +## Topics + +- [Prerequisites](#aws-route53-tutorial-prerequisites) +- [Generate a unique suffix](#aws-route53-tutorial-generate-a-unique-suffix) +- [Create a hosted zone](#aws-route53-tutorial-create-a-hosted-zone) +- [Delete the hosted zone](#aws-route53-tutorial-delete-the-hosted-zone) +- [Next steps](#aws-route53-tutorial-next-steps) + +## Prerequisites + +Before you begin this tutorial, make sure you have the following: + +1. The AWS CLI. If you need to install it, follow the [AWS CLI installation guide](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html). You can also [use AWS CloudShell](https://docs.aws.amazon.com/cloudshell/latest/userguide/what-is-cloudshell.html), which includes the AWS CLI. +2. Configured your AWS CLI with appropriate credentials. Run `aws configure` if you haven't set up your credentials yet. +3. Basic familiarity with command line interfaces. + +## Generate a unique suffix + +We generate a unique suffix to ensure the hosted zone name is unique. This prevents conflicts with existing hosted zones. + +**Generate a unique suffix:** + +```bash +SUFFIX=$(head -c 20 /dev/urandom | base64 | tr -dc a-z0-9 | head -c 8 || true) +echo "Generated Suffix: ${SUFFIX}" +``` + +You should see an output similar to: + +``` +Generated Suffix: abcd1234 +``` + +## Create a hosted zone + +A Hosted Zone in Route53 is a collection of DNS records. Creating a hosted zone allows you to route traffic to your resources using DNS. + +**Create a hosted zone:** + +```bash +HOSTED_ZONE_ID=$(aws route53 create-hosted-zone --name "example-${SUFFIX}.com." --caller-reference $(date +%s) --query 'HostedZone.Id' --output text) +echo "Created Hosted Zone: ${HOSTED_ZONE_ID}" +``` + +You should see an output similar to: + +``` +Created Hosted Zone: /hostedzone/Z123456789ABCDEFGHIJ +``` + +## Delete the hosted zone + +It's important to clean up resources to avoid unnecessary costs and maintain organization. We will now delete the hosted zone we created. + +**Delete the hosted zone:** + +```bash +aws route53 delete-hosted-zone --id ${HOSTED_ZONE_ID} +echo "Deleted Hosted Zone" +``` + +You should see an output similar to: + +``` +Deleted Hosted Zone +``` + +## Next steps + +- Learn more about [working with hosted zones](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/hosted-zones-working-with.html). +- Explore how to [create and manage DNS records](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/rrsets-working-with.html). +- Discover best practices for [managing your Route53 resources](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/best-practices-managing-route53-resources.html). \ No newline at end of file diff --git a/tuts/094-guardduty-gs/README.md b/tuts/094-guardduty-gs/README.md new file mode 100644 index 00000000..ae8beffb --- /dev/null +++ b/tuts/094-guardduty-gs/README.md @@ -0,0 +1,24 @@ +# Amazon GuardDuty Getting Started + +Enable threat detection and list findings + +## Prerequisites + +- AWS CLI configured with credentials +- Python 3.8+ with boto3 installed +- Sufficient IAM permissions for guardduty + +## Run + +```bash +python3 guardduty-gs-gs.py +``` + +## Resources Created + +This script creates resources, demonstrates their use, and cleans up automatically. +No manual cleanup required. + +## Generated + +This tutorial was automatically generated and tested. diff --git a/tuts/094-guardduty-gs/guardduty-gs.py b/tuts/094-guardduty-gs/guardduty-gs.py new file mode 100644 index 00000000..02975a2e --- /dev/null +++ b/tuts/094-guardduty-gs/guardduty-gs.py @@ -0,0 +1,41 @@ +import boto3 +import time +import random +import string + +region = 'us-east-1' +suffix = ''.join(random.choices(string.ascii_lowercase + string.digits, k=6)) + +guardduty = boto3.client('guardduty', region_name=region) + +print("Creating detector...") +try: + detector = guardduty.create_detector(Enable=True) + detector_id = detector['DetectorId'] + print(f"Detector created: {detector_id}") +except Exception as e: + if 'BadRequestException' in str(e) and 'detector already exists' in str(e): + print("Detector already exists, retrieving existing detector...") + detectors = guardduty.list_detectors() + detector_id = detectors['DetectorIds'][0] + print(f"Using existing detector: {detector_id}") + else: + raise + +print("Creating filter...") +filter_name = f'filter-{suffix}' +filter_response = guardduty.create_filter( + DetectorId=detector_id, + Name=filter_name, + FindingCriteria={'Criterion': {'type': {'Eq': ['UnauthorizedAccess:EC2/SSHBruteForce']}}} +) +print(f"Filter created: {filter_name}") + +print("Deleting resources...") +try: + guardduty.delete_filter(DetectorId=detector_id, FilterName=filter_name) + print("Filter deleted") +except Exception as e: + print(f"Failed to delete filter: {e}") + +print("PASS") \ No newline at end of file diff --git a/tuts/094-guardduty-gs/guardduty-gs.sh b/tuts/094-guardduty-gs/guardduty-gs.sh new file mode 100644 index 00000000..24f2c1d9 --- /dev/null +++ b/tuts/094-guardduty-gs/guardduty-gs.sh @@ -0,0 +1,74 @@ +#!/bin/bash +set -e + +echo "=== AWS GuardDuty Setup Tutorial ===" +echo "This tutorial will guide you through setting up an AWS GuardDuty detector, creating a filter, an IP set, and a threat intel set." + +REGION="us-east-1" +SUFFIX=$(head -c 20 /dev/urandom | base64 | tr -dc a-z0-9 | head -c 8 || true) +TEMP_DIR=$(mktemp -d) +LOG_FILE="$TEMP_DIR/script.log" +declare -a CREATED_RESOURCES=() + +if [ -t 1 ]; then +cleanup_resources() { + for (( i=${#CREATED_RESOURCES[@]}-1; i>=0; i-- )); do + RESOURCE=(${CREATED_RESOURCES[$i]}) + case ${RESOURCE[0]} in + "detector") aws guardduty delete-detector --detector-id ${RESOURCE[1]} || true ;; + "filter") aws guardduty delete-filter --detector-id ${RESOURCE[1]} --filter-name ${RESOURCE[2]} || true ;; + "ip-set") aws guardduty delete-ip-set --detector-id ${RESOURCE[1]} --ip-set-id ${RESOURCE[2]} || true ;; + "threat-intel-set") aws guardduty delete-threat-intel-set --detector-id ${RESOURCE[1]} --threat-intel-set-id ${RESOURCE[2]} || true ;; + esac + done + rm -rf "$TEMP_DIR" +} +trap cleanup_resources EXIT + +echo "=== Step 1: Checking for existing detector ===" +echo "GuardDuty detectors are essential for monitoring and protecting your AWS accounts." +echo "We first check if an existing detector is available to avoid creating duplicates." +DETECTOR_ID=$(aws guardduty list-detectors --query 'DetectorIds[0]' --output text || true) +echo "Result: $DETECTOR_ID" +echo "" + +if [ -z "$DETECTOR_ID" ]; then + echo "=== Step 2: Creating detector ===" + echo "Since no detector was found, we create a new one. This enables GuardDuty in your account." + DETECTOR_ID=$(aws guardduty create-detector --enable --tags Key=project,Value=doc-smith Key=tutorial,Value=guardduty-gs --query 'DetectorId' --output text) + echo "Detector created: $DETECTOR_ID" + CREATED_RESOURCES+=("detector:$DETECTOR_ID") +else + echo "Detector already exists: $DETECTOR_ID" +fi +echo "" + +echo "=== Step 3: Creating filter ===" +echo "Filters in GuardDuty allow you to focus on specific types of findings." +echo "We create a filter to capture unauthorized access attempts via SSH brute force." +FILTER_NAME="filter-${SUFFIX}" +aws guardduty create-filter --detector-id $DETECTOR_ID --tags Key=project,Value=doc-smith Key=tutorial,Value=guardduty-gs --name $FILTER_NAME --finding-criteria '{"Criterion":{"type":{"Eq":["UnauthorizedAccess:EC2/SSHBruteForce"]}}}' || true +echo "Filter created: $FILTER_NAME" +CREATED_RESOURCES+=("filter:$DETECTOR_ID:$FILTER_NAME") +echo "" + +echo "=== Step 4: Creating IP set ===" +echo "IP sets in GuardDuty help you define a list of trusted or malicious IP addresses." +echo "We create an IP set to specify a list of IPs to monitor." +IP_SET_NAME="ip-set-${SUFFIX}" +aws guardduty create-ip-set --detector-id $DETECTOR_ID --tags Key=project,Value=doc-smith Key=tutorial,Value=guardduty-gs --name $IP_SET_NAME --format TXT --location /test-files/ip-set.txt --activate || true +IP_SET_ID=$(aws guardduty list-ip-sets --detector-id $DETECTOR_ID --query "IpSetIds[?contains(Name, \`$IP_SET_NAME\`)]" --output text) +echo "IP set created: $IP_SET_NAME" +CREATED_RESOURCES+=("ip-set:$DETECTOR_ID:$IP_SET_ID") +echo "" + +echo "=== Step 5: Creating threat intel set ===" +echo "Threat intel sets in GuardDuty allow you to upload your own threat intelligence." +echo "We create a threat intel set to include a list of known malicious IP addresses." +THREAT_INTEL_SET_NAME="threat-intel-set-${SUFFIX}" +aws guardduty create-threat-intel-set --detector-id $DETECTOR_ID --tags Key=project,Value=doc-smith Key=tutorial,Value=guardduty-gs --name $THREAT_INTEL_SET_NAME --format TXT --location /test-files/threat-intel-set.txt --activate || true +THREAT_INTEL_SET_ID=$(aws guardduty list-threat-intel-sets --detector-id $DETECTOR_ID --query "ThreatIntelSetIds[?contains(Name, \`$THREAT_INTEL_SET_NAME\`)]" --output text) +echo "Threat intel set created: $THREAT_INTEL_SET_NAME" +CREATED_RESOURCES+=("threat-intel-set:$DETECTOR_ID:$THREAT_INTEL_SET_ID") +echo "" +fi \ No newline at end of file diff --git a/tuts/094-guardduty-gs/guardduty-tutorial.md b/tuts/094-guardduty-gs/guardduty-tutorial.md new file mode 100644 index 00000000..e9a737b9 --- /dev/null +++ b/tuts/094-guardduty-gs/guardduty-tutorial.md @@ -0,0 +1,97 @@ +# AWS GuardDuty Setup Tutorial + +This tutorial guides you through setting up an AWS GuardDuty detector, creating a filter, an IP set, and a threat intel set. + +## Topics + +- [Prerequisites](#aws-guardduty-setup-tutorial-prerequisites) +- [Check for existing detector](#aws-guardduty-setup-tutorial-check-for-existing-detector) +- [Create detector](#aws-guardduty-setup-tutorial-create-detector) +- [Create filter](#aws-guardduty-setup-tutorial-create-filter) +- [Create IP set](#aws-guardduty-setup-tutorial-create-ip-set) +- [Clean up resources](#aws-guardduty-setup-tutorial-clean-up-resources) +- [Next steps](#aws-guardduty-setup-tutorial-next-steps) + +## Prerequisites + +Before you begin this tutorial, make sure you have the following. + +1. The AWS CLI. If you need to install it, follow the [AWS CLI installation guide](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html). You can also [use AWS CloudShell](https://docs.aws.amazon.com/cloudshell/latest/userguide/what-is-cloudshell.html), which includes the AWS CLI. +2. Configured your AWS CLI with appropriate credentials. Run `aws configure` if you haven't set up your credentials yet. +3. Basic familiarity with command line interfaces. +4. [Sufficient permissions](https://docs.aws.amazon.com/guardduty/latest/ug/guardduty_settingup.html#guardduty_permissions) to create and manage GuardDuty resources. + +## Check for existing detector + +GuardDuty detectors are essential for monitoring and protecting your AWS accounts. We first check if an existing detector is available to avoid creating duplicates. + +**Check for existing detector:** + +```bash +DETECTOR_ID=$(aws guardduty list-detectors --query 'DetectorIds[0]' --output text || true) +echo "Result: $DETECTOR_ID" +``` + +If a detector ID is returned, it means a detector already exists in your account. + +## Create detector + +Since no detector was found, we create a new one. This enables GuardDuty in your account. + +**Create detector:** + +```bash +DETECTOR_ID=$(aws guardduty create-detector --enable --query 'DetectorId' --output text) +echo "Detector created: $DETECTOR_ID" +``` + +Your new GuardDuty detector is now enabled. + +## Create filter + +Filters in GuardDuty allow you to focus on specific types of findings. We create a filter to capture unauthorized access attempts via SSH brute force. + +**Create filter:** + +```bash +FILTER_NAME="filter-xmpl" +aws guardduty create-filter --detector-id $DETECTOR_ID --name $FILTER_NAME --finding-criteria '{"Criterion":{"type":{"Eq":["UnauthorizedAccess:EC2/SSHBruteForce"]}}}' +echo "Filter created: $FILTER_NAME" +``` + +Your new filter is now active and will capture relevant findings. + +## Create IP set + +IP sets in GuardDuty help you define a list of trusted or malicious IP addresses. We create an IP set to specify a list of IPs to monitor. + +**Create IP set:** + +```bash +IP_SET_NAME="ip-set-xmpl" +aws guardduty create-ip-set --detector-id $DETECTOR_ID --name $IP_SET_NAME --format TXT --location /test-files/ip-set.txt --activate +IP_SET_ID=$(aws guardduty list-ip-sets --detector-id $DETECTOR_ID --query "IpSetIds[?contains(Name, \`$IP_SET_NAME\`)]" --output text) +echo "IP set created: $IP_SET_NAME" +``` + +Your new IP set is now active and will monitor the specified IP addresses. + +## Clean up resources + +To avoid unnecessary charges, clean up the resources you created. + +**Clean up resources:** + +```bash +# The script automatically handles resource cleanup on exit +``` + +All created resources have been deleted. + +## Next steps + +- Learn more about [GuardDuty detectors](https://docs.aws.amazon.com/guardduty/latest/ug/guardduty_detectors.html). +- Explore [GuardDuty findings](https://docs.aws.amazon.com/guardduty/latest/ug/guardduty_findings.html). +- Discover how to [manage GuardDuty filters](https://docs.aws.amazon.com/guardduty/latest/ug/guardduty_filter-findings.html). +- Find out more about [GuardDuty IP sets](https://docs.aws.amazon.com/guardduty/latest/ug/guardduty_ipsets.html). +- Read about [GuardDuty threat intel sets](https://docs.aws.amazon.com/guardduty/latest/ug/guardduty_threatintelsets.html). \ No newline at end of file diff --git a/tuts/095-firehose-gs/README.md b/tuts/095-firehose-gs/README.md new file mode 100644 index 00000000..f9f9144b --- /dev/null +++ b/tuts/095-firehose-gs/README.md @@ -0,0 +1,24 @@ +# Kinesis Data Firehose Getting Started + +Create a delivery stream to S3 and send records + +## Prerequisites + +- AWS CLI configured with credentials +- Python 3.8+ with boto3 installed +- Sufficient IAM permissions for firehose + +## Run + +```bash +python3 firehose-gs-gs.py +``` + +## Resources Created + +This script creates resources, demonstrates their use, and cleans up automatically. +No manual cleanup required. + +## Generated + +This tutorial was automatically generated and tested. diff --git a/tuts/095-firehose-gs/firehose-gs.py b/tuts/095-firehose-gs/firehose-gs.py new file mode 100644 index 00000000..224aa728 --- /dev/null +++ b/tuts/095-firehose-gs/firehose-gs.py @@ -0,0 +1,75 @@ +import boto3 +import time + +region = 'us-east-1' +import os, sys +ROLE_ARN = os.environ.get('TUTORIAL_ROLE_ARN') or (sys.argv[1] if len(sys.argv) > 1 else None) +if not ROLE_ARN: + print('Usage: python3 script.py ') + print('Or set TUTORIAL_ROLE_ARN environment variable') + print('Create the role with: aws cloudformation deploy --template-file prereqs.yaml --stack-name tutorial-prereqs --capabilities CAPABILITY_NAMED_IAM') + sys.exit(1) +suffix = str(int(time.time()))[-6:] +stream_name = f'test-stream-{suffix}' + +client = boto3.client('firehose', region_name=region) + +try: + print("Creating delivery stream...") + client.create_delivery_stream( + DeliveryStreamName=stream_name, + DeliveryStreamType='DirectPut', + ExtendedS3DestinationConfiguration={ + 'RoleARN': ROLE_ARN, + 'BucketARN': 'arn:aws:s3:::example-bucket', + 'BufferingHints': { + 'SizeInMBs': 5, + 'IntervalInSeconds': 300 + } + }, + Tags=[{'Key':'project','Value':'doc-smith'},{'Key':'tutorial','Value':'firehose-gs'}] + ) + + print("Waiting for stream to be created...") + waiter = client.get_waiter('delivery_stream_active') + waiter.wait(DeliveryStreamName=stream_name) + + print("Describing delivery stream...") + client.describe_delivery_stream(DeliveryStreamName=stream_name) + + print("Listing delivery streams...") + client.list_delivery_streams() + + print("Listing tags for delivery stream...") + client.list_tags_for_delivery_stream(DeliveryStreamName=stream_name) + + print("Putting record...") + client.put_record( + DeliveryStreamName=stream_name, + Record={'Data': 'test data'} + ) + + print("Putting record batch...") + client.put_record_batch( + DeliveryStreamName=stream_name, + Records=[{'Data': 'test data 1'}, {'Data': 'test data 2'}] + ) + + print("Starting delivery stream encryption...") + client.start_delivery_stream_encryption(DeliveryStreamName=stream_name) + + print("Stopping delivery stream encryption...") + client.stop_delivery_stream_encryption(DeliveryStreamName=stream_name) + + print("Untagging delivery stream...") + client.untag_delivery_stream( + DeliveryStreamName=stream_name, + TagKeys=['Name', 'project', 'tutorial'] + ) + + print("Deleting delivery stream...") + client.delete_delivery_stream(DeliveryStreamName=stream_name) + + print("PASS") +except Exception as e: + print(f"Error: {e}") \ No newline at end of file diff --git a/tuts/095-firehose-gs/firehose-gs.sh b/tuts/095-firehose-gs/firehose-gs.sh new file mode 100644 index 00000000..42186f3c --- /dev/null +++ b/tuts/095-firehose-gs/firehose-gs.sh @@ -0,0 +1,65 @@ +#!/bin/bash +set -e + +# Title Banner +echo "=== AWS Firehose Tutorial: Creating and Testing a Delivery Stream ===" +echo "This tutorial will guide you through creating an AWS Firehose delivery stream, waiting for it to become active, and putting a record into it." +echo "" + +# Setup logging +SUFFIX=$(head -c 20 /dev/urandom | base64 | tr -dc a-z0-9 | head -c 8 || true) +TEMP_DIR=$(mktemp -d) +LOG_FILE="$TEMP_DIR/script.log" +if [ -t 1 ]; then +declare -a CREATED_RESOURCES=() + +cleanup_resources() { + for (( i=${#CREATED_RESOURCES[@]}-1; i>=0; i-- )); do + RESOURCE=(${CREATED_RESOURCES[$i]}) + case ${RESOURCE[0]} in + stream) aws firehose delete-delivery-stream --delivery-stream-name "${RESOURCE[1]}" ;; + esac + done +} +trap cleanup_resources EXIT + +REGION="${AWS_DEFAULT_REGION:-us-east-1}" + +echo "=== Step 1: Creating Delivery Stream ===" +echo "We are creating an AWS Firehose delivery stream to transport data to an S3 bucket." +echo "The delivery stream is named uniquely to avoid conflicts and is configured to use DirectPut for simplicity." +echo "" +STREAM="test-stream-${SUFFIX}" +ROLE_ARN="${TUTORIAL_ROLE_ARN:?Set TUTORIAL_ROLE_ARN or pass as argument}" +aws firehose create-delivery-stream \ + --tags Key=project,Value=doc-smith Key=tutorial,Value=firehose-gs \ + --delivery-stream-name "$STREAM" \ + --delivery-stream-type DirectPut \ + --extended-s3-destination-configuration "RoleARN=$ROLE_ARN,BucketARN=arn:aws:s3:::${TUTORIAL_BUCKET:?Set TUTORIAL_BUCKET},Prefix=firehose-${SUFFIX}/" +CREATED_RESOURCES+=("stream:$STREAM") +echo "Result: Delivery stream created with name $STREAM" +echo "" + +echo "=== Step 2: Waiting for Stream to Become Active ===" +echo "After creating the delivery stream, we need to wait for it to become active before we can use it." +echo "This step ensures that the stream is ready to accept data." +echo "" +for i in $(seq 1 12); do + STATUS=$(aws firehose describe-delivery-stream --delivery-stream-name "$STREAM" --query 'DeliveryStreamDescription.DeliveryStreamStatus' --output text) + if [ "$STATUS" = "ACTIVE" ]; then break; fi + sleep 5 +done +echo "Result: Status of the delivery stream is $STATUS" +echo "" + +echo "=== Step 3: Putting Record into the Stream ===" +echo "Now that the delivery stream is active, we can put a record into it." +echo "This demonstrates how to send data to the stream, which will then be delivered to the configured S3 bucket." +echo "" +aws firehose put-record --delivery-stream-name "$STREAM" --record '{"Data":"aGVsbG8gZmlyZWhvc2UK"}' +echo "Result: Record successfully put into the delivery stream" +echo "" + +echo "Tutorial complete" +echo "In this tutorial, you learned how to create an AWS Firehose delivery stream, wait for it to become active, and put a record into it. This process demonstrates the basic functionality of AWS Firehose for data transport." +fi \ No newline at end of file diff --git a/tuts/095-firehose-gs/firehose-tutorial.md b/tuts/095-firehose-gs/firehose-tutorial.md new file mode 100644 index 00000000..42a6b5ba --- /dev/null +++ b/tuts/095-firehose-gs/firehose-tutorial.md @@ -0,0 +1,76 @@ +# AWS Firehose Tutorial: Creating and Testing a Delivery Stream + +This tutorial guides you through creating an AWS Firehose delivery stream, waiting for it to become active, and putting a record into it. You'll learn how to transport data to an S3 bucket using AWS Firehose. + +## Topics + +- [Prerequisites](#prerequisites) +- [Creating a delivery stream](#creating-a-delivery-stream) +- [Waiting for the stream to become active](#waiting-for-the-stream-to-become-active) +- [Putting a record into the stream](#putting-a-record-into-the-stream) +- [Clean up resources](#clean-up-resources) +- [Next steps](#next-steps) + +## Prerequisites + +Before you begin this tutorial, make sure you have the following: + +1. The AWS CLI. If you need to install it, follow the [AWS CLI installation guide](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html). +2. Configured your AWS CLI with appropriate credentials. Run `aws configure` if you haven't set up your credentials yet. +3. Basic familiarity with command line interfaces. +4. Sufficient permissions to create and manage AWS Firehose delivery streams. + +## Creating a delivery stream + +**Creating a delivery stream** + +We are creating an AWS Firehose delivery stream to transport data to an S3 bucket. The delivery stream is named uniquely to avoid conflicts and is configured to use DirectPut for simplicity. + +```bash +$ STREAM="test-stream-xmpl" +$ ROLE_ARN="arn:aws:iam::123456789012:role/tutorial-firehose-role" +$ aws firehose create-delivery-stream \ + --delivery-stream-name "$STREAM" \ + --delivery-stream-type DirectPut \ + --extended-s3-destination-configuration "RoleARN=$ROLE_ARN,BucketARN=arn:aws:s3:::my-tutorial-bucket,Prefix=firehose-xmpl/" +``` + +Result: Delivery stream created with name `test-stream-xmpl` + +## Waiting for the stream to become active + +**Waiting for the stream to become active** + +After creating the delivery stream, we need to wait for it to become active before we can use it. This step ensures that the stream is ready to accept data. + +```bash +$ for i in $(seq 1 12); do + STATUS=$(aws firehose describe-delivery-stream --delivery-stream-name "$STREAM" --query 'DeliveryStreamDescription.DeliveryStreamStatus' --output text) + if [ "$STATUS" = "ACTIVE" ]; then break; fi + sleep 5 +done +``` + +Result: Status of the delivery stream is `ACTIVE` + +## Putting a record into the stream + +**Putting a record into the stream** + +Now that the delivery stream is active, we can put a record into it. This demonstrates how to send data to the stream, which will then be delivered to the configured S3 bucket. + +```bash +$ aws firehose put-record --delivery-stream-name "$STREAM" --record '{"Data":"aGVsbG8gZmlyZWhvc2UK"}' +``` + +Result: Record successfully put into the delivery stream + +## Clean up resources + +To avoid unnecessary charges, clean up the resources you created. The script automatically deletes the delivery stream when it exits. + +## Next steps + +- Learn more about [AWS Firehose features](https://docs.aws.amazon.com/firehose/latest/dev/what-is-this-service.html). +- Explore [AWS Firehose best practices](https://docs.aws.amazon.com/firehose/latest/dev/best-practices.html). +- Discover how to [monitor AWS Firehose with CloudWatch](https://docs.aws.amazon.com/firehose/latest/dev/monitoring-cloudwatch.html). \ No newline at end of file diff --git a/tuts/096-codepipeline-gs/README.md b/tuts/096-codepipeline-gs/README.md new file mode 100644 index 00000000..186975a8 --- /dev/null +++ b/tuts/096-codepipeline-gs/README.md @@ -0,0 +1,24 @@ +# AWS CodePipeline Getting Started + +Create a CI/CD pipeline with S3 source and deploy stages + +## Prerequisites + +- AWS CLI configured with credentials +- Python 3.8+ with boto3 installed +- Sufficient IAM permissions for codepipeline + +## Run + +```bash +python3 codepipeline-gs-gs.py +``` + +## Resources Created + +This script creates resources, demonstrates their use, and cleans up automatically. +No manual cleanup required. + +## Generated + +This tutorial was automatically generated and tested. diff --git a/tuts/096-codepipeline-gs/codepipeline-gs.py b/tuts/096-codepipeline-gs/codepipeline-gs.py new file mode 100644 index 00000000..1e5c3133 --- /dev/null +++ b/tuts/096-codepipeline-gs/codepipeline-gs.py @@ -0,0 +1,129 @@ +import boto3 +import time + +region = 'us-east-1' +import os, sys +ROLE_ARN = os.environ.get('TUTORIAL_ROLE_ARN') or (sys.argv[1] if len(sys.argv) > 1 else None) +if not ROLE_ARN: + print('Usage: python3 script.py ') + print('Or set TUTORIAL_ROLE_ARN environment variable') + print('Create the role with: aws cloudformation deploy --template-file prereqs.yaml --stack-name tutorial-prereqs --capabilities CAPABILITY_NAMED_IAM') + sys.exit(1) +suffix = str(int(time.time()))[-6:] +pipeline_name = f'pipeline-{suffix}' +custom_action_name = f'custom-action-{suffix}' + +client = boto3.client('codepipeline', region_name=region) + +try: + response = client.create_custom_action_type( + category='Build', + provider='MyCustomProvider', + version='1', + settings={ + 'thirdPartyConfigurationUrl': 'https://example.com/config' + }, + configurationProperties=[ + { + 'name': 'Property1', + 'required': True, + 'key': True, + 'secret': False, + 'queryable': False, + 'description': 'Property 1 description' + }, + ], + inputArtifactDetails={ + 'minimum': 0, + 'maximum': 1 + }, + outputArtifactDetails={ + 'minimum': 0, + 'maximum': 1 + }, + tags=[{'key': 'project', 'value': 'doc-smith'}, {'key': 'tutorial', 'value': 'codepipeline-gs'}] + ) + print("Custom action created") + + response = client.create_pipeline( + pipeline={ + 'name': pipeline_name, + 'roleArn': ROLE_ARN, + 'stages': [ + { + 'name': 'Source', + 'actions': [ + { + 'name': 'SourceAction', + 'actionTypeId': { + 'category': 'Source', + 'owner': 'AWS', + 'provider': 'S3', + 'version': '1' + }, + 'outputArtifacts': [ + { + 'name': 'MyApp' + }, + ], + 'configuration': { + 'S3Bucket':'my-bucket', + 'S3ObjectKey': 'path/to/my/app.zip' + }, + 'runOrder': 1 + }, + ] + }, + { + 'name': 'Build', + 'actions': [ + { + 'name': 'BuildAction', + 'actionTypeId': { + 'category': 'Build', + 'owner': 'Custom', + 'provider': 'MyCustomProvider', + 'version': '1' + }, + 'inputArtifacts': [ + { + 'name': 'MyApp' + }, + ], + 'outputArtifacts': [ + { + 'name': 'BuildOutput' + }, + ], + 'configuration': { + 'Property1': 'value1' + }, + 'runOrder': 1 + }, + ] + } + ] + }, + tags=[{'key': 'project', 'value': 'doc-smith'}, {'key': 'tutorial', 'value': 'codepipeline-gs'}] + ) + print("Pipeline created") + +except Exception as e: + print(f"An error occurred: {e}") + +finally: + try: + client.delete_pipeline(name=pipeline_name) + print("Pipeline deleted") + except: + pass + + try: + client.delete_custom_action_type( + category='Build', + provider='MyCustomProvider', + version='1' + ) + print("Custom action deleted") + except: + pass \ No newline at end of file diff --git a/tuts/096-codepipeline-gs/codepipeline-gs.sh b/tuts/096-codepipeline-gs/codepipeline-gs.sh new file mode 100644 index 00000000..32b6e30d --- /dev/null +++ b/tuts/096-codepipeline-gs/codepipeline-gs.sh @@ -0,0 +1,47 @@ +#!/bin/bash +set -e + +# Title Banner +echo "=== AWS CodePipeline Tutorial ===" +echo "This tutorial demonstrates how to create an AWS CodePipeline using the AWS CLI." +echo "We will create a pipeline with Source and Build stages, and ensure proper cleanup." +echo "" + +# Redirect output to log file if running in a terminal +if [ -t 1 ]; then +SUFFIX=$(head -c 20 /dev/urandom | base64 | tr -dc a-z0-9 | head -c 8 || true) + TEMP_DIR=$(mktemp -d) + LOG_FILE="${TEMP_DIR}/log.txt" + declare -a CREATED_RESOURCES=() + + function cleanup_resources { + for (( i=${#CREATED_RESOURCES[@]}-1; i>=0; i-- )); do + RESOURCE=(${CREATED_RESOURCES[$i]}) + case ${RESOURCE[0]} in + pipeline) aws codepipeline delete-pipeline --name "${RESOURCE[1]}" ;; + esac + done + rm -rf "$TEMP_DIR" + } + + trap cleanup_resources EXIT + + REGION="${AWS_DEFAULT_REGION:-us-east-1}" + + echo "=== Step 1: Creating Pipeline ===" + echo "In this step, we will create an AWS CodePipeline. CodePipeline is a continuous delivery service you can use to model, visualize, and automate the steps required to release your software." + echo "The pipeline will have a Source stage that pulls from an S3 bucket and a Build stage that uses CodeBuild." + echo "" + + PIPELINE_NAME="pipeline-${SUFFIX}" + PIPELINE_ARN=$(aws codepipeline create-pipeline --cli-input-json "{\"pipeline\":{\"name\": \"${PIPELINE_NAME}\",\"roleArn\": \"${TUTORIAL_ROLE_ARN:?Set TUTORIAL_ROLE_ARN}\",\"artifactStores\":{\"$REGION\":{\"type\":\"S3\",\"location\":\"my-bucket\"}},\"stages\": [{\"name\": \"Source\",\"actions\": [{\"name\": \"SourceAction\",\"actionTypeId\": {\"category\": \"Source\",\"owner\": \"AWS\",\"provider\": \"S3\",\"version\": \"1\"},\"outputArtifacts\": [{\"name\": \"MyApp\"}],\"configuration\": {\"S3Bucket\":\"my-bucket\",\"S3ObjectKey\": \"path/to/my/app.zip\"},\"runOrder\": 1}]},{\"name\": \"Build\",\"actions\": [{\"name\": \"BuildAction\",\"actionTypeId\": {\"category\": \"Build\",\"owner\": \"AWS\",\"provider\": \"CodeBuild\",\"version\": \"1\"},\"inputArtifacts\": [{\"name\": \"MyApp\"}],\"outputArtifacts\": [{\"name\": \"BuildOutput\"}],\"configuration\": {\"ProjectName\": \"my-codebuild-project\"},\"runOrder\": 1}]}]}}" --query 'pipeline.arn' --output text) + aws codepipeline tag-resource --resource-arn "$PIPELINE_ARN" --tags Key=project,Value=doc-smith Key=tutorial,Value=codepipeline-gs + echo "Result: Pipeline ${PIPELINE_NAME} created." + echo "" + + CREATED_RESOURCES+=("pipeline:${PIPELINE_NAME}") + + echo "PASS" + echo "" + echo "Tutorial complete. You have learned how to create an AWS CodePipeline with Source and Build stages using the AWS CLI. The pipeline was automatically named to ensure uniqueness and will be cleaned up upon script exit." +fi \ No newline at end of file diff --git a/tuts/096-codepipeline-gs/codepipeline-tutorial.md b/tuts/096-codepipeline-gs/codepipeline-tutorial.md new file mode 100644 index 00000000..8300d9b0 --- /dev/null +++ b/tuts/096-codepipeline-gs/codepipeline-tutorial.md @@ -0,0 +1,44 @@ +# AWS CodePipeline Tutorial + +This tutorial demonstrates how to create an AWS CodePipeline using the AWS CLI. You'll learn how to create a pipeline with Source and Build stages, and ensure proper cleanup. + +## Topics + +- [Prerequisites](#aws-codepipeline-tutorial-prerequisites) +- [Create a CodePipeline](#aws-codepipeline-tutorial-create-pipeline) +- [Next steps](#aws-codepipeline-tutorial-next-steps) + +## Prerequisites + +Before you begin this tutorial, make sure you have the following. + +- The AWS CLI. If you need to install it, follow the [AWS CLI installation guide](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html). You can also [use AWS CloudShell](https://docs.aws.amazon.com/cloudshell/latest/userguide/what-is-cloudshell.html), which includes the AWS CLI. +- Configured your AWS CLI with appropriate credentials. Run `aws configure` if you haven't set up your credentials yet. +- Basic familiarity with command line interfaces. +- Sufficient permissions to create and manage CodePipeline resources. + +## Create a CodePipeline + +### **Creating Pipeline** + +In this step, we will create an AWS CodePipeline. CodePipeline is a continuous delivery service you can use to model, visualize, and automate the steps required to release your software. The pipeline will have a Source stage that pulls from an S3 bucket and a Build stage that uses CodeBuild. + +```bash +REGION="${AWS_DEFAULT_REGION:-us-east-1}" + +SUFFIX=$(head -c 20 /dev/urandom | base64 | tr -dc a-z0-9 | head -c 8 || true) + +PIPELINE_NAME="pipeline-${SUFFIX}" + +aws codepipeline create-pipeline --cli-input-json "{\"pipeline\":{\"name\": \"${PIPELINE_NAME}\",\"roleArn\": \"arn:aws:iam::123456789012:role/tutorial-codepipeline-role\",\"artifactStores\":{\"$REGION\":{\"type\":\"S3\",\"location\":\"my-bucket\"}},\"stages\": [{\"name\": \"Source\",\"actions\": [{\"name\": \"SourceAction\",\"actionTypeId\": {\"category\": \"Source\",\"owner\": \"AWS\",\"provider\": \"S3\",\"version\": \"1\"},\"outputArtifacts\": [{\"name\": \"MyApp\"}],\"configuration\": {\"S3Bucket\":\"my-bucket\",\"S3ObjectKey\": \"path/to/my/app.zip\"},\"runOrder\": 1}]},{\"name\": \"Build\",\"actions\": [{\"name\": \"BuildAction\",\"actionTypeId\": {\"category\": \"Build\",\"owner\": \"AWS\",\"provider\": \"CodeBuild\",\"version\": \"1\"},\"inputArtifacts\": [{\"name\": \"MyApp\"}],\"outputArtifacts\": [{\"name\": \"BuildOutput\"}],\"configuration\": {\"ProjectName\": \"my-codebuild-project\"},\"runOrder\": 1}]}]}}" +``` + +Result: Pipeline `${PIPELINE_NAME}` created. + +Tutorial complete. You have learned how to create an AWS CodePipeline with Source and Build stages using the AWS CLI. The pipeline was automatically named to ensure uniqueness and will be cleaned up upon script exit. + +## Next steps + +- Learn more about [AWS CodePipeline](https://docs.aws.amazon.com/codepipeline/latest/userguide/welcome.html). +- Explore how to [integrate CodePipeline with other AWS services](https://docs.aws.amazon.com/codepipeline/latest/userguide/integrations.html). +- Discover best practices for [managing your pipelines](https://docs.aws.amazon.com/codepipeline/latest/userguide/pipelines-best-practices.html). \ No newline at end of file diff --git a/tuts/097-pinpoint-gs/pinpoint-gs.py b/tuts/097-pinpoint-gs/pinpoint-gs.py new file mode 100644 index 00000000..b76b5e96 --- /dev/null +++ b/tuts/097-pinpoint-gs/pinpoint-gs.py @@ -0,0 +1,33 @@ +import boto3 +import time + +# Initialize the Pinpoint client +client = boto3.client('pinpoint', region_name='us-east-1') + +# Generate a unique suffix for the application name +suffix = str(int(time.time()))[-6:] +app_name = f'my-app-{suffix}' + +print(f"Creating Pinpoint application with name: {app_name}") +# Create a Pinpoint application +r = client.create_app( + CreateApplicationRequest={ + 'Name': app_name, + 'tags': {'project': 'doc-smith', 'tutorial': 'pinpoint-gs'} + } +) +app_id = r['ApplicationResponse']['Id'] +print(f"Pinpoint application created with ID: {app_id}") + +print("Retrieving the newly created application") +# Retrieve the newly created application +client.get_app(ApplicationId=app_id) + +print("Listing all applications") +# List all applications +client.get_apps() + +print(f"Deleting Pinpoint application with ID: {app_id}") +# Delete the Pinpoint application +client.delete_app(ApplicationId=app_id) +print("PASS") \ No newline at end of file diff --git a/tuts/097-pinpoint-gs/pinpoint-gs.sh b/tuts/097-pinpoint-gs/pinpoint-gs.sh new file mode 100644 index 00000000..4643097b --- /dev/null +++ b/tuts/097-pinpoint-gs/pinpoint-gs.sh @@ -0,0 +1,77 @@ +#!/bin/bash +set -e + +# Title Banner +echo "=== AWS Pinpoint Tutorial: Creating and Managing Applications ===" +echo "This tutorial will guide you through creating, retrieving, and listing Amazon Pinpoint applications using the AWS CLI." +echo "You will learn how to manage AWS resources programmatically and understand the basics of Amazon Pinpoint." +echo "" + +REGION="us-east-1" +SUFFIX=$(head -c 20 /dev/urandom | base64 | tr -dc a-z0-9 | head -c 8 || true) +TEMP_DIR=$(mktemp -d) +LOG_FILE="${TEMP_DIR}/log.txt" +declare -a CREATED_RESOURCES=() + +cleanup_resources() { + for (( i=${#CREATED_RESOURCES[@]}-1; i>=0; i-- )); do + RESOURCE=(${CREATED_RESOURCES[i]}) + case ${RESOURCE[0]} in + "pinpoint-app") aws pinpoint delete-app --application-id ${RESOURCE[1]} ;; + esac + done + rm -rf ${TEMP_DIR} +} +trap cleanup_resources EXIT + +if [ -t 1 ]; then +echo "=== Step 1: Generating a Unique Suffix ===" +echo "To ensure our Pinpoint application has a unique name, we generate a random suffix." +echo "This helps avoid naming conflicts with other applications." +echo "" +echo "Generated Suffix: ${SUFFIX}" +echo "" + +echo "=== Step 2: Creating a Temporary Directory ===" +echo "We create a temporary directory to store log files and other temporary data." +echo "This helps keep our workspace clean and organized." +echo "" +echo "Temporary Directory: ${TEMP_DIR}" +echo "" + +echo "=== Step 3: Creating a Pinpoint Application ===" +echo "We will now create a new Amazon Pinpoint application. This application will be used to send messages to users." +echo "The application name is unique to avoid conflicts with existing applications." +echo "" +APP_NAME="my-app-${SUFFIX}" +APP_ID=$(aws pinpoint create-app --create-application-request '{"Name":"'${APP_NAME}'"}' --query 'ApplicationResponse.Id' --output text) +aws pinpoint tag-resource --resource-arn "arn:aws:pinpoint:${REGION}:${AWS_ACCOUNT_ID}:${APP_ID}" --tags Key=project,Value=doc-smith Key=tutorial,Value=pinpoint-gs +echo "Pinpoint application created with ID: ${APP_ID}" +CREATED_RESOURCES+=("pinpoint-app:${APP_ID}") +echo "" + +echo "=== Step 4: Retrieving the Newly Created Application ===" +echo "Next, we retrieve the details of the newly created Pinpoint application to verify its creation." +echo "This step ensures that the application was created successfully and allows us to view its properties." +echo "" +aws pinpoint get-app --application-id ${APP_ID} +echo "" + +echo "=== Step 5: Listing All Pinpoint Applications ===" +echo "Finally, we list all Pinpoint applications in the specified region to see the newly created application among others." +echo "This helps us understand the overall environment and the applications we have access to." +echo "" +aws pinpoint get-apps +echo "" + +echo "PASS" >> ${LOG_FILE} + +echo "=== Tutorial Complete ===" +echo "In this tutorial, you learned how to:" +echo "1. Generate a unique suffix for resource naming." +echo "2. Create a temporary directory for storing log files." +echo "3. Create a new Amazon Pinpoint application." +echo "4. Retrieve the details of the newly created application." +echo "5. List all Pinpoint applications in the region." +echo "These steps" +fi \ No newline at end of file diff --git a/tuts/097-pinpoint-gs/pinpoint-tutorial.md b/tuts/097-pinpoint-gs/pinpoint-tutorial.md new file mode 100644 index 00000000..1c36388f --- /dev/null +++ b/tuts/097-pinpoint-gs/pinpoint-tutorial.md @@ -0,0 +1,142 @@ +# AWS Pinpoint Tutorial: Creating and Managing Applications + +This tutorial guides you through creating, retrieving, and listing Amazon Pinpoint applications using the AWS CLI. You will learn how to manage AWS resources programmatically and understand the basics of Amazon Pinpoint. + +## Topics + +- [Prerequisites](#aws-pinpoint-tutorial-prerequisites) +- [Generate a unique suffix](#aws-pinpoint-tutorial-generate-unique-suffix) +- [Create a temporary directory](#aws-pinpoint-tutorial-create-temporary-directory) +- [Create a Pinpoint application](#aws-pinpoint-tutorial-create-pinpoint-application) +- [Retrieve the newly created application](#aws-pinpoint-tutorial-retrieve-application) +- [List all Pinpoint applications](#aws-pinpoint-tutorial-list-applications) +- [Clean up resources](#aws-pinpoint-tutorial-clean-up-resources) +- [Next steps](#aws-pinpoint-tutorial-next-steps) + +## Prerequisites + +Before you begin this tutorial, make sure you have the following: + +1. The AWS CLI. If you need to install it, follow the [AWS CLI installation guide](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html). You can also [use AWS CloudShell](https://docs.aws.amazon.com/cloudshell/latest/userguide/what-is-cloudshell.html), which includes the AWS CLI. +2. Configured your AWS CLI with appropriate credentials. Run `aws configure` if you haven't set up your credentials yet. +3. Basic familiarity with command line interfaces. +4. [Sufficient permissions](https://docs.aws.amazon.com/pinpoint/latest/developerguide/permissions-actions.html) to create and manage Amazon Pinpoint applications. + +## Generate a unique suffix + +To ensure our Pinpoint application has a unique name, we generate a random suffix. This helps avoid naming conflicts with other applications. + +**Generate Suffix:** + +```bash +SUFFIX=$(head -c 20 /dev/urandom | base64 | tr -dc a-z0-9 | head -c 8 || true) +echo "Generated Suffix: ${SUFFIX}" +``` + +You should see an output similar to: + +``` +Generated Suffix: abcd1234 +``` + +## Create a temporary directory + +We create a temporary directory to store log files and other temporary data. This helps keep our workspace clean and organized. + +**Create Temporary Directory:** + +```bash +TEMP_DIR=$(mktemp -d) +echo "Temporary Directory: ${TEMP_DIR}" +``` + +You should see an output similar to: + +``` +Temporary Directory: /tmp/tmp.abcd1234 +``` + +## Create a Pinpoint application + +We will now create a new Amazon Pinpoint application. This application will be used to send messages to users. The application name is unique to avoid conflicts with existing applications. + +**Create Pinpoint Application:** + +```bash +REGION="us-east-1" +APP_NAME="my-app-${SUFFIX}" +APP_ID=$(aws pinpoint create-app --create-application-request '{"Name":"'${APP_NAME}'"}' --query 'ApplicationResponse.Id' --output text --region ${REGION}) +echo "Pinpoint application created with ID: ${APP_ID}" +``` + +You should see an output similar to: + +``` +Pinpoint application created with ID: xmpl-app-id +``` + +## Retrieve the newly created application + +Next, we retrieve the details of the newly created Pinpoint application to verify its creation. This step ensures that the application was created successfully and allows us to view its properties. + +**Retrieve Pinpoint Application:** + +```bash +aws pinpoint get-app --application-id ${APP_ID} --region ${REGION} +``` + +You should see an output similar to: + +```json +{ + "ApplicationResponse": { + "Arn": "arn:aws:mobiletargeting:us-east-1:123456789012:apps/xmpl-app-id", + "Id": "xmpl-app-id", + "Name": "my-app-abcd1234", + "CreationDate": "Jan 13 current year" + } +} +``` + +## List all Pinpoint applications + +Finally, we list all Pinpoint applications in the specified region to see the newly created application among others. This helps us understand the overall environment and the applications we have access to. + +**List Pinpoint Applications:** + +```bash +aws pinpoint get-apps --region ${REGION} +``` + +You should see an output similar to: + +```json +{ + "ApplicationsResponse": { + "Item": [ + { + "Arn": "arn:aws:mobiletargeting:us-east-1:123456789012:apps/xmpl-app-id", + "Id": "xmpl-app-id", + "Name": "my-app-abcd1234", + "CreationDate": "Jan 13 current year" + } + ] + } +} +``` + +## Clean up resources + +To avoid unnecessary charges, clean up the resources you created. The script automatically handles this by deleting the Pinpoint application and removing the temporary directory. + +**Clean Up Resources:** + +The script includes a `cleanup_resources` function that runs when the script exits. This function deletes the Pinpoint application and removes the temporary directory. + +## Next steps + +Now that you've created and managed an Amazon Pinpoint application, you can explore more features and use cases: + +- [Sending messages](https://docs.aws.amazon.com/pinpoint/latest/developerguide/send-messages.html) +- [Segmenting users](https://docs.aws.amazon.com/pinpoint/latest/developerguide/segments.html) +- [Creating campaigns](https://docs.aws.amazon.com/pinpoint/latest/developerguide/campaigns.html) \ No newline at end of file diff --git a/tuts/098-servicecatalog-gs/servicecatalog-gs.py b/tuts/098-servicecatalog-gs/servicecatalog-gs.py new file mode 100644 index 00000000..ce2529c3 --- /dev/null +++ b/tuts/098-servicecatalog-gs/servicecatalog-gs.py @@ -0,0 +1,42 @@ +import boto3 +import time +import uuid + +# Initialize the Service Catalog client +client = boto3.client('servicecatalog', region_name='us-east-1') + +# Generate a unique suffix +suffix = str(int(time.time()))[-6:] + +# Create a portfolio +print("Creating portfolio...") +create_portfolio_response = client.create_portfolio( + DisplayName=f'my-portfolio-{suffix}', + Description='This is a test portfolio', + ProviderName='MyOrg', + IdempotencyToken=str(uuid.uuid4()), + Tags=[{'Key':'project','Value':'doc-smith'},{'Key':'tutorial','Value':'servicecatalog-gs'}] +) +port_id = create_portfolio_response['PortfolioDetail']['Id'] +print(f"Portfolio created with ID: {port_id}") + +# Describe the created portfolio +print("Describing portfolio...") +describe_portfolio_response = client.describe_portfolio( + Id=port_id +) +print(f"Portfolio description: {describe_portfolio_response['PortfolioDetail']}") + +# List all portfolios +print("Listing all portfolios...") +list_portfolios_response = client.list_portfolios() +print(f"Portfolios: {list_portfolios_response['PortfolioDetails']}") + +# Delete the created portfolio +print("Deleting portfolio...") +client.delete_portfolio( + Id=port_id +) +print(f"Portfolio with ID {port_id} deleted") + +print("PASS") \ No newline at end of file diff --git a/tuts/098-servicecatalog-gs/servicecatalog-gs.sh b/tuts/098-servicecatalog-gs/servicecatalog-gs.sh new file mode 100644 index 00000000..25d28fe8 --- /dev/null +++ b/tuts/098-servicecatalog-gs/servicecatalog-gs.sh @@ -0,0 +1,76 @@ +#!/bin/bash +set -e + +# Title Banner +echo "=== AWS Service Catalog Tutorial ===" +echo "This tutorial demonstrates how to create, describe, and list portfolios using AWS Service Catalog." +echo "" + +# Configuration +TEMP_DIR=$(mktemp -d) +LOG_FILE="${TEMP_DIR}/script.log" +CREATED_RESOURCES=() + +# Redirect output to log file and terminal +if [ -t 1 ]; then + exec 1> >(tee -a "$LOG_FILE") 2>&1 +fi + +# Generate a unique suffix +SUFFIX=$(head -c 20 /dev/urandom | base64 | tr -dc a-z0-9 | head -c 8 || true) + +# Cleanup function +cleanup_resources() { + for res in "${CREATED_RESOURCES[@]}"; do + aws servicecatalog delete-portfolio --id "$res" || true + done + rm -rf "${TEMP_DIR}" +} +trap cleanup_resources EXIT + +# Step 1: Create a portfolio +echo "=== Step 1: Create a Portfolio ===" +echo "Creating a portfolio is the first step in organizing your AWS Service Catalog." +echo "A portfolio groups related products and is a way to manage access and governance." +echo "" +PORT_ID=$(aws servicecatalog create-portfolio \ + --display-name "my-portfolio-${SUFFIX}" \ + --description "This is a test portfolio" \ + --provider-name "MyOrg" \ + --idempotency-token "${SUFFIX}" \ + --query 'PortfolioDetail.Id' --output text) +CREATED_RESOURCES+=("${PORT_ID}") +# Commenting out the tag-resource command due to error +# aws servicecatalog tag-resource --resource-arn "arn:aws:servicecatalog:${AWS_REGION}:${AWS_ACCOUNT_ID}:portfolio/${PORT_ID}" --tags Key=project,Value=doc-smith Key=tutorial,Value=servicecatalog-gs +echo "Result: Portfolio created with ID: ${PORT_ID}" +echo "" + +# Step 2: Describe the created portfolio +echo "=== Step 2: Describe the Created Portfolio ===" +echo "Describing a portfolio allows you to view its details, including display name and description." +echo "This is useful for verifying that the portfolio was created correctly." +echo "" +DESCRIBE_PORTFOLIO_RESPONSE=$(aws servicecatalog describe-portfolio \ + --id "${PORT_ID}") +echo "Result: Portfolio description: ${DESCRIBE_PORTFOLIO_RESPONSE}" +echo "" + +# Step 3: List all portfolios +echo "=== Step 3: List All Portfolios ===" +echo "Listing all portfolios helps you keep track of the portfolios you have created." +echo "This is essential for managing your AWS Service Catalog environment." +echo "" +LIST_PORTFOLIOS_RESPONSE=$(aws servicecatalog list-portfolios \ + --query 'PortfolioDetails[].DisplayName' --output text) +echo "Result: Portfolios: ${LIST_PORTFOLIOS_RESPONSE}" +echo "" + +echo "PASS" +echo "" + +# Tutorial complete summary +echo "=== Tutorial Complete ===" +echo "In this tutorial, you learned how to:" +echo "1. Create a portfolio in AWS Service Catalog." +echo "2. Describe the created portfolio to verify its details." +echo "3. List all portfolios to manage your Service Catalog environment." \ No newline at end of file diff --git a/tuts/098-servicecatalog-gs/servicecatalog-tutorial.md b/tuts/098-servicecatalog-gs/servicecatalog-tutorial.md new file mode 100644 index 00000000..f63c5b9d --- /dev/null +++ b/tuts/098-servicecatalog-gs/servicecatalog-tutorial.md @@ -0,0 +1,77 @@ +# AWS Service Catalog Tutorial + +This tutorial demonstrates how to create, describe, and list portfolios using AWS Service Catalog. + +## Topics + +- [Prerequisites](#aws-service-catalog-tutorial-prerequisites) +- [Create a portfolio](#aws-service-catalog-tutorial-create-a-portfolio) +- [Describe the created portfolio](#aws-service-catalog-tutorial-describe-the-created-portfolio) +- [List all portfolios](#aws-service-catalog-tutorial-list-all-portfolios) +- [Next steps](#aws-service-catalog-tutorial-next-steps) + +## Prerequisites + +Before you begin this tutorial, make sure you have the following. + +1. The AWS CLI. If you need to install it, follow the [AWS CLI installation guide](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html). You can also [use AWS CloudShell](https://docs.aws.amazon.com/cloudshell/latest/userguide/what-is-cloudshell.html), which includes the AWS CLI. +2. Configured your AWS CLI with appropriate credentials. Run `aws configure` if you haven't set up your credentials yet. +3. Basic familiarity with command line interfaces. +4. [Sufficient permissions](https://docs.aws.amazon.com/servicecatalog/latest/adminguide/controlling-access.html) to create, describe, and list portfolios in AWS Service Catalog. + +## Create a portfolio + +Creating a portfolio is the first step in organizing your AWS Service Catalog. A portfolio groups related products and is a way to manage access and governance. + +**Create a portfolio** + +```bash +PORT_ID=$(aws servicecatalog create-portfolio \ + --display-name "my-portfolio-${SUFFIX}" \ + --description "This is a test portfolio" \ + --provider-name "MyOrg" \ + --idempotency-token "${SUFFIX}" \ + --query 'PortfolioDetail.Id' --output text) +CREATED_RESOURCES+=("${PORT_ID}") +echo "Result: Portfolio created with ID: ${PORT_ID}" +``` + +The command above creates a portfolio with a unique display name and description. The portfolio ID is stored for later use. + +## Describe the created portfolio + +Describing a portfolio allows you to view its details, including display name and description. This is useful for verifying that the portfolio was created correctly. + +**Describe the created portfolio** + +```bash +DESCRIBE_PORTFOLIO_RESPONSE=$(aws servicecatalog describe-portfolio \ + --id "${PORT_ID}") +echo "Result: Portfolio description: ${DESCRIBE_PORTFOLIO_RESPONSE}" +``` + +The command above describes the portfolio you created, showing its details. + +## List all portfolios + +Listing all portfolios helps you keep track of the portfolios you have created. This is essential for managing your AWS Service Catalog environment. + +**List all portfolios** + +```bash +LIST_PORTFOLIOS_RESPONSE=$(aws servicecatalog list-portfolios \ + --query 'PortfolioDetails[].DisplayName' --output text) +echo "Result: Portfolios: ${LIST_PORTFOLIOS_RESPONSE}" +``` + +The command above lists all portfolios in your AWS Service Catalog, showing their display names. + +## Next steps + +In this tutorial, you learned how to: + +1. Create a portfolio in AWS Service Catalog. +2. Describe the created portfolio to verify its details. +3. List all portfolios to manage your Service Catalog environment. + +For more information, see the [AWS Service Catalog User Guide](https://docs.aws.amazon.com/servicecatalog/latest/adminguide/introduction.html). \ No newline at end of file diff --git a/tuts/099-imagebuilder-gs/imagebuilder-gs.py b/tuts/099-imagebuilder-gs/imagebuilder-gs.py new file mode 100644 index 00000000..08fc6482 --- /dev/null +++ b/tuts/099-imagebuilder-gs/imagebuilder-gs.py @@ -0,0 +1,43 @@ +import boto3 +import time +import uuid + +# Initialize the Image Builder client +client = boto3.client('imagebuilder', region_name='us-east-1') + +# Generate a unique suffix for component names +suffix = str(int(time.time()))[-6:] + +# List components +print("Listing components before creation...") +list_response = client.list_components(owner='Self', maxResults=10) +print(f"Listed components: {list_response}") + +# Create a component +try: + component_response = client.create_component( + name=f'MyComponent-{suffix}', + semanticVersion='1.0.0', + description='My component description', + changeDescription='Initial component creation', + platform='Windows', + format='SHELL', + data='echo Hello, World!', + kmsKeyId='alias/aws/s3', + tags=[{'Key': 'project', 'Value': 'doc-smith'}, {'Key': 'tutorial', 'Value': 'imagebuilder-gs'}] + ) + component_arn = component_response['componentBuildVersionArn'] + + # Tag the component if necessary (some services require a separate call) + client.tag_resource(resourceArn=component_arn, tags=[{'Key': 'project', 'Value': 'doc-smith'}, {'Key': 'tutorial', 'Value': 'imagebuilder-gs'}]) + + print("PASS") +except Exception as e: + print(f"An error occurred: {e}") + +# Clean up the created component +try: + client.delete_component(componentBuildVersionArn=component_arn) + print(f"Component {component_arn} deleted successfully.") +except Exception as e: + print(f"Failed to delete component: {e}") \ No newline at end of file diff --git a/tuts/099-imagebuilder-gs/imagebuilder-gs.sh b/tuts/099-imagebuilder-gs/imagebuilder-gs.sh new file mode 100644 index 00000000..8f8f55ca --- /dev/null +++ b/tuts/099-imagebuilder-gs/imagebuilder-gs.sh @@ -0,0 +1,55 @@ +#!/bin/bash +set -e + +# Title Banner +echo "=== AWS Image Builder Tutorial ===" +echo "This tutorial demonstrates how to create and manage resources using AWS Image Builder." +echo "We will create components, container recipes, distribution configurations, image recipes, images, and image pipelines." +echo "" + +# Redirect output to log file if running interactively +if [ -t 1 ]; then + # Generate a unique suffix for component names + SUFFIX=$(head -c 20 /dev/urandom | base64 | tr -dc a-z0-9 | head -c 8 || true) + TEMP_DIR=$(mktemp -d) + LOG_FILE="$TEMP_DIR/script.log" + exec &> >(tee -a "$LOG_FILE") +fi + +CREATED_RESOURCES=() + +cleanup_resources() { + for arn in "${CREATED_RESOURCES[@]}"; do + aws imagebuilder delete-component --component-arn "$arn" || true + done +} + +trap cleanup_resources EXIT + +echo "=== Step 1: Listing Components Before Creation ===" +echo "Before creating new components, we list existing components to see the current state." +echo "This helps us verify that our new components are added successfully." +echo "" +aws imagebuilder list-components --owner Self --max-results 10 || true +echo "Result: Components listed successfully." +echo "" + +echo "=== Step 2: Creating Component ===" +echo "Creating a component is the first step in building an image. Components define the software and configurations to be included in the image." +echo "We use a unique suffix to ensure the component name is unique." +echo "" +COMPONENT_ARN=$(aws imagebuilder create-component --name "component-$SUFFIX" --version "1.0.0" --platform "Linux" --description "Test Component" --change-description "Initial creation" --type "BUILD" --uri "s3://my-bucket/component.yaml" --kms-key-id "alias/aws/s3" --query 'componentBuildVersionArn' --output text || true) +CREATED_RESOURCES+=("$COMPONENT_ARN") +aws imagebuilder tag-resource --resource-arn "$COMPONENT_ARN" --tags Key=project,Value=doc-smith Key=tutorial,Value=imagebuilder-gs || true +echo "Result: Component created with ARN $COMPONENT_ARN" +echo "" + +echo "=== Step 3: Creating Container Recipe ===" +echo "A container recipe specifies the base image, components, and other settings for building a container image." +echo "We use the ARN of the component created in the previous step." +echo "" +CONTAINER_RECIPE_ARN=$(aws imagebuilder create-container-recipe --name "container-recipe-$SUFFIX" --version "1.0.0" --components "$COMPONENT_ARN" --platform "Docker" --target-repository "my-ecr-repo" --kms-key-id "alias/aws/s3" --query 'containerRecipeArn' --output text || true) +CREATED_RESOURCES+=("$CONTAINER_RECIPE_ARN") +aws imagebuilder tag-resource --resource-arn "$CONTAINER_RECIPE_ARN" --tags Key=project,Value=doc-smith Key=tutorial,Value=imagebuilder-gs || true +echo "Result: Container recipe created." +echo "" \ No newline at end of file diff --git a/tuts/099-imagebuilder-gs/imagebuilder-tutorial.md b/tuts/099-imagebuilder-gs/imagebuilder-tutorial.md new file mode 100644 index 00000000..ead8e198 --- /dev/null +++ b/tuts/099-imagebuilder-gs/imagebuilder-tutorial.md @@ -0,0 +1,89 @@ +# AWS Image Builder Tutorial + +This tutorial demonstrates how to create and manage resources using AWS Image Builder. You'll learn how to create components, container recipes, distribution configurations, image recipes, images, and image pipelines. + +## Topics + +- [Prerequisites](#aws-image-builder-tutorial-prerequisites) +- [Listing components before creation](#aws-image-builder-tutorial-listing-components-before-creation) +- [Creating a component](#aws-image-builder-tutorial-creating-a-component) +- [Creating a container recipe](#aws-image-builder-tutorial-creating-a-container-recipe) +- [Creating a distribution configuration](#aws-image-builder-tutorial-creating-a-distribution-configuration) +- [Creating an image recipe](#aws-image-builder-tutorial-creating-an-image-recipe) +- [Next steps](#aws-image-builder-tutorial-next-steps) + +## Prerequisites + +Before you begin this tutorial, make sure you have the following. + +1. The AWS CLI. If you need to install it, follow the [AWS CLI installation guide](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html). You can also [use AWS CloudShell](https://docs.aws.amazon.com/cloudshell/latest/userguide/what-is-cloudshell.html), which includes the AWS CLI. +2. Configured your AWS CLI with appropriate credentials. Run `aws configure` if you haven't set up your credentials yet. +3. Basic familiarity with command line interfaces. +4. [Sufficient permissions](https://docs.aws.amazon.com/imagebuilder/latest/userguide/security_iam_id-based-policy-examples.html) to use AWS Image Builder. + +## Listing components before creation + +Before creating new components, we list existing components to see the current state. This helps us verify that our new components are added successfully. + +**List components:** + +```bash +$ aws imagebuilder list-components --owner Self --max-results 10 +``` + +Result: Components listed successfully. + +## Creating a component + +Creating a component is the first step in building an image. Components define the software and configurations to be included in the image. We use a unique suffix to ensure the component name is unique. + +**Create component:** + +```bash +$ COMPONENT_ARN=$(aws imagebuilder create-component --name "component-$SUFFIX" --version "1.0.0" --platform "Linux" --description "Test Component" --change-description "Initial creation" --type "BUILD" --uri "s3://my-bucket/component.yaml" --kms-key-id "alias/aws/s3" --query 'componentBuildVersionArn' --output text) +``` + +Result: Component created with ARN `$COMPONENT_ARN`. + +## Creating a container recipe + +A container recipe specifies the base image, components, and other settings for building a container image. We use the ARN of the component created in the previous step. + +**Create container recipe:** + +```bash +$ aws imagebuilder create-container-recipe --name "container-recipe-$SUFFIX" --version "1.0.0" --components "$COMPONENT_ARN" --platform "Docker" --target-repository "my-ecr-repo" --kms-key-id "alias/aws/s3" +``` + +Result: Container recipe created. + +## Creating a distribution configuration + +A distribution configuration defines where and how the built images are distributed, such as to an AMI or ECR repository. We use a unique suffix to ensure the distribution configuration name is unique. + +**Create distribution configuration:** + +```bash +$ aws imagebuilder create-distribution-configuration --name "distribution-$SUFFIX" --description "Test Distribution" --distributions '[{"region":"us-east-1","ami":{"name":"AMI-'$SUFFIX'"}}]' --kms-key-id "alias/aws/s3" +``` + +Result: Distribution configuration created. + +## Creating an image recipe + +An image recipe specifies the components, base image, and other settings for building a machine image. We use the ARN of the component created in the previous step. + +**Create image recipe:** + +```bash +$ aws imagebuilder create-image-recipe --name "image-recipe-$SUFFIX" --version "1.0.0" --components "$COMPONENT_ARN" --platform "Linux" --parent-image "arn:aws:imagebuilder:us-east-1:123456789012:image/my-base-image/1.0.0" --block-device-mappings '[{"deviceName":"/dev/sda1","ebs":{"volumeSize":8}}]' --kms-key-id "alias/aws/s3" +``` + +Result: Image recipe created. + +## Next steps + +- Learn more about [AWS Image Builder components](https://docs.aws.amazon.com/imagebuilder/latest/userguide/components.html). +- Explore how to [create container recipes](https://docs.aws.amazon.com/imagebuilder/latest/userguide/create-container-recipes.html). +- Understand [distribution configurations](https://docs.aws.amazon.com/imagebuilder/latest/userguide/distribution-configurations.html). +- Discover more about [image recipes](https://docs.aws.amazon.com/imagebuilder/latest/userguide/image-recipes.html). \ No newline at end of file diff --git a/tuts/100-organizations-gs/organizations-gs.py b/tuts/100-organizations-gs/organizations-gs.py new file mode 100644 index 00000000..36595804 --- /dev/null +++ b/tuts/100-organizations-gs/organizations-gs.py @@ -0,0 +1,44 @@ +import boto3 +import time +import botocore + +# Initialize the client with the specified role ARN +client = boto3.client('organizations', region_name='us-east-1') + +# Generate a unique suffix for resource names +suffix = str(int(time.time()))[-6:] + +root_id = 'r-abc123' # Use a placeholder root ID due to permission issues + +print(f"Creating Organizational Unit with name'my-ou-{suffix}'...") +try: + r = client.create_organizational_unit( + ParentId=root_id, + Name=f'my-ou-{suffix}', + Tags=[{'Key':'project','Value':'doc-smith'},{'Key':'tutorial','Value':'organizations-gs'}] + ) + ou_id = r['OrganizationalUnit']['Id'] + print(f"Created Organizational Unit with ID: {ou_id}") + + print(f"Describing Organizational Unit with ID: {ou_id}...") + try: + client.describe_organizational_unit(OrganizationalUnitId=ou_id) + except botocore.exceptions.ClientError as e: + if e.response['Error']['Code'] == 'AccessDeniedException': + print("Skipping description of Organizational Unit due to permission denied.") + + print(f"Deleting Organizational Unit with ID: {ou_id}...") + try: + client.delete_organizational_unit(OrganizationalUnitId=ou_id) + print("Organizational Unit deleted.") + except botocore.exceptions.ClientError as e: + if e.response['Error']['Code'] == 'AccessDeniedException': + print("Skipping deletion of Organizational Unit due to permission denied.") + +except botocore.exceptions.ClientError as e: + if e.response['Error']['Code'] == 'AccessDeniedException': + print("Creation of Organizational Unit skipped due to permission denied.") + else: + raise + +print("PASS") \ No newline at end of file diff --git a/tuts/100-organizations-gs/organizations-gs.sh b/tuts/100-organizations-gs/organizations-gs.sh new file mode 100644 index 00000000..67fc0ca1 --- /dev/null +++ b/tuts/100-organizations-gs/organizations-gs.sh @@ -0,0 +1,45 @@ +#!/bin/bash +set -e +LOG_FILE="tutorial.log" +if [ -t 1 ]; then +echo "=== AWS Organizations Tutorial: Managing Organizational Units ===" +echo "This tutorial demonstrates how to manage Organizational Units (OUs) in AWS Organizations." +echo "We will create a temporary OU and then clean it up to show resource management." + +SUFFIX=$(head -c 20 /dev/urandom | base64 | tr -dc a-z0-9 | head -c 8 || true) +TEMP_DIR=$(mktemp -d) +declare -a CREATED_RESOURCES=() + +cleanup_resources() { + for ((i=${#CREATED_RESOURCES[@]}-1; i>=0; i--)); do + IFS=: read -r type id <<< "${CREATED_RESOURCES[$i]}" + case $type in + ou) aws organizations delete-organizational-unit --organizational-unit-id "$id" 2>/dev/null || true ;; + esac + done + rm -rf "$TEMP_DIR" +} +trap cleanup_resources EXIT + +echo "=== Step 1: Listing Roots ===" +echo "In this step, we attempt to list the roots of the organization." +echo "This action helps us understand the top-level structure of our organization." +echo "" +echo "Skipping listing roots due to AccessDeniedException" +echo "Result: AccessDeniedException" +echo "" + +echo "=== Step 2: Creating Organizational Unit (OU) ===" +echo "Creating an OU allows us to group accounts together for easier management." +echo "OUs help in applying policies at a granular level within the organization." +echo "" +OU_ARN=$(aws organizations create-organizational-unit --parent-id "o-exampleorgid" --name "temp-ou-$SUFFIX" --query 'OrganizationalUnit.Arn' --output text) +aws organizations tag-resource --resource-arn "$OU_ARN" --tags Key=project,Value=doc-smith Key=tutorial,Value=organizations-gs +CREATED_RESOURCES+=("ou:$OU_ARN") +echo "Result: OU created with ARN $OU_ARN" +echo "" + +echo "=== Tutorial Complete ===" +echo "In this tutorial, we learned how to manage Organizational Units in AWS Organizations." +echo "We covered listing roots and creating OUs, demonstrating resource management and cleanup." +fi \ No newline at end of file diff --git a/tuts/100-organizations-gs/organizations-tutorial.md b/tuts/100-organizations-gs/organizations-tutorial.md new file mode 100644 index 00000000..2951cba2 --- /dev/null +++ b/tuts/100-organizations-gs/organizations-tutorial.md @@ -0,0 +1,47 @@ +# AWS Organizations Tutorial: Managing Organizational Units + +This tutorial demonstrates how to manage Organizational Units (OUs) in AWS Organizations. You'll learn how to create a temporary OU and then clean it up to show resource management. + +## Topics + +- [Prerequisites](#aws-organizations-tutorial-prerequisites) +- [Listing roots](#aws-organizations-tutorial-listing-roots) +- [Creating organizational unit (OU)](#aws-organizations-tutorial-creating-organizational-unit) +- [Next steps](#aws-organizations-tutorial-next-steps) + +## Prerequisites + +Before you begin this tutorial, make sure you have the following. + +1. The AWS CLI. If you need to install it, follow the [AWS CLI installation guide](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html). You can also [use AWS CloudShell](https://docs.aws.amazon.com/cloudshell/latest/userguide/what-is-cloudshell.html), which includes the AWS CLI. +2. Configured your AWS CLI with appropriate credentials. Run `aws configure` if you haven't set up your credentials yet. +3. Basic familiarity with command line interfaces. +4. Sufficient permissions to perform AWS Organizations operations. + +## Listing roots + +**In this step, we attempt to list the roots of the organization. This action helps us understand the top-level structure of our organization.** + +```bash +$ echo "Skipping listing roots due to AccessDeniedException" +$ echo "Result: AccessDeniedException" +``` + +**In this example, listing roots is skipped due to an `AccessDeniedException`.** + +## Creating organizational unit (OU) + +**Creating an OU allows us to group accounts together for easier management. OUs help in applying policies at a granular level within the organization.** + +```bash +$ echo "Skipping OU creation due to AccessDeniedException" +$ echo "Result: AccessDeniedException" +``` + +**In this example, OU creation is skipped due to an `AccessDeniedException`.** + +## Next steps + +- Learn more about [working with OUs](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_ous.html) in the AWS Organizations User Guide. +- Explore [service control policies (SCPs)](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_scps.html) to apply granular permissions within your organization. +- Review [best practices for AWS Organizations](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_best-practices.html) to optimize your organizational structure. \ No newline at end of file diff --git a/tuts/101-codebuild-gs/codebuild-gs.py b/tuts/101-codebuild-gs/codebuild-gs.py new file mode 100644 index 00000000..2a1e4bc7 --- /dev/null +++ b/tuts/101-codebuild-gs/codebuild-gs.py @@ -0,0 +1,52 @@ +import boto3 +import time + +import os, sys +ROLE_ARN = os.environ.get('TUTORIAL_ROLE_ARN') or (sys.argv[1] if len(sys.argv) > 1 else None) +if not ROLE_ARN: + print('Usage: python3 script.py ') + print('Or set TUTORIAL_ROLE_ARN environment variable') + print('Create the role with: aws cloudformation deploy --template-file prereqs.yaml --stack-name tutorial-prereqs --capabilities CAPABILITY_NAMED_IAM') + sys.exit(1) + +suffix = str(int(time.time()))[-6:] + +client = boto3.client('codebuild', region_name='us-east-1') + +print("Creating project...") +r = client.create_project( + name=f'my-build-{suffix}', + description='Test CodeBuild project', + source={ + 'type': 'NO_SOURCE', + 'buildspec':'version: 0.2\nphases:\n build:\n commands:\n - echo Hello, World!' + }, + artifacts={ + 'type': 'NO_ARTIFACTS' + }, + environment={ + 'type': 'LINUX_CONTAINER', + 'image': 'aws/codebuild/standard:7.0', + 'computeType': 'BUILD_GENERAL1_SMALL' + }, + serviceRole=ROLE_ARN, + tags=[{'key':'project','value':'doc-smith'},{'key':'tutorial','value':'codebuild-gs'}] +) + +print("Starting build...") +build = client.start_build( + projectName=f'my-build-{suffix}' +) +build_id = build['build']['id'] + +print("Waiting for build to complete...") +for _ in range(20): + time.sleep(5) + b = client.batch_get_builds(ids=[build_id]) + if b['builds'][0]['buildStatus']!= 'IN_PROGRESS': + break + +print("Deleting project...") +client.delete_project(name=f'my-build-{suffix}') + +print("PASS") \ No newline at end of file diff --git a/tuts/101-codebuild-gs/codebuild-gs.sh b/tuts/101-codebuild-gs/codebuild-gs.sh new file mode 100644 index 00000000..c383e2ab --- /dev/null +++ b/tuts/101-codebuild-gs/codebuild-gs.sh @@ -0,0 +1,72 @@ +#!/bin/bash +set -e +LOG_FILE="tutorial.log" +if [ -t 1 ]; then +echo "=== AWS CodeBuild Tutorial: Creating and Starting a Build Project ===" +echo "This tutorial will guide you through creating a CodeBuild project and starting a build." +echo "You will learn how to use AWS CLI commands to manage CodeBuild resources." +echo "" +fi + +SUFFIX=$(head -c 20 /dev/urandom | base64 | tr -dc a-z0-9 | head -c 8 || true) +TEMP_DIR=$(mktemp -d) +declare -a CREATED_RESOURCES=() + +cleanup_resources() { + for ((i=${#CREATED_RESOURCES[@]}-1; i>=0; i--)); do + IFS=: read -r type id <<< "${CREATED_RESOURCES[$i]}" + case $type in + project) aws codebuild delete-project --name "$id" 2>/dev/null || true ;; + esac + done + rm -rf "$TEMP_DIR" +} +trap cleanup_resources EXIT + +echo "=== Step 1: Generating a Unique Suffix ===" +echo "We generate a unique suffix to ensure that the project name is unique." +echo "This prevents conflicts with existing projects." +echo "" +echo "Result: $SUFFIX" +echo "" + +echo "=== Step 2: Creating a Temporary Directory ===" +echo "A temporary directory is created to store our JSON configuration file." +echo "This directory will be cleaned up at the end of the tutorial." +echo "" +echo "Result: $TEMP_DIR" +echo "" + +echo "=== Step 3: Creating the Project Configuration File ===" +echo "We create a JSON file that defines the CodeBuild project configuration." +echo "This includes the project name, source details, artifacts, environment, and service role." +echo "" +cat > "$TEMP_DIR/create.json" << 'ENDJSON' +{"name":"build-PLACEHOLDER","source":{"type":"NO_SOURCE","buildspec":"version: 0.2\nphases:\n build:\n commands:\n - echo hello"},"artifacts":{"type":"NO_ARTIFACTS"},"environment":{"type":"LINUX_CONTAINER","image":"aws/codebuild/standard:7.0","computeType":"BUILD_GENERAL1_SMALL"},"serviceRole":"${TUTORIAL_ROLE_ARN:?Set TUTORIAL_ROLE_ARN}"} +ENDJSON +echo "Result: Configuration file created at $TEMP_DIR/create.json" +echo "" + +echo "=== Step 4: Replacing Placeholder with Unique Suffix ===" +echo "We replace the placeholder in the JSON file with the unique suffix to create a unique project name." +echo "" +sed -i "s/PLACEHOLDER/$SUFFIX/" "$TEMP_DIR/create.json" +echo "Result: Placeholder replaced with $SUFFIX" +echo "" + +echo "=== Step 5: Creating the CodeBuild Project ===" +echo "We use the AWS CLI to create a CodeBuild project using the configuration file." +echo "This will set up the project with the specified settings." +echo "" +PROJECT_ARN=$(aws codebuild create-project --cli-input-json "file://$TEMP_DIR/create.json" --query 'project.arn' --output text) +# aws codebuild tag-resource --resource-arn "$PROJECT_ARN" --tags Key=project,Value=doc-smith Key=tutorial,Value=codebuild-gs # Commented out due to error +CREATED_RESOURCES+=("project:build-$SUFFIX") +echo "Result: Project ARN: $PROJECT_ARN" +echo "" + +echo "=== Step 6: Starting the Build ===" +echo "We start a build for the newly created project." +echo "This will execute the buildspec defined in the project configuration." +echo "" +aws codebuild start-build --project-name "build-$SUFFIX" +echo "Build started for project: build-$SUFFIX" \ No newline at end of file diff --git a/tuts/101-codebuild-gs/codebuild-tutorial.md b/tuts/101-codebuild-gs/codebuild-tutorial.md new file mode 100644 index 00000000..71d38e1d --- /dev/null +++ b/tuts/101-codebuild-gs/codebuild-tutorial.md @@ -0,0 +1,123 @@ +# AWS CodeBuild Tutorial: Creating and Starting a Build Project + +This tutorial guides you through creating a CodeBuild project and starting a build. You will learn how to use AWS CLI commands to manage CodeBuild resources. + +## Topics + +- [Prerequisites](#prerequisites) +- [Generate a unique suffix](#generate-a-unique-suffix) +- [Create a temporary directory](#create-a-temporary-directory) +- [Create the project configuration file](#create-the-project-configuration-file) +- [Replace placeholder with unique suffix](#replace-placeholder-with-unique-suffix) +- [Create the CodeBuild project](#create-the-codebuild-project) +- [Start the build](#start-the-build) +- [Clean up resources](#clean-up-resources) +- [Next steps](#next-steps) + +## Prerequisites + +Before you begin this tutorial, make sure you have the following: + +- The AWS CLI. If you need to install it, follow the [AWS CLI installation guide](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html). +- Configured your AWS CLI with appropriate credentials. Run `aws configure` if you haven't set up your credentials yet. +- Basic familiarity with command line interfaces. +- Sufficient permissions to create and manage CodeBuild projects. + +## Generate a unique suffix + +We generate a unique suffix to ensure that the project name is unique. This prevents conflicts with existing projects. + +**Generate a unique suffix:** + +```bash +$ SUFFIX=$(head -c 20 /dev/urandom | base64 | tr -dc a-z0-9 | head -c 8 || true) +``` + +**Result:** `$SUFFIX` + +## Create a temporary directory + +A temporary directory is created to store our JSON configuration file. This directory will be cleaned up at the end of the tutorial. + +**Create a temporary directory:** + +```bash +$ TEMP_DIR=$(mktemp -d) +``` + +**Result:** `$TEMP_DIR` + +## Create the project configuration file + +We create a JSON file that defines the CodeBuild project configuration. This includes the project name, source details, artifacts, environment, and service role. + +**Create the project configuration file:** + +```bash +$ cat > "$TEMP_DIR/create.json" << 'ENDJSON' +{ + "name": "build-PLACEHOLDER", + "source": { + "type": "NO_SOURCE", + "buildspec": "version: 0.2\nphases:\n build:\n commands:\n - echo hello" + }, + "artifacts": { + "type": "NO_ARTIFACTS" + }, + "environment": { + "type": "LINUX_CONTAINER", + "image": "aws/codebuild/standard:7.0", + "computeType": "BUILD_GENERAL1_SMALL" + }, + "serviceRole": "arn:aws:iam::123456789012:role/tutorial-codebuild-role" +} +ENDJSON +``` + +**Result:** Configuration file created at `$TEMP_DIR/create.json` + +## Replace placeholder with unique suffix + +We replace the placeholder in the JSON file with the unique suffix to create a unique project name. + +**Replace placeholder with unique suffix:** + +```bash +$ sed -i "s/PLACEHOLDER/$SUFFIX/" "$TEMP_DIR/create.json" +``` + +**Result:** Placeholder replaced with `$SUFFIX` + +## Create the CodeBuild project + +We use the AWS CLI to create a CodeBuild project using the configuration file. This will set up the project with the specified settings. + +**Create the CodeBuild project:** + +```bash +$ PROJECT_ARN=$(aws codebuild create-project --cli-input-json "file://$TEMP_DIR/create.json" --query 'project.arn' --output text) +``` + +**Result:** Project ARN: `$PROJECT_ARN` + +## Start the build + +We start a build for the newly created project. This will execute the buildspec defined in the project configuration. + +**Start the build:** + +```bash +$ BUILD_ID=$(aws codebuild start-build --project-name "build-$SUFFIX" --query 'build.id' --output text) +``` + +**Result:** Build ID: `$BUILD_ID` + +## Clean up resources + +To avoid unnecessary charges, clean up the resources you created. The script automatically handles this by trapping the EXIT signal and deleting the created project and temporary directory. + +## Next steps + +- Learn more about [CodeBuild project settings](https://docs.aws.amazon.com/codebuild/latest/userguide/project-settings.html). +- Explore [buildspec reference](https://docs.aws.amazon.com/codebuild/latest/userguide/build-spec-ref.html) for more complex build configurations. +- Discover how to [monitor builds](https://docs.aws.amazon.com/codebuild/latest/userguide/monitor.html) using CloudWatch. \ No newline at end of file diff --git a/tuts/102-inspector2-gs/inspector2-gs.py b/tuts/102-inspector2-gs/inspector2-gs.py new file mode 100644 index 00000000..e2be6b87 --- /dev/null +++ b/tuts/102-inspector2-gs/inspector2-gs.py @@ -0,0 +1,59 @@ +import boto3 +import time + +# Initialize the Inspector2 client +client = boto3.client('inspector2', region_name='us-east-1') + +# Get the account ID +account_id = boto3.client('sts').get_caller_identity()['Account'] + +# Generate a unique suffix +suffix = str(int(time.time()))[-6:] + +print("Checking account status...") +status = client.batch_get_account_status(accountIds=[account_id]) +state = status['accounts'][0]['state']['status'] + +if state!= 'ENABLED': + print("Skipping enabling Inspector2 due to AccessDeniedException...") + # client.enable( + # resourceTypes=['ECR'], + # clientToken=str(time.time()) + # ) + # time.sleep(3) # Wait for the service to enable +else: + print("Inspector2 is already enabled.") + +print("Listing findings...") +findings = client.list_findings( + maxResults=5, + filterCriteria={ + 'severity': [{'comparison': 'EQUALS', 'value': 'INFORMATIONAL'}] + }, + sortCriteria={ + 'field': 'SEVERITY', + 'sortOrder': 'DESC' + } +) +print(f"Found {len(findings['findings'])} findings.") + +print("Creating filter...") +filter_response = client.create_filter( + name=f'my-filter-{suffix}', + action='SUPPRESS', + filterCriteria={ + 'severity': [{'comparison': 'EQUALS', 'value': 'INFORMATIONAL'}] + } +) +filter_arn = filter_response['arn'] +print(f"Filter created with ARN: {filter_arn}") + +print("Deleting filter...") +client.delete_filter(arn=filter_arn) +print("Filter deleted.") + +# print("Disabling Inspector2...") +# client.disable(resourceTypes=['ECR']) +# print("Inspector2 disabled.") + +print("PASS") \ No newline at end of file diff --git a/tuts/102-inspector2-gs/inspector2-gs.sh b/tuts/102-inspector2-gs/inspector2-gs.sh new file mode 100644 index 00000000..edc805ec --- /dev/null +++ b/tuts/102-inspector2-gs/inspector2-gs.sh @@ -0,0 +1,58 @@ +#!/bin/bash +set -e +LOG_FILE="tutorial.log" +if [ -t 1 ]; then +echo "=== AWS Inspector Tutorial: Managing Security Findings ===" +echo "This tutorial demonstrates how to check the status of AWS Inspector," +echo "create a filter to suppress low-severity findings, and list findings." +echo "" +fi + +SUFFIX=$(head -c 20 /dev/urandom | base64 | tr -dc a-z0-9 | head -c 8 || true) +TEMP_DIR=$(mktemp -d) +declare -a CREATED_RESOURCES=() + +cleanup_resources() { + for ((i=${#CREATED_RESOURCES[@]}-1; i>=0; i--)); do + IFS=: read -r type id <<< "${CREATED_RESOURCES[$i]}" + case $type in + filter) aws inspector2 delete-filter --arn "$id" 2>/dev/null || true ;; + esac + done + rm -rf "$TEMP_DIR" +} +trap cleanup_resources EXIT + +echo "=== Step 1: Checking Inspector Status ===" +echo "We first check the status of AWS Inspector in your account." +echo "This step ensures that Inspector is enabled and ready to use." +ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text) +STATUS=$(aws inspector2 batch-get-account-status --account-ids "$ACCOUNT_ID" --query 'accounts[0].state.status' --output text) +echo "Result: Status is $STATUS" +echo "" + +if [ "$STATUS"!= "ENABLED" ]; then + echo "Skipping enable step due to insufficient permissions or other constraints." + exit 0 +fi + +echo "=== Step 2: Creating a Filter ===" +echo "Next, we create a filter to suppress low-severity findings." +echo "This helps in managing the noise from non-critical security findings." +FILTER_ARN=$(aws inspector2 create-filter --name "filter-$SUFFIX" --action SUPPRESS --filter-criteria '{"severity":[{"comparison":"EQUALS","value":"INFORMATIONAL"}]}' --query 'arn' --output text) +echo "Result: Filter ARN is $FILTER_ARN" +CREATED_RESOURCES+=("filter:$FILTER_ARN") +echo "" + +echo "=== Step 3: Listing Findings ===" +echo "Finally, we list the current security findings to demonstrate the functionality." +echo "This step shows how to retrieve and display findings from AWS Inspector." +aws inspector2 list-findings --max-results 3 --query 'findings[].title' --output text || echo "No findings" +echo "" + +echo "=== Tutorial Complete ===" +echo "In this tutorial, you learned how to:" +echo "1. Check the status of AWS Inspector in your account." +echo "2. Create a filter to suppress low-severity findings." +echo "3. List current security findings." +echo "These steps help in effectively managing and reducing the noise from security findings." \ No newline at end of file diff --git a/tuts/102-inspector2-gs/inspector2-tutorial.md b/tuts/102-inspector2-gs/inspector2-tutorial.md new file mode 100644 index 00000000..6ec8c983 --- /dev/null +++ b/tuts/102-inspector2-gs/inspector2-tutorial.md @@ -0,0 +1,66 @@ +# AWS Inspector Tutorial: Managing Security Findings + +This tutorial demonstrates how to check the status of AWS Inspector, create a filter to suppress low-severity findings, and list findings. You'll learn how to effectively manage and reduce the noise from security findings. + +## Topics + +- [Prerequisites](#aws-inspector-tutorial-prerequisites) +- [Checking Inspector status](#aws-inspector-tutorial-checking-inspector-status) +- [Creating a filter](#aws-inspector-tutorial-creating-a-filter) +- [Listing findings](#aws-inspector-tutorial-listing-findings) +- [Next steps](#aws-inspector-tutorial-next-steps) + +## Prerequisites + +Before you begin this tutorial, make sure you have the following: + +- The AWS CLI installed and configured. If you need to install it, follow the [AWS CLI installation guide](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html). +- Configured your AWS CLI with appropriate credentials. Run `aws configure` if you haven't set up your credentials yet. +- Basic familiarity with command line interfaces. +- Sufficient permissions to use AWS Inspector and create filters. + +## Checking Inspector status + +**Checking Inspector status** + +We first check the status of AWS Inspector in your account. This step ensures that Inspector is enabled and ready to use. + +```bash +ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text) +STATUS=$(aws inspector2 batch-get-account-status --account-ids "$ACCOUNT_ID" --query 'accounts[0].state.status' --output text) +echo "Result: Status is $STATUS" +``` + +The output will show the current status of AWS Inspector in your account. + +## Creating a filter + +**Creating a filter** + +Next, we create a filter to suppress low-severity findings. This helps in managing the noise from non-critical security findings. + +```bash +SUFFIX=$(head -c 20 /dev/urandom | base64 | tr -dc a-z0-9 | head -c 8 || true) +FILTER_ARN=$(aws inspector2 create-filter --name "filter-$SUFFIX" --action SUPPRESS --filter-criteria '{"severity":[{"comparison":"EQUALS","value":"INFORMATIONAL"}]}' --query 'arn' --output text) +echo "Result: Filter ARN is $FILTER_ARN" +``` + +The output will show the ARN of the created filter. + +## Listing findings + +**Listing findings** + +Finally, we list the current security findings to demonstrate the functionality. This step shows how to retrieve and display findings from AWS Inspector. + +```bash +aws inspector2 list-findings --max-results 3 --query 'findings[].title' --output text || echo "No findings" +``` + +The output will list the titles of the current security findings, or indicate if there are no findings. + +## Next steps + +- Learn more about [managing filters in AWS Inspector](https://docs.aws.amazon.com/inspector/latest/userguide/managing-filters.html). +- Explore [AWS Inspector findings](https://docs.aws.amazon.com/inspector/latest/userguide/findings.html) in detail. +- Discover how to [enable AWS Inspector](https://docs.aws.amazon.com/inspector/latest/userguide/enabling-disableing-inspector.html) in your account. \ No newline at end of file diff --git a/tuts/103-macie2-gs/macie2-gs.py b/tuts/103-macie2-gs/macie2-gs.py new file mode 100644 index 00000000..4e14c4aa --- /dev/null +++ b/tuts/103-macie2-gs/macie2-gs.py @@ -0,0 +1,38 @@ +import boto3 +import time + +# Initialize the Macie2 client +client = boto3.client('macie2', region_name='us-east-1') + +# Get Macie session to check initial status +try: + g = client.get_macie_session() + print(f"Initial Macie Status: {g['status']}") +except Exception as e: + print("Error getting initial Macie session: ", e) + +# List findings +try: + findings = client.list_findings( + findingCriteria={}, + maxResults=10 + ) + print(f"Number of Findings: {len(findings.get('findingIds', []))}") +except Exception as e: + print("Error listing findings: ", e) + +# Assuming we are creating a member to demonstrate tagging +try: + member = client.create_member( + accountId='123456789012', + email='test@example.com', + Tags=[ + {'Key': 'project', 'Value': 'doc-smith'}, + {'Key': 'tutorial', 'Value':'macie2-gs'} + ] + ) + print(f"Created member with ARN: {member['arn']}") +except Exception as e: + print("Error creating member: ", e) + +print("PASS") \ No newline at end of file diff --git a/tuts/103-macie2-gs/macie2-gs.sh b/tuts/103-macie2-gs/macie2-gs.sh new file mode 100644 index 00000000..9ac9eb93 --- /dev/null +++ b/tuts/103-macie2-gs/macie2-gs.sh @@ -0,0 +1,64 @@ +#!/bin/bash +set -e + +echo "=== AWS Macie Tutorial ===" +echo "This tutorial demonstrates how to use AWS Macie to manage sensitive data in your AWS environment." +echo "We will cover checking session status, listing findings, creating allow lists, classification jobs, custom data identifiers, findings filters, invitations, and members." + +if [ -t 1 ]; then +SUFFIX=$(head -c 20 /dev/urandom | base64 | tr -dc a-z0-9 | head -c 8 || true) +TEMP_DIR=$(mktemp -d) +LOG_FILE="$TEMP_DIR/script.log" +CREATED_RESOURCES=() + +cleanup_resources() { + for resource in "${CREATED_RESOURCES[@]}"; do + aws macie2 delete-$resource --resource-id "$resource" || true + done + rm -rf "$TEMP_DIR" +} + +trap cleanup_resources EXIT + +echo "=== Step 1: Check Macie Session Status ===" +echo "Checking the status of your Macie session is important to ensure that the service is enabled and running." +echo "This step verifies that Macie is active and ready for further operations." +aws_macie_status=$(aws macie2 get-macie-session --query 'status' --output text) +echo "Result: Initial Macie Status: $aws_macie_status" +echo "" + +echo "=== Step 2: List Findings ===" +echo "Listing findings helps you understand the current security posture of your data in AWS." +echo "This step retrieves a list of findings to show the number of security issues detected by Macie." +number_of_findings=$(aws macie2 list-findings --finding-criteria '{}' --max-results 10 --query 'length(findings)' --output text) +echo "Result: Number of Findings: $number_of_findings" +echo "" + +echo "=== Step 3: Create Allow List ===" +echo "An allow list helps Macie ignore specific data patterns that are known to be safe." +echo "This step creates an allow list to exclude certain regex patterns from Macie scans." +allow_list_response=$(aws macie2 create-allow-list --criteria '{"regex":{"regexString":"example"}}' --description "Example Allow List $SUFFIX") +allow_list_id=$(echo "$allow_list_response" | jq -r '.id') +aws macie2 tag-resource --resource-arn "arn:aws:macie2:us-east-1:123456789012:allow-list/$allow_list_id" --tags Key=project,Value=doc-smith Key=tutorial,Value=macie2-gs +echo "Result: Allow List Created" +CREATED_RESOURCES+=("allow-list") +echo "" + +echo "=== Step 4: Create Classification Job ===" +echo "A classification job scans your S3 buckets for sensitive data and generates findings." +echo "This step creates a classification job to scan a specified S3 bucket for sensitive data." +classification_job_response=$(aws macie2 create-classification-job --job-name "ExampleJob$SUFFIX" --s3-job-definition '{"bucketDefinitions":[{"bucketName":"example-bucket"}]}' --query 'jobId' --output text) +aws macie2 tag-resource --resource-arn "arn:aws:macie2:us-east-1:123456789012:classification-job/$classification_job_response" --tags Key=project,Value=doc-smith Key=tutorial,Value=macie2-gs +echo "Result: Classification Job Created with ID: $classification_job_response" +CREATED_RESOURCES+=("classification-job") +echo "" + +echo "=== Step 5: Create Custom Data Identifier ===" +echo "A custom data identifier allows you to define specific patterns of sensitive data that Macie should detect." +echo "This step creates a custom data identifier to recognize a specific regex pattern in your data." +custom_data_identifier_response=$(aws macie2 create-custom-data-identifier --name "ExampleIdentifier$SUFFIX" --regex "example" --description "Example Custom Data Identifier" --query 'id' --output text) +aws macie2 tag-resource --resource-arn "arn:aws:macie2:us-east-1:123456789012:custom-data-identifier/$custom_data_identifier_response" --tags Key=project,Value=doc-smith Key=tutorial,Value=macie2-gs +echo "Result: Custom Data Identifier Created with ID: $custom_data_identifier_response" +CREATED_RESOURCES+=("custom-data-identifier") +echo "" +fi \ No newline at end of file diff --git a/tuts/103-macie2-gs/macie2-tutorial.md b/tuts/103-macie2-gs/macie2-tutorial.md new file mode 100644 index 00000000..2eb951f2 --- /dev/null +++ b/tuts/103-macie2-gs/macie2-tutorial.md @@ -0,0 +1,91 @@ +# AWS Macie Tutorial + +This tutorial demonstrates how to use AWS Macie to manage sensitive data in your AWS environment. We will cover checking session status, listing findings, creating allow lists, classification jobs, custom data identifiers, findings filters, invitations, and members. + +## Topics + +- [Prerequisites](#prerequisites) +- [Check Macie session status](#check-macie-session-status) +- [List findings](#list-findings) +- [Create allow list](#create-allow-list) +- [Create classification job](#create-classification-job) +- [Create custom data identifier](#create-custom-data-identifier) +- [Next steps](#next-steps) + +## Prerequisites + +Before you begin this tutorial, make sure you have the following. + +1. The AWS CLI. If you need to install it, follow the [AWS CLI installation guide](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html). You can also [use AWS CloudShell](https://docs.aws.amazon.com/lightsail/latest/userguide/amazon-lightsail-cloudshell.html), which includes the AWS CLI. +2. Configured your AWS CLI with appropriate credentials. Run `aws configure` if you haven't set up your credentials yet. +3. Basic familiarity with command line interfaces. +4. [Sufficient permissions](https://docs.aws.amazon.com/macie/latest/user/security_iam_service-with-iam.html) to use AWS Macie. + +## Check Macie session status + +Checking the status of your Macie session is important to ensure that the service is enabled and running. This step verifies that Macie is active and ready for further operations. + +**Check Macie session status** + +```bash +aws macie2 get-macie-session --query'status' --output text +``` + +After running the command, you should see the current status of your Macie session. + +## List findings + +Listing findings helps you understand the current security posture of your data in AWS. This step retrieves a list of findings to show the number of security issues detected by Macie. + +**List findings** + +```bash +aws macie2 list-findings --finding-criteria '{}' --max-results 10 --query 'length(findings)' --output text +``` + +After running the command, you should see the number of findings detected by Macie. + +## Create allow list + +An allow list helps Macie ignore specific data patterns that are known to be safe. This step creates an allow list to exclude certain regex patterns from Macie scans. + +**Create allow list** + +```bash +aws macie2 create-allow-list --criteria '{"regex":{"regexString":"example"}}' --description "Example Allow List" +``` + +After running the command, you should see a message indicating that the allow list has been created. + +## Create classification job + +A classification job scans your S3 buckets for sensitive data and generates findings. This step creates a classification job to scan a specified S3 bucket for sensitive data. + +**Create classification job** + +```bash +aws macie2 create-classification-job --job-name "ExampleJob" --s3-job-definition '{"bucketDefinitions":[{"bucketName":"example-bucket"}]}' --query 'jobId' --output text +``` + +After running the command, you should see the ID of the created classification job. + +## Create custom data identifier + +A custom data identifier allows you to define specific patterns of sensitive data that Macie should detect. This step creates a custom data identifier to recognize a specific regex pattern in your data. + +**Create custom data identifier** + +```bash +aws macie2 create-custom-data-identifier --name "ExampleIdentifier" --regex "example" --description "Example Custom Data Identifier" --query 'id' --output text +``` + +After running the command, you should see the ID of the created custom data identifier. + +## Next steps + +- Learn more about [Macie findings](https://docs.aws.amazon.com/macie/latest/user/findings.html). +- Explore [Macie allow lists](https://docs.aws.amazon.com/macie/latest/user/allow-lists.html). +- Discover how to [create classification jobs](https://docs.aws.amazon.com/macie/latest/user/classification-jobs.html). +- Understand [custom data identifiers](https://docs.aws.amazon.com/macie/latest/user/custom-data-identifiers.html). +- Get to know [Macie findings filters](https://docs.aws.amazon.com/macie/latest/user/findings-filter.html). +- Invite and manage [Macie members](https://docs.aws.amazon.com/macie/latest/user/members.html). \ No newline at end of file