There are more AWS SDK examples available in the AWS Doc SDK Examples
Get started with Marketplace Buyer using the CLI
The following code example shows how to:
Use ec2 AuthorizeSecurityGroupIngress
Use ec2 CreateKeyPair
Use ec2 CreateSecurityGroup
- Bash
-
- AWS CLI with Bash script
-
Note
There's more on GitHub. Find the complete example and learn how to set up and run in the Sample developer tutorials
repository. #!/bin/bash # AWS Marketplace Buyer Getting Started Script # This script demonstrates how to search for products in AWS Marketplace, # launch an EC2 instance with a product AMI, and manage subscriptions. set -euo pipefail # Setup logging with secure permissions LOG_FILE="marketplace-tutorial.log" touch "$LOG_FILE" chmod 600 "$LOG_FILE" exec > >(tee -a "$LOG_FILE") 2>&1 echo "===================================================" echo "AWS Marketplace Buyer Getting Started Tutorial" echo "===================================================" echo "This script will:" echo "1. List available products in AWS Marketplace" echo "2. Create resources needed to launch an EC2 instance" echo "3. Launch an EC2 instance with an Amazon Linux 2 AMI" echo "4. Show how to manage and terminate the instance" echo "===================================================" echo "" # Validate AWS CLI is installed and configured if ! command -v aws &> /dev/null; then echo "ERROR: AWS CLI is not installed. Please install it first." exit 1 fi # Verify AWS credentials are configured if ! aws sts get-caller-identity &> /dev/null; then echo "ERROR: AWS credentials are not configured. Please configure them first." exit 1 fi # Validate jq is installed if ! command -v jq &> /dev/null; then echo "ERROR: jq is not installed. Please install jq for safe JSON parsing." exit 1 fi # Function to safely extract JSON values using jq extract_json_value() { local json=$1 local query=$2 echo "$json" | jq -r "$query" 2>/dev/null || { echo "ERROR: Failed to parse JSON with query: $query" >&2 return 1 } } # Function to validate AWS permissions validate_aws_permissions() { echo "Validating AWS permissions..." local identity identity=$(aws sts get-caller-identity --output json) local account_id account_id=$(extract_json_value "$identity" '.Account') || return 1 local arn arn=$(extract_json_value "$identity" '.Arn') || return 1 echo "AWS Account ID: $account_id" echo "AWS Principal ARN: $arn" echo "Note: This script requires EC2 permissions for key pair, security group, and instance management." echo "" } # Function to clean up resources cleanup_resources() { echo "" echo "===================================================" echo "CLEANING UP RESOURCES" echo "===================================================" if [ -n "${INSTANCE_ID:-}" ]; then echo "Terminating EC2 instance: $INSTANCE_ID" aws ec2 terminate-instances --instance-ids "$INSTANCE_ID" --region "$AWS_REGION" > /dev/null 2>&1 || true echo "Waiting for instance to terminate..." aws ec2 wait instance-terminated --instance-ids "$INSTANCE_ID" --region "$AWS_REGION" 2>/dev/null || true echo "Instance terminated successfully." fi if [ -n "${SECURITY_GROUP_ID:-}" ]; then echo "Waiting before deleting security group..." sleep 5 echo "Deleting security group: $SECURITY_GROUP_ID" aws ec2 delete-security-group --group-id "$SECURITY_GROUP_ID" --region "$AWS_REGION" > /dev/null 2>&1 || true echo "Security group deleted." fi if [ -n "${KEY_NAME:-}" ]; then echo "Deleting key pair: $KEY_NAME" aws ec2 delete-key-pair --key-name "$KEY_NAME" --region "$AWS_REGION" > /dev/null 2>&1 || true # Remove the local key file if it exists with secure deletion if [ -f "${KEY_NAME}.pem" ]; then if command -v shred &> /dev/null; then shred -vfz -n 3 "${KEY_NAME}.pem" 2>/dev/null || rm -f "${KEY_NAME}.pem" else rm -f "${KEY_NAME}.pem" fi echo "Local key file securely deleted." fi fi echo "Cleanup completed." } # Set trap to ensure cleanup on script exit trap cleanup_resources EXIT # Get the current AWS region AWS_REGION=$(aws configure get region || echo "us-east-1") if [ -z "$AWS_REGION" ] || [ "$AWS_REGION" = "None" ]; then AWS_REGION="us-east-1" fi echo "Using AWS Region: $AWS_REGION" echo "" # Validate permissions validate_aws_permissions # Generate random identifier for resource names using cryptographically secure method RANDOM_ID=$(head -c 6 /dev/urandom | od -An -tx1 | tr -d ' ') KEY_NAME="marketplace-key-${RANDOM_ID}" SECURITY_GROUP_NAME="marketplace-sg-${RANDOM_ID}" # Initialize variables to track created resources INSTANCE_ID="" SECURITY_GROUP_ID="" AMI_ID="" # Step 1: List available products in AWS Marketplace echo "Listing available products in AWS Marketplace..." echo "Note: In a real scenario, you would use marketplace-catalog commands to list and search for products." echo "However, this requires specific permissions and product knowledge." echo "" echo "For this tutorial, we'll use a public Amazon Linux 2 AMI instead of an actual marketplace product." echo "This is because subscribing to marketplace products requires accepting terms via the console." echo "" # Step 2: Create a key pair for SSH access echo "Creating key pair: $KEY_NAME" KEY_OUTPUT=$(aws ec2 create-key-pair \ --key-name "$KEY_NAME" \ --region "$AWS_REGION" \ --query 'KeyMaterial' \ --output text) || { echo "ERROR: Failed to create key pair" >&2 exit 1 } # Securely save the key with restricted permissions if ! echo "$KEY_OUTPUT" > "${KEY_NAME}.pem" 2>/dev/null; then echo "ERROR: Failed to write key file ${KEY_NAME}.pem" >&2 exit 1 fi chmod 600 "${KEY_NAME}.pem" || { echo "ERROR: Failed to set permissions on key file" >&2 rm -f "${KEY_NAME}.pem" exit 1 } echo "Key pair created and saved to ${KEY_NAME}.pem with secure permissions (600)" # Step 3: Create a security group echo "Creating security group: $SECURITY_GROUP_NAME" SG_OUTPUT=$(aws ec2 create-security-group \ --group-name "$SECURITY_GROUP_NAME" \ --description "Security group for AWS Marketplace tutorial" \ --region "$AWS_REGION" \ --output json) || { echo "ERROR: Failed to create security group" >&2 exit 1 } # Extract security group ID using jq for safe parsing SECURITY_GROUP_ID=$(extract_json_value "$SG_OUTPUT" '.GroupId') || exit 1 if [ -z "$SECURITY_GROUP_ID" ] || [ "$SECURITY_GROUP_ID" = "null" ]; then echo "ERROR: Could not extract security group ID" >&2 exit 1 fi echo "Security group created with ID: $SECURITY_GROUP_ID" # Add inbound rules for SSH and HTTP in parallel for better performance echo "Configuring security group rules..." { aws ec2 authorize-security-group-ingress \ --group-id "$SECURITY_GROUP_ID" \ --protocol tcp \ --port 22 \ --cidr 0.0.0.0/0 \ --region "$AWS_REGION" > /dev/null 2>&1 } & SSH_PID=$! { aws ec2 authorize-security-group-ingress \ --group-id "$SECURITY_GROUP_ID" \ --protocol tcp \ --port 80 \ --cidr 0.0.0.0/0 \ --region "$AWS_REGION" > /dev/null 2>&1 } & HTTP_PID=$! # Wait for both operations to complete wait $SSH_PID || { echo "ERROR: Failed to add SSH ingress rule" >&2 exit 1 } wait $HTTP_PID || { echo "ERROR: Failed to add HTTP ingress rule" >&2 exit 1 } echo "Security group configured with SSH and HTTP access." echo "WARNING: SSH rule allows access from any IP (0.0.0.0/0). Restrict this in production." echo "WARNING: In a production environment, you should restrict access to specific IP ranges." echo "" # Step 4: Get the latest Amazon Linux 2 AMI ID - Use pagination to optimize costs echo "Getting the latest Amazon Linux 2 AMI ID..." AMI_ID=$(aws ec2 describe-images \ --owners amazon \ --filters "Name=name,Values=amzn2-ami-hvm-2.0.*-x86_64-gp2" "Name=state,Values=available" \ --region "$AWS_REGION" \ --query "sort_by(Images, &CreationDate)[-1].ImageId" \ --output text \ --max-results 50) || { echo "ERROR: Failed to describe images" >&2 exit 1 } if [ -z "$AMI_ID" ] || [ "$AMI_ID" = "None" ]; then echo "ERROR: Could not find a suitable AMI ID" >&2 exit 1 fi echo "Using AMI ID: $AMI_ID" echo "Note: In a real marketplace scenario, you would use the AMI ID from your subscribed product." echo "" # Step 5: Launch an EC2 instance with cost optimization echo "Launching EC2 instance with the AMI..." echo "Using t2.micro (eligible for AWS Free Tier if applicable)" INSTANCE_OUTPUT=$(aws ec2 run-instances \ --image-id "$AMI_ID" \ --instance-type t2.micro \ --key-name "$KEY_NAME" \ --security-group-ids "$SECURITY_GROUP_ID" \ --count 1 \ --region "$AWS_REGION" \ --monitoring Enabled=false \ --tag-specifications 'ResourceType=instance,Tags=[{Key=project,Value=doc-smith},{Key=tutorial,Value=marketplace-buyer-gs}]' \ --output json) || { echo "ERROR: Failed to launch instance" >&2 exit 1 } # Extract instance ID using jq for safe parsing INSTANCE_ID=$(extract_json_value "$INSTANCE_OUTPUT" '.Instances[0].InstanceId') || exit 1 if [ -z "$INSTANCE_ID" ] || [ "$INSTANCE_ID" = "null" ]; then echo "ERROR: Could not extract instance ID" >&2 exit 1 fi echo "Instance launched with ID: $INSTANCE_ID" # Wait for the instance to be running echo "Waiting for instance to be in running state..." aws ec2 wait instance-running --instance-ids "$INSTANCE_ID" --region "$AWS_REGION" || { echo "ERROR: Instance failed to reach running state" >&2 exit 1 } echo "Instance is now running." echo "" # Step 6: Get instance details echo "Getting instance details..." INSTANCE_DETAILS=$(aws ec2 describe-instances \ --instance-ids "$INSTANCE_ID" \ --region "$AWS_REGION" \ --output json) || { echo "ERROR: Failed to describe instance" >&2 exit 1 } echo "Instance details:" extract_json_value "$INSTANCE_DETAILS" '.Reservations[0].Instances[0] | {InstanceId, State: .State.Name, PublicDnsName, PrivateIpAddress, LaunchTime, InstanceType}' || exit 1 # Display summary of created resources echo "" echo "===================================================" echo "RESOURCE SUMMARY" echo "===================================================" echo "Key Pair: $KEY_NAME" echo "Security Group: $SECURITY_GROUP_NAME (ID: $SECURITY_GROUP_ID)" echo "EC2 Instance: $INSTANCE_ID" echo "Instance Type: t2.micro (cost-optimized)" echo "AMI ID: $AMI_ID" echo "Region: $AWS_REGION" echo "" echo "COST OPTIMIZATION NOTES:" echo "- t2.micro instances are eligible for AWS Free Tier (750 hours/month for 12 months)" echo "- Detailed monitoring is disabled to reduce costs" echo "- Consider using Spot Instances for non-production workloads" echo "- Review AWS Pricing Calculator: https://calculator.aws/" echo "" echo "To connect to your instance (once it's fully initialized):" echo "ssh -i ${KEY_NAME}.pem ec2-user@<public-dns-name>" echo "Replace <public-dns-name> with the PublicDnsName from the instance details above." echo "" # Auto-confirm cleanup of resources echo "===================================================" echo "CLEANUP CONFIRMATION" echo "===================================================" echo "Cleaning up all created resources..." echo "" echo "Script completed. See $LOG_FILE for the complete log."-
For API details, see the following topics in AWS CLI Command Reference.
-
Get started with Aws Direct Connect
Getting started with Amazon DocumentDB