IAM examples using SDK for Java 2.x - AWS SDK Code Examples

There are more AWS SDK examples available in the AWS Doc SDK Examples GitHub repo.

IAM examples using SDK for Java 2.x

The following code examples show you how to perform actions and implement common scenarios by using the AWS SDK for Java 2.x with IAM.

Basics are code examples that show you how to perform the essential operations within a service.

Actions are code excerpts from larger programs and must be run in context. While actions show you how to call individual service functions, you can see actions in context in their related scenarios.

Scenarios are code examples that show you how to accomplish specific tasks by calling multiple functions within a service or combined with other AWS services.

Each example includes a link to the complete source code, where you can find instructions on how to set up and run the code in context.

Get started

The following code examples show how to get started using IAM.

SDK for Java 2.x
Note

There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository.

import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.iam.IamClient; import software.amazon.awssdk.services.iam.model.ListPoliciesResponse; import software.amazon.awssdk.services.iam.model.Policy; import java.util.List; /** * Before running this Java V2 code example, set up your development * environment, including your credentials. * * For more information, see the following documentation topic: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html */ public class HelloIAM { public static void main(String[] args) { Region region = Region.AWS_GLOBAL; IamClient iam = IamClient.builder() .region(region) .build(); listPolicies(iam); } public static void listPolicies(IamClient iam) { ListPoliciesResponse response = iam.listPolicies(); List<Policy> polList = response.policies(); polList.forEach(policy -> { System.out.println("Policy Name: " + policy.policyName()); }); } }
  • For API details, see ListPolicies in AWS SDK for Java 2.x API Reference.

Basics

The following code example shows how to create a user and assume a role.

Warning

To avoid security risks, don't use IAM users for authentication when developing purpose-built software or working with real data. Instead, use federation with an identity provider such as AWS IAM Identity Center.

  • Create a user with no permissions.

  • Create a role that grants permission to list Amazon S3 buckets for the account.

  • Add a policy to let the user assume the role.

  • Assume the role and list S3 buckets using temporary credentials, then clean up resources.

SDK for Java 2.x
Note

There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository.

Create functions that wrap IAM user actions.

/* To run this Java V2 code example, set up your development environment, including your credentials. For information, see this documentation topic: https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html This example performs these operations: 1. Creates a user that has no permissions. 2. Creates a role and policy that grants Amazon S3 permissions. 3. Creates a role. 4. Grants the user permissions. 5. Gets temporary credentials by assuming the role. Creates an Amazon S3 Service client object with the temporary credentials. 6. Deletes the resources. */ public class IAMScenario { public static final String DASHES = new String(new char[80]).replace("\0", "-"); public static final String PolicyDocument = "{" + " \"Version\": \"2012-10-17\"," + " \"Statement\": [" + " {" + " \"Effect\": \"Allow\"," + " \"Action\": [" + " \"s3:*\"" + " ]," + " \"Resource\": \"*\"" + " }" + " ]" + "}"; public static String userArn; public static void main(String[] args) throws Exception { final String usage = """ Usage: <username> <policyName> <roleName> <roleSessionName> <bucketName>\s Where: username - The name of the IAM user to create.\s policyName - The name of the policy to create.\s roleName - The name of the role to create.\s roleSessionName - The name of the session required for the assumeRole operation.\s bucketName - The name of the Amazon S3 bucket from which objects are read.\s """; if (args.length != 5) { System.out.println(usage); System.exit(1); } String userName = args[0]; String policyName = args[1]; String roleName = args[2]; String roleSessionName = args[3]; String bucketName = args[4]; Region region = Region.AWS_GLOBAL; IamClient iam = IamClient.builder() .region(region) .build(); System.out.println(DASHES); System.out.println("Welcome to the AWS IAM example scenario."); System.out.println(DASHES); System.out.println(DASHES); System.out.println(" 1. Create the IAM user."); User createUser = createIAMUser(iam, userName); System.out.println(DASHES); userArn = createUser.arn(); AccessKey myKey = createIAMAccessKey(iam, userName); String accessKey = myKey.accessKeyId(); String secretKey = myKey.secretAccessKey(); String assumeRolePolicyDocument = "{" + "\"Version\": \"2012-10-17\"," + "\"Statement\": [{" + "\"Effect\": \"Allow\"," + "\"Principal\": {" + " \"AWS\": \"" + userArn + "\"" + "}," + "\"Action\": \"sts:AssumeRole\"" + "}]" + "}"; System.out.println(assumeRolePolicyDocument); System.out.println(userName + " was successfully created."); System.out.println(DASHES); System.out.println("2. Creates a policy."); String polArn = createIAMPolicy(iam, policyName); System.out.println("The policy " + polArn + " was successfully created."); System.out.println(DASHES); System.out.println(DASHES); System.out.println("3. Creates a role."); TimeUnit.SECONDS.sleep(30); String roleArn = createIAMRole(iam, roleName, assumeRolePolicyDocument); System.out.println(roleArn + " was successfully created."); System.out.println(DASHES); System.out.println(DASHES); System.out.println("4. Grants the user permissions."); attachIAMRolePolicy(iam, roleName, polArn); System.out.println(DASHES); System.out.println(DASHES); System.out.println("*** Wait for 30 secs so the resource is available"); TimeUnit.SECONDS.sleep(30); System.out.println("5. Gets temporary credentials by assuming the role."); System.out.println("Perform an Amazon S3 Service operation using the temporary credentials."); assumeRole(roleArn, roleSessionName, bucketName, accessKey, secretKey); System.out.println(DASHES); System.out.println(DASHES); System.out.println("6 Getting ready to delete the AWS resources"); deleteKey(iam, userName, accessKey); deleteRole(iam, roleName, polArn); deleteIAMUser(iam, userName); System.out.println(DASHES); System.out.println(DASHES); System.out.println("This IAM Scenario has successfully completed"); System.out.println(DASHES); } public static AccessKey createIAMAccessKey(IamClient iam, String user) { try { CreateAccessKeyRequest request = CreateAccessKeyRequest.builder() .userName(user) .build(); CreateAccessKeyResponse response = iam.createAccessKey(request); return response.accessKey(); } catch (IamException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } return null; } public static User createIAMUser(IamClient iam, String username) { try { // Create an IamWaiter object IamWaiter iamWaiter = iam.waiter(); CreateUserRequest request = CreateUserRequest.builder() .userName(username) .build(); // Wait until the user is created. CreateUserResponse response = iam.createUser(request); GetUserRequest userRequest = GetUserRequest.builder() .userName(response.user().userName()) .build(); WaiterResponse<GetUserResponse> waitUntilUserExists = iamWaiter.waitUntilUserExists(userRequest); waitUntilUserExists.matched().response().ifPresent(System.out::println); return response.user(); } catch (IamException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } return null; } public static String createIAMRole(IamClient iam, String rolename, String json) { try { CreateRoleRequest request = CreateRoleRequest.builder() .roleName(rolename) .assumeRolePolicyDocument(json) .description("Created using the AWS SDK for Java") .build(); CreateRoleResponse response = iam.createRole(request); System.out.println("The ARN of the role is " + response.role().arn()); return response.role().arn(); } catch (IamException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } return ""; } public static String createIAMPolicy(IamClient iam, String policyName) { try { // Create an IamWaiter object. IamWaiter iamWaiter = iam.waiter(); CreatePolicyRequest request = CreatePolicyRequest.builder() .policyName(policyName) .policyDocument(PolicyDocument).build(); CreatePolicyResponse response = iam.createPolicy(request); GetPolicyRequest polRequest = GetPolicyRequest.builder() .policyArn(response.policy().arn()) .build(); WaiterResponse<GetPolicyResponse> waitUntilPolicyExists = iamWaiter.waitUntilPolicyExists(polRequest); waitUntilPolicyExists.matched().response().ifPresent(System.out::println); return response.policy().arn(); } catch (IamException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } return ""; } public static void attachIAMRolePolicy(IamClient iam, String roleName, String policyArn) { try { ListAttachedRolePoliciesRequest request = ListAttachedRolePoliciesRequest.builder() .roleName(roleName) .build(); ListAttachedRolePoliciesResponse response = iam.listAttachedRolePolicies(request); List<AttachedPolicy> attachedPolicies = response.attachedPolicies(); String polArn; for (AttachedPolicy policy : attachedPolicies) { polArn = policy.policyArn(); if (polArn.compareTo(policyArn) == 0) { System.out.println(roleName + " policy is already attached to this role."); return; } } AttachRolePolicyRequest attachRequest = AttachRolePolicyRequest.builder() .roleName(roleName) .policyArn(policyArn) .build(); iam.attachRolePolicy(attachRequest); System.out.println("Successfully attached policy " + policyArn + " to role " + roleName); } catch (IamException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } } // Invoke an Amazon S3 operation using the Assumed Role. public static void assumeRole(String roleArn, String roleSessionName, String bucketName, String keyVal, String keySecret) { // Use the creds of the new IAM user that was created in this code example. AwsBasicCredentials credentials = AwsBasicCredentials.create(keyVal, keySecret); StsClient stsClient = StsClient.builder() .region(Region.US_EAST_1) .credentialsProvider(StaticCredentialsProvider.create(credentials)) .build(); try { AssumeRoleRequest roleRequest = AssumeRoleRequest.builder() .roleArn(roleArn) .roleSessionName(roleSessionName) .build(); AssumeRoleResponse roleResponse = stsClient.assumeRole(roleRequest); Credentials myCreds = roleResponse.credentials(); String key = myCreds.accessKeyId(); String secKey = myCreds.secretAccessKey(); String secToken = myCreds.sessionToken(); // List all objects in an Amazon S3 bucket using the temp creds retrieved by // invoking assumeRole. Region region = Region.US_EAST_1; S3Client s3 = S3Client.builder() .credentialsProvider( StaticCredentialsProvider.create(AwsSessionCredentials.create(key, secKey, secToken))) .region(region) .build(); System.out.println("Created a S3Client using temp credentials."); System.out.println("Listing objects in " + bucketName); ListObjectsRequest listObjects = ListObjectsRequest.builder() .bucket(bucketName) .build(); ListObjectsResponse res = s3.listObjects(listObjects); List<S3Object> objects = res.contents(); for (S3Object myValue : objects) { System.out.println("The name of the key is " + myValue.key()); System.out.println("The owner is " + myValue.owner()); } } catch (StsException e) { System.err.println(e.getMessage()); System.exit(1); } } public static void deleteRole(IamClient iam, String roleName, String polArn) { try { // First the policy needs to be detached. DetachRolePolicyRequest rolePolicyRequest = DetachRolePolicyRequest.builder() .policyArn(polArn) .roleName(roleName) .build(); iam.detachRolePolicy(rolePolicyRequest); // Delete the policy. DeletePolicyRequest request = DeletePolicyRequest.builder() .policyArn(polArn) .build(); iam.deletePolicy(request); System.out.println("*** Successfully deleted " + polArn); // Delete the role. DeleteRoleRequest roleRequest = DeleteRoleRequest.builder() .roleName(roleName) .build(); iam.deleteRole(roleRequest); System.out.println("*** Successfully deleted " + roleName); } catch (IamException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } } public static void deleteKey(IamClient iam, String username, String accessKey) { try { DeleteAccessKeyRequest request = DeleteAccessKeyRequest.builder() .accessKeyId(accessKey) .userName(username) .build(); iam.deleteAccessKey(request); System.out.println("Successfully deleted access key " + accessKey + " from user " + username); } catch (IamException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } } public static void deleteIAMUser(IamClient iam, String userName) { try { DeleteUserRequest request = DeleteUserRequest.builder() .userName(userName) .build(); iam.deleteUser(request); System.out.println("*** Successfully deleted " + userName); } catch (IamException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } } }

Actions

The following code example shows how to use AttachRolePolicy.

SDK for Java 2.x
Note

There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository.

import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.iam.IamClient; import software.amazon.awssdk.services.iam.model.IamException; import software.amazon.awssdk.services.iam.model.AttachRolePolicyRequest; import software.amazon.awssdk.services.iam.model.AttachedPolicy; import software.amazon.awssdk.services.iam.model.ListAttachedRolePoliciesRequest; import software.amazon.awssdk.services.iam.model.ListAttachedRolePoliciesResponse; import java.util.List; /** * Before running this Java V2 code example, set up your development * environment, including your credentials. * * For more information, see the following documentation topic: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html */ public class AttachRolePolicy { public static void main(String[] args) { final String usage = """ Usage: <roleName> <policyArn>\s Where: roleName - A role name that you can obtain from the AWS Management Console.\s policyArn - A policy ARN that you can obtain from the AWS Management Console.\s """; if (args.length != 2) { System.out.println(usage); System.exit(1); } String roleName = args[0]; String policyArn = args[1]; Region region = Region.AWS_GLOBAL; IamClient iam = IamClient.builder() .region(region) .build(); attachIAMRolePolicy(iam, roleName, policyArn); iam.close(); } public static void attachIAMRolePolicy(IamClient iam, String roleName, String policyArn) { try { ListAttachedRolePoliciesRequest request = ListAttachedRolePoliciesRequest.builder() .roleName(roleName) .build(); ListAttachedRolePoliciesResponse response = iam.listAttachedRolePolicies(request); List<AttachedPolicy> attachedPolicies = response.attachedPolicies(); // Ensure that the policy is not attached to this role String polArn = ""; for (AttachedPolicy policy : attachedPolicies) { polArn = policy.policyArn(); if (polArn.compareTo(policyArn) == 0) { System.out.println(roleName + " policy is already attached to this role."); return; } } AttachRolePolicyRequest attachRequest = AttachRolePolicyRequest.builder() .roleName(roleName) .policyArn(policyArn) .build(); iam.attachRolePolicy(attachRequest); System.out.println("Successfully attached policy " + policyArn + " to role " + roleName); } catch (IamException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } System.out.println("Done"); } }

The following code example shows how to use CreateAccessKey.

SDK for Java 2.x
Note

There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository.

import software.amazon.awssdk.services.iam.model.CreateAccessKeyRequest; import software.amazon.awssdk.services.iam.model.CreateAccessKeyResponse; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.iam.IamClient; import software.amazon.awssdk.services.iam.model.IamException; /** * Before running this Java V2 code example, set up your development * environment, including your credentials. * * For more information, see the following documentation topic: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html */ public class CreateAccessKey { public static void main(String[] args) { final String usage = """ Usage: <user>\s Where: user - An AWS IAM user that you can obtain from the AWS Management Console. """; if (args.length != 1) { System.out.println(usage); System.exit(1); } String user = args[0]; Region region = Region.AWS_GLOBAL; IamClient iam = IamClient.builder() .region(region) .build(); String keyId = createIAMAccessKey(iam, user); System.out.println("The Key Id is " + keyId); iam.close(); } public static String createIAMAccessKey(IamClient iam, String user) { try { CreateAccessKeyRequest request = CreateAccessKeyRequest.builder() .userName(user) .build(); CreateAccessKeyResponse response = iam.createAccessKey(request); return response.accessKey().accessKeyId(); } catch (IamException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } return ""; } }
  • For API details, see CreateAccessKey in AWS SDK for Java 2.x API Reference.

The following code example shows how to use CreateAccountAlias.

SDK for Java 2.x
Note

There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository.

import software.amazon.awssdk.services.iam.model.CreateAccountAliasRequest; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.iam.IamClient; import software.amazon.awssdk.services.iam.model.IamException; /** * Before running this Java V2 code example, set up your development * environment, including your credentials. * * For more information, see the following documentation topic: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html */ public class CreateAccountAlias { public static void main(String[] args) { final String usage = """ Usage: <alias>\s Where: alias - The account alias to create (for example, myawsaccount).\s """; if (args.length != 1) { System.out.println(usage); System.exit(1); } String alias = args[0]; Region region = Region.AWS_GLOBAL; IamClient iam = IamClient.builder() .region(region) .build(); createIAMAccountAlias(iam, alias); iam.close(); System.out.println("Done"); } public static void createIAMAccountAlias(IamClient iam, String alias) { try { CreateAccountAliasRequest request = CreateAccountAliasRequest.builder() .accountAlias(alias) .build(); iam.createAccountAlias(request); System.out.println("Successfully created account alias: " + alias); } catch (IamException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } } }

The following code example shows how to use CreatePolicy.

SDK for Java 2.x
Note

There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository.

import software.amazon.awssdk.core.waiters.WaiterResponse; import software.amazon.awssdk.services.iam.model.CreatePolicyRequest; import software.amazon.awssdk.services.iam.model.CreatePolicyResponse; import software.amazon.awssdk.services.iam.model.GetPolicyRequest; import software.amazon.awssdk.services.iam.model.GetPolicyResponse; import software.amazon.awssdk.services.iam.model.IamException; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.iam.IamClient; import software.amazon.awssdk.services.iam.waiters.IamWaiter; /** * Before running this Java V2 code example, set up your development * environment, including your credentials. * * For more information, see the following documentation topic: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html */ public class CreatePolicy { public static final String PolicyDocument = "{" + " \"Version\": \"2012-10-17\"," + " \"Statement\": [" + " {" + " \"Effect\": \"Allow\"," + " \"Action\": [" + " \"dynamodb:DeleteItem\"," + " \"dynamodb:GetItem\"," + " \"dynamodb:PutItem\"," + " \"dynamodb:Scan\"," + " \"dynamodb:UpdateItem\"" + " ]," + " \"Resource\": \"*\"" + " }" + " ]" + "}"; public static void main(String[] args) { final String usage = """ Usage: CreatePolicy <policyName>\s Where: policyName - A unique policy name.\s """; if (args.length != 1) { System.out.println(usage); System.exit(1); } String policyName = args[0]; Region region = Region.AWS_GLOBAL; IamClient iam = IamClient.builder() .region(region) .build(); String result = createIAMPolicy(iam, policyName); System.out.println("Successfully created a policy with this ARN value: " + result); iam.close(); } public static String createIAMPolicy(IamClient iam, String policyName) { try { // Create an IamWaiter object. IamWaiter iamWaiter = iam.waiter(); CreatePolicyRequest request = CreatePolicyRequest.builder() .policyName(policyName) .policyDocument(PolicyDocument) .build(); CreatePolicyResponse response = iam.createPolicy(request); // Wait until the policy is created. GetPolicyRequest polRequest = GetPolicyRequest.builder() .policyArn(response.policy().arn()) .build(); WaiterResponse<GetPolicyResponse> waitUntilPolicyExists = iamWaiter.waitUntilPolicyExists(polRequest); waitUntilPolicyExists.matched().response().ifPresent(System.out::println); return response.policy().arn(); } catch (IamException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } return ""; } }
  • For API details, see CreatePolicy in AWS SDK for Java 2.x API Reference.

The following code example shows how to use CreateRole.

SDK for Java 2.x
Note

There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository.

import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import software.amazon.awssdk.services.iam.model.CreateRoleRequest; import software.amazon.awssdk.services.iam.model.CreateRoleResponse; import software.amazon.awssdk.services.iam.model.IamException; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.iam.IamClient; import java.io.FileReader; /* * This example requires a trust policy document. For more information, see: * https://aws.amazon.com/blogs/security/how-to-use-trust-policies-with-iam-roles/ * * * In addition, set up your development environment, including your credentials. * * For information, see this documentation topic: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html */ public class CreateRole { public static void main(String[] args) throws Exception { final String usage = """ Usage: <rolename> <fileLocation>\s Where: rolename - The name of the role to create.\s fileLocation - The location of the JSON document that represents the trust policy.\s """; if (args.length != 2) { System.out.println(usage); System.exit(1); } String rolename = args[0]; String fileLocation = args[1]; Region region = Region.AWS_GLOBAL; IamClient iam = IamClient.builder() .region(region) .build(); String result = createIAMRole(iam, rolename, fileLocation); System.out.println("Successfully created user: " + result); iam.close(); } public static String createIAMRole(IamClient iam, String rolename, String fileLocation) throws Exception { try { JSONObject jsonObject = (JSONObject) readJsonSimpleDemo(fileLocation); CreateRoleRequest request = CreateRoleRequest.builder() .roleName(rolename) .assumeRolePolicyDocument(jsonObject.toJSONString()) .description("Created using the AWS SDK for Java") .build(); CreateRoleResponse response = iam.createRole(request); System.out.println("The ARN of the role is " + response.role().arn()); } catch (IamException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } return ""; } public static Object readJsonSimpleDemo(String filename) throws Exception { FileReader reader = new FileReader(filename); JSONParser jsonParser = new JSONParser(); return jsonParser.parse(reader); } }
  • For API details, see CreateRole in AWS SDK for Java 2.x API Reference.

The following code example shows how to use CreateUser.

SDK for Java 2.x
Note

There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository.

import software.amazon.awssdk.core.waiters.WaiterResponse; import software.amazon.awssdk.services.iam.model.CreateUserRequest; import software.amazon.awssdk.services.iam.model.CreateUserResponse; import software.amazon.awssdk.services.iam.model.IamException; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.iam.IamClient; import software.amazon.awssdk.services.iam.waiters.IamWaiter; import software.amazon.awssdk.services.iam.model.GetUserRequest; import software.amazon.awssdk.services.iam.model.GetUserResponse; /** * Before running this Java V2 code example, set up your development * environment, including your credentials. * * For more information, see the following documentation topic: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html */ public class CreateUser { public static void main(String[] args) { final String usage = """ Usage: <username>\s Where: username - The name of the user to create.\s """; if (args.length != 1) { System.out.println(usage); System.exit(1); } String username = args[0]; Region region = Region.AWS_GLOBAL; IamClient iam = IamClient.builder() .region(region) .build(); String result = createIAMUser(iam, username); System.out.println("Successfully created user: " + result); iam.close(); } public static String createIAMUser(IamClient iam, String username) { try { // Create an IamWaiter object. IamWaiter iamWaiter = iam.waiter(); CreateUserRequest request = CreateUserRequest.builder() .userName(username) .build(); CreateUserResponse response = iam.createUser(request); // Wait until the user is created. GetUserRequest userRequest = GetUserRequest.builder() .userName(response.user().userName()) .build(); WaiterResponse<GetUserResponse> waitUntilUserExists = iamWaiter.waitUntilUserExists(userRequest); waitUntilUserExists.matched().response().ifPresent(System.out::println); return response.user().userName(); } catch (IamException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } return ""; } }
  • For API details, see CreateUser in AWS SDK for Java 2.x API Reference.

The following code example shows how to use DeleteAccessKey.

SDK for Java 2.x
Note

There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository.

import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.iam.IamClient; import software.amazon.awssdk.services.iam.model.DeleteAccessKeyRequest; import software.amazon.awssdk.services.iam.model.IamException; /** * Before running this Java V2 code example, set up your development * environment, including your credentials. * * For more information, see the following documentation topic: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html */ public class DeleteAccessKey { public static void main(String[] args) { final String usage = """ Usage: <username> <accessKey>\s Where: username - The name of the user.\s accessKey - The access key ID for the secret access key you want to delete.\s """; if (args.length != 2) { System.out.println(usage); System.exit(1); } String username = args[0]; String accessKey = args[1]; Region region = Region.AWS_GLOBAL; IamClient iam = IamClient.builder() .region(region) .build(); deleteKey(iam, username, accessKey); iam.close(); } public static void deleteKey(IamClient iam, String username, String accessKey) { try { DeleteAccessKeyRequest request = DeleteAccessKeyRequest.builder() .accessKeyId(accessKey) .userName(username) .build(); iam.deleteAccessKey(request); System.out.println("Successfully deleted access key " + accessKey + " from user " + username); } catch (IamException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } } }
  • For API details, see DeleteAccessKey in AWS SDK for Java 2.x API Reference.

The following code example shows how to use DeleteAccountAlias.

SDK for Java 2.x
Note

There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository.

import software.amazon.awssdk.services.iam.model.DeleteAccountAliasRequest; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.iam.IamClient; import software.amazon.awssdk.services.iam.model.IamException; /** * Before running this Java V2 code example, set up your development * environment, including your credentials. * * For more information, see the following documentation topic: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html */ public class DeleteAccountAlias { public static void main(String[] args) { final String usage = """ Usage: <alias>\s Where: alias - The account alias to delete.\s """; if (args.length != 1) { System.out.println(usage); System.exit(1); } String alias = args[0]; Region region = Region.AWS_GLOBAL; IamClient iam = IamClient.builder() .region(region) .build(); deleteIAMAccountAlias(iam, alias); iam.close(); } public static void deleteIAMAccountAlias(IamClient iam, String alias) { try { DeleteAccountAliasRequest request = DeleteAccountAliasRequest.builder() .accountAlias(alias) .build(); iam.deleteAccountAlias(request); System.out.println("Successfully deleted account alias " + alias); } catch (IamException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } System.out.println("Done"); } }

The following code example shows how to use DeletePolicy.

SDK for Java 2.x
Note

There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository.

import software.amazon.awssdk.services.iam.model.DeletePolicyRequest; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.iam.IamClient; import software.amazon.awssdk.services.iam.model.IamException; /** * Before running this Java V2 code example, set up your development * environment, including your credentials. * * For more information, see the following documentation topic: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html */ public class DeletePolicy { public static void main(String[] args) { final String usage = """ Usage: <policyARN>\s Where: policyARN - A policy ARN value to delete.\s """; if (args.length != 1) { System.out.println(usage); System.exit(1); } String policyARN = args[0]; Region region = Region.AWS_GLOBAL; IamClient iam = IamClient.builder() .region(region) .build(); deleteIAMPolicy(iam, policyARN); iam.close(); } public static void deleteIAMPolicy(IamClient iam, String policyARN) { try { DeletePolicyRequest request = DeletePolicyRequest.builder() .policyArn(policyARN) .build(); iam.deletePolicy(request); System.out.println("Successfully deleted the policy"); } catch (IamException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } System.out.println("Done"); } }
  • For API details, see DeletePolicy in AWS SDK for Java 2.x API Reference.

The following code example shows how to use DeleteUser.

SDK for Java 2.x
Note

There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository.

import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.iam.IamClient; import software.amazon.awssdk.services.iam.model.DeleteUserRequest; import software.amazon.awssdk.services.iam.model.IamException; /** * Before running this Java V2 code example, set up your development * environment, including your credentials. * * For more information, see the following documentation topic: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html */ public class DeleteUser { public static void main(String[] args) { final String usage = """ Usage: <userName>\s Where: userName - The name of the user to delete.\s """; if (args.length != 1) { System.out.println(usage); System.exit(1); } String userName = args[0]; Region region = Region.AWS_GLOBAL; IamClient iam = IamClient.builder() .region(region) .build(); deleteIAMUser(iam, userName); System.out.println("Done"); iam.close(); } public static void deleteIAMUser(IamClient iam, String userName) { try { DeleteUserRequest request = DeleteUserRequest.builder() .userName(userName) .build(); iam.deleteUser(request); System.out.println("Successfully deleted IAM user " + userName); } catch (IamException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } } }
  • For API details, see DeleteUser in AWS SDK for Java 2.x API Reference.

The following code example shows how to use DetachRolePolicy.

SDK for Java 2.x
Note

There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository.

import software.amazon.awssdk.services.iam.model.DetachRolePolicyRequest; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.iam.IamClient; import software.amazon.awssdk.services.iam.model.IamException; /** * Before running this Java V2 code example, set up your development * environment, including your credentials. * * For more information, see the following documentation topic: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html */ public class DetachRolePolicy { public static void main(String[] args) { final String usage = """ Usage: <roleName> <policyArn>\s Where: roleName - A role name that you can obtain from the AWS Management Console.\s policyArn - A policy ARN that you can obtain from the AWS Management Console.\s """; if (args.length != 2) { System.out.println(usage); System.exit(1); } String roleName = args[0]; String policyArn = args[1]; Region region = Region.AWS_GLOBAL; IamClient iam = IamClient.builder() .region(region) .build(); detachPolicy(iam, roleName, policyArn); System.out.println("Done"); iam.close(); } public static void detachPolicy(IamClient iam, String roleName, String policyArn) { try { DetachRolePolicyRequest request = DetachRolePolicyRequest.builder() .roleName(roleName) .policyArn(policyArn) .build(); iam.detachRolePolicy(request); System.out.println("Successfully detached policy " + policyArn + " from role " + roleName); } catch (IamException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } } }

The following code example shows how to use ListAccessKeys.

SDK for Java 2.x
Note

There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository.

import software.amazon.awssdk.services.iam.model.AccessKeyMetadata; import software.amazon.awssdk.services.iam.model.IamException; import software.amazon.awssdk.services.iam.model.ListAccessKeysRequest; import software.amazon.awssdk.services.iam.model.ListAccessKeysResponse; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.iam.IamClient; /** * Before running this Java V2 code example, set up your development * environment, including your credentials. * * For more information, see the following documentation topic: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html */ public class ListAccessKeys { public static void main(String[] args) { final String usage = """ Usage: <userName>\s Where: userName - The name of the user for which access keys are retrieved.\s """; if (args.length != 1) { System.out.println(usage); System.exit(1); } String userName = args[0]; Region region = Region.AWS_GLOBAL; IamClient iam = IamClient.builder() .region(region) .build(); listKeys(iam, userName); System.out.println("Done"); iam.close(); } public static void listKeys(IamClient iam, String userName) { try { boolean done = false; String newMarker = null; while (!done) { ListAccessKeysResponse response; if (newMarker == null) { ListAccessKeysRequest request = ListAccessKeysRequest.builder() .userName(userName) .build(); response = iam.listAccessKeys(request); } else { ListAccessKeysRequest request = ListAccessKeysRequest.builder() .userName(userName) .marker(newMarker) .build(); response = iam.listAccessKeys(request); } for (AccessKeyMetadata metadata : response.accessKeyMetadata()) { System.out.format("Retrieved access key %s", metadata.accessKeyId()); } if (!response.isTruncated()) { done = true; } else { newMarker = response.marker(); } } } catch (IamException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } } }
  • For API details, see ListAccessKeys in AWS SDK for Java 2.x API Reference.

The following code example shows how to use ListAccountAliases.

SDK for Java 2.x
Note

There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository.

import software.amazon.awssdk.services.iam.model.IamException; import software.amazon.awssdk.services.iam.model.ListAccountAliasesResponse; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.iam.IamClient; /** * Before running this Java V2 code example, set up your development * environment, including your credentials. * * For more information, see the following documentation topic: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html */ public class ListAccountAliases { public static void main(String[] args) { Region region = Region.AWS_GLOBAL; IamClient iam = IamClient.builder() .region(region) .build(); listAliases(iam); System.out.println("Done"); iam.close(); } public static void listAliases(IamClient iam) { try { ListAccountAliasesResponse response = iam.listAccountAliases(); for (String alias : response.accountAliases()) { System.out.printf("Retrieved account alias %s", alias); } } catch (IamException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } } }

The following code example shows how to use ListUsers.

SDK for Java 2.x
Note

There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository.

import software.amazon.awssdk.services.iam.model.AttachedPermissionsBoundary; import software.amazon.awssdk.services.iam.model.IamException; import software.amazon.awssdk.services.iam.model.ListUsersRequest; import software.amazon.awssdk.services.iam.model.ListUsersResponse; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.iam.IamClient; import software.amazon.awssdk.services.iam.model.User; /** * Before running this Java V2 code example, set up your development * environment, including your credentials. * * For more information, see the following documentation topic: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html */ public class ListUsers { public static void main(String[] args) { Region region = Region.AWS_GLOBAL; IamClient iam = IamClient.builder() .region(region) .build(); listAllUsers(iam); System.out.println("Done"); iam.close(); } public static void listAllUsers(IamClient iam) { try { boolean done = false; String newMarker = null; while (!done) { ListUsersResponse response; if (newMarker == null) { ListUsersRequest request = ListUsersRequest.builder().build(); response = iam.listUsers(request); } else { ListUsersRequest request = ListUsersRequest.builder() .marker(newMarker) .build(); response = iam.listUsers(request); } for (User user : response.users()) { System.out.format("\n Retrieved user %s", user.userName()); AttachedPermissionsBoundary permissionsBoundary = user.permissionsBoundary(); if (permissionsBoundary != null) System.out.format("\n Permissions boundary details %s", permissionsBoundary.permissionsBoundaryTypeAsString()); } if (!response.isTruncated()) { done = true; } else { newMarker = response.marker(); } } } catch (IamException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } } }
  • For API details, see ListUsers in AWS SDK for Java 2.x API Reference.

The following code example shows how to use UpdateAccessKey.

SDK for Java 2.x
Note

There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository.

import software.amazon.awssdk.services.iam.model.IamException; import software.amazon.awssdk.services.iam.model.StatusType; import software.amazon.awssdk.services.iam.model.UpdateAccessKeyRequest; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.iam.IamClient; /** * Before running this Java V2 code example, set up your development * environment, including your credentials. * * For more information, see the following documentation topic: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html */ public class UpdateAccessKey { private static StatusType statusType; public static void main(String[] args) { final String usage = """ Usage: <username> <accessId> <status>\s Where: username - The name of the user whose key you want to update.\s accessId - The access key ID of the secret access key you want to update.\s status - The status you want to assign to the secret access key.\s """; if (args.length != 3) { System.out.println(usage); System.exit(1); } String username = args[0]; String accessId = args[1]; String status = args[2]; Region region = Region.AWS_GLOBAL; IamClient iam = IamClient.builder() .region(region) .build(); updateKey(iam, username, accessId, status); System.out.println("Done"); iam.close(); } public static void updateKey(IamClient iam, String username, String accessId, String status) { try { if (status.toLowerCase().equalsIgnoreCase("active")) { statusType = StatusType.ACTIVE; } else if (status.toLowerCase().equalsIgnoreCase("inactive")) { statusType = StatusType.INACTIVE; } else { statusType = StatusType.UNKNOWN_TO_SDK_VERSION; } UpdateAccessKeyRequest request = UpdateAccessKeyRequest.builder() .accessKeyId(accessId) .userName(username) .status(statusType) .build(); iam.updateAccessKey(request); System.out.printf("Successfully updated the status of access key %s to" + "status %s for user %s", accessId, status, username); } catch (IamException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } } }
  • For API details, see UpdateAccessKey in AWS SDK for Java 2.x API Reference.

The following code example shows how to use UpdateUser.

SDK for Java 2.x
Note

There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository.

import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.iam.IamClient; import software.amazon.awssdk.services.iam.model.IamException; import software.amazon.awssdk.services.iam.model.UpdateUserRequest; /** * Before running this Java V2 code example, set up your development * environment, including your credentials. * * For more information, see the following documentation topic: * * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html */ public class UpdateUser { public static void main(String[] args) { final String usage = """ Usage: <curName> <newName>\s Where: curName - The current user name.\s newName - An updated user name.\s """; if (args.length != 2) { System.out.println(usage); System.exit(1); } String curName = args[0]; String newName = args[1]; Region region = Region.AWS_GLOBAL; IamClient iam = IamClient.builder() .region(region) .build(); updateIAMUser(iam, curName, newName); System.out.println("Done"); iam.close(); } public static void updateIAMUser(IamClient iam, String curName, String newName) { try { UpdateUserRequest request = UpdateUserRequest.builder() .userName(curName) .newUserName(newName) .build(); iam.updateUser(request); System.out.printf("Successfully updated user to username %s", newName); } catch (IamException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } } }
  • For API details, see UpdateUser in AWS SDK for Java 2.x API Reference.

Scenarios

The following code example shows how to create a load-balanced web service that returns book, movie, and song recommendations. The example shows how the service responds to failures, and how to restructure the service for more resilience when failures occur.

  • Use an Amazon EC2 Auto Scaling group to create Amazon Elastic Compute Cloud (Amazon EC2) instances based on a launch template and to keep the number of instances in a specified range.

  • Handle and distribute HTTP requests with Elastic Load Balancing.

  • Monitor the health of instances in an Auto Scaling group and forward requests only to healthy instances.

  • Run a Python web server on each EC2 instance to handle HTTP requests. The web server responds with recommendations and health checks.

  • Simulate a recommendation service with an Amazon DynamoDB table.

  • Control web server response to requests and health checks by updating AWS Systems Manager parameters.

SDK for Java 2.x
Note

There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository.

Run the interactive scenario at a command prompt.

public class Main { public static final String fileName = "C:\\AWS\\resworkflow\\recommendations.json"; // Modify file location. public static final String tableName = "doc-example-recommendation-service"; public static final String startScript = "C:\\AWS\\resworkflow\\server_startup_script.sh"; // Modify file location. public static final String policyFile = "C:\\AWS\\resworkflow\\instance_policy.json"; // Modify file location. public static final String ssmJSON = "C:\\AWS\\resworkflow\\ssm_only_policy.json"; // Modify file location. public static final String failureResponse = "doc-example-resilient-architecture-failure-response"; public static final String healthCheck = "doc-example-resilient-architecture-health-check"; public static final String templateName = "doc-example-resilience-template"; public static final String roleName = "doc-example-resilience-role"; public static final String policyName = "doc-example-resilience-pol"; public static final String profileName = "doc-example-resilience-prof"; public static final String badCredsProfileName = "doc-example-resilience-prof-bc"; public static final String targetGroupName = "doc-example-resilience-tg"; public static final String autoScalingGroupName = "doc-example-resilience-group"; public static final String lbName = "doc-example-resilience-lb"; public static final String protocol = "HTTP"; public static final int port = 80; public static final String DASHES = new String(new char[80]).replace("\0", "-"); public static void main(String[] args) throws IOException, InterruptedException { Scanner in = new Scanner(System.in); Database database = new Database(); AutoScaler autoScaler = new AutoScaler(); LoadBalancer loadBalancer = new LoadBalancer(); System.out.println(DASHES); System.out.println("Welcome to the demonstration of How to Build and Manage a Resilient Service!"); System.out.println(DASHES); System.out.println(DASHES); System.out.println("A - SETUP THE RESOURCES"); System.out.println("Press Enter when you're ready to start deploying resources."); in.nextLine(); deploy(loadBalancer); System.out.println(DASHES); System.out.println(DASHES); System.out.println("B - DEMO THE RESILIENCE FUNCTIONALITY"); System.out.println("Press Enter when you're ready."); in.nextLine(); demo(loadBalancer); System.out.println(DASHES); System.out.println(DASHES); System.out.println("C - DELETE THE RESOURCES"); System.out.println(""" This concludes the demo of how to build and manage a resilient service. To keep things tidy and to avoid unwanted charges on your account, we can clean up all AWS resources that were created for this demo. """); System.out.println("\n Do you want to delete the resources (y/n)? "); String userInput = in.nextLine().trim().toLowerCase(); // Capture user input if (userInput.equals("y")) { // Delete resources here deleteResources(loadBalancer, autoScaler, database); System.out.println("Resources deleted."); } else { System.out.println(""" Okay, we'll leave the resources intact. Don't forget to delete them when you're done with them or you might incur unexpected charges. """); } System.out.println(DASHES); System.out.println(DASHES); System.out.println("The example has completed. "); System.out.println("\n Thanks for watching!"); System.out.println(DASHES); } // Deletes the AWS resources used in this example. private static void deleteResources(LoadBalancer loadBalancer, AutoScaler autoScaler, Database database) throws IOException, InterruptedException { loadBalancer.deleteLoadBalancer(lbName); System.out.println("*** Wait 30 secs for resource to be deleted"); TimeUnit.SECONDS.sleep(30); loadBalancer.deleteTargetGroup(targetGroupName); autoScaler.deleteAutoScaleGroup(autoScalingGroupName); autoScaler.deleteRolesPolicies(policyName, roleName, profileName); autoScaler.deleteTemplate(templateName); database.deleteTable(tableName); } private static void deploy(LoadBalancer loadBalancer) throws InterruptedException, IOException { Scanner in = new Scanner(System.in); System.out.println( """ For this demo, we'll use the AWS SDK for Java (v2) to create several AWS resources to set up a load-balanced web service endpoint and explore some ways to make it resilient against various kinds of failures. Some of the resources create by this demo are: \t* A DynamoDB table that the web service depends on to provide book, movie, and song recommendations. \t* An EC2 launch template that defines EC2 instances that each contain a Python web server. \t* An EC2 Auto Scaling group that manages EC2 instances across several Availability Zones. \t* An Elastic Load Balancing (ELB) load balancer that targets the Auto Scaling group to distribute requests. """); System.out.println("Press Enter when you're ready."); in.nextLine(); System.out.println(DASHES); System.out.println(DASHES); System.out.println("Creating and populating a DynamoDB table named " + tableName); Database database = new Database(); database.createTable(tableName, fileName); System.out.println(DASHES); System.out.println(DASHES); System.out.println(""" Creating an EC2 launch template that runs '{startup_script}' when an instance starts. This script starts a Python web server defined in the `server.py` script. The web server listens to HTTP requests on port 80 and responds to requests to '/' and to '/healthcheck'. For demo purposes, this server is run as the root user. In production, the best practice is to run a web server, such as Apache, with least-privileged credentials. The template also defines an IAM policy that each instance uses to assume a role that grants permissions to access the DynamoDB recommendation table and Systems Manager parameters that control the flow of the demo. """); LaunchTemplateCreator templateCreator = new LaunchTemplateCreator(); templateCreator.createTemplate(policyFile, policyName, profileName, startScript, templateName, roleName); System.out.println(DASHES); System.out.println(DASHES); System.out.println( "Creating an EC2 Auto Scaling group that maintains three EC2 instances, each in a different Availability Zone."); System.out.println("*** Wait 30 secs for the VPC to be created"); TimeUnit.SECONDS.sleep(30); AutoScaler autoScaler = new AutoScaler(); String[] zones = autoScaler.createGroup(3, templateName, autoScalingGroupName); System.out.println(""" At this point, you have EC2 instances created. Once each instance starts, it listens for HTTP requests. You can see these instances in the console or continue with the demo. Press Enter when you're ready to continue. """); in.nextLine(); System.out.println(DASHES); System.out.println(DASHES); System.out.println("Creating variables that control the flow of the demo."); ParameterHelper paramHelper = new ParameterHelper(); paramHelper.reset(); System.out.println(DASHES); System.out.println(DASHES); System.out.println(""" Creating an Elastic Load Balancing target group and load balancer. The target group defines how the load balancer connects to instances. The load balancer provides a single endpoint where clients connect and dispatches requests to instances in the group. """); String vpcId = autoScaler.getDefaultVPC(); List<Subnet> subnets = autoScaler.getSubnets(vpcId, zones); System.out.println("You have retrieved a list with " + subnets.size() + " subnets"); String targetGroupArn = loadBalancer.createTargetGroup(protocol, port, vpcId, targetGroupName); String elbDnsName = loadBalancer.createLoadBalancer(subnets, targetGroupArn, lbName, port, protocol); autoScaler.attachLoadBalancerTargetGroup(autoScalingGroupName, targetGroupArn); System.out.println("Verifying access to the load balancer endpoint..."); boolean wasSuccessul = loadBalancer.verifyLoadBalancerEndpoint(elbDnsName); if (!wasSuccessul) { System.out.println("Couldn't connect to the load balancer, verifying that the port is open..."); CloseableHttpClient httpClient = HttpClients.createDefault(); // Create an HTTP GET request to "http://checkip.amazonaws.com" HttpGet httpGet = new HttpGet("http://checkip.amazonaws.com"); try { // Execute the request and get the response HttpResponse response = httpClient.execute(httpGet); // Read the response content. String ipAddress = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8).trim(); // Print the public IP address. System.out.println("Public IP Address: " + ipAddress); GroupInfo groupInfo = autoScaler.verifyInboundPort(vpcId, port, ipAddress); if (!groupInfo.isPortOpen()) { System.out.println(""" For this example to work, the default security group for your default VPC must allow access from this computer. You can either add it automatically from this example or add it yourself using the AWS Management Console. """); System.out.println( "Do you want to add a rule to security group " + groupInfo.getGroupName() + " to allow"); System.out.println("inbound traffic on port " + port + " from your computer's IP address (y/n) "); String ans = in.nextLine(); if ("y".equalsIgnoreCase(ans)) { autoScaler.openInboundPort(groupInfo.getGroupName(), String.valueOf(port), ipAddress); System.out.println("Security group rule added."); } else { System.out.println("No security group rule added."); } } } catch (AutoScalingException e) { e.printStackTrace(); } } else if (wasSuccessul) { System.out.println("Your load balancer is ready. You can access it by browsing to:"); System.out.println("\t http://" + elbDnsName); } else { System.out.println("Couldn't get a successful response from the load balancer endpoint. Troubleshoot by"); System.out.println("manually verifying that your VPC and security group are configured correctly and that"); System.out.println("you can successfully make a GET request to the load balancer."); } System.out.println("Press Enter when you're ready to continue with the demo."); in.nextLine(); } // A method that controls the demo part of the Java program. public static void demo(LoadBalancer loadBalancer) throws IOException, InterruptedException { ParameterHelper paramHelper = new ParameterHelper(); System.out.println("Read the ssm_only_policy.json file"); String ssmOnlyPolicy = readFileAsString(ssmJSON); System.out.println("Resetting parameters to starting values for demo."); paramHelper.reset(); System.out.println( """ This part of the demonstration shows how to toggle different parts of the system to create situations where the web service fails, and shows how using a resilient architecture can keep the web service running in spite of these failures. At the start, the load balancer endpoint returns recommendations and reports that all targets are healthy. """); demoChoices(loadBalancer); System.out.println( """ The web service running on the EC2 instances gets recommendations by querying a DynamoDB table. The table name is contained in a Systems Manager parameter named self.param_helper.table. To simulate a failure of the recommendation service, let's set this parameter to name a non-existent table. """); paramHelper.put(paramHelper.tableName, "this-is-not-a-table"); System.out.println( """ \nNow, sending a GET request to the load balancer endpoint returns a failure code. But, the service reports as healthy to the load balancer because shallow health checks don't check for failure of the recommendation service. """); demoChoices(loadBalancer); System.out.println( """ Instead of failing when the recommendation service fails, the web service can return a static response. While this is not a perfect solution, it presents the customer with a somewhat better experience than failure. """); paramHelper.put(paramHelper.failureResponse, "static"); System.out.println(""" Now, sending a GET request to the load balancer endpoint returns a static response. The service still reports as healthy because health checks are still shallow. """); demoChoices(loadBalancer); System.out.println("Let's reinstate the recommendation service."); paramHelper.put(paramHelper.tableName, paramHelper.dyntable); System.out.println(""" Let's also substitute bad credentials for one of the instances in the target group so that it can't access the DynamoDB recommendation table. We will get an instance id value. """); LaunchTemplateCreator templateCreator = new LaunchTemplateCreator(); AutoScaler autoScaler = new AutoScaler(); // Create a new instance profile based on badCredsProfileName. templateCreator.createInstanceProfile(policyFile, policyName, badCredsProfileName, roleName); String badInstanceId = autoScaler.getBadInstance(autoScalingGroupName); System.out.println("The bad instance id values used for this demo is " + badInstanceId); String profileAssociationId = autoScaler.getInstanceProfile(badInstanceId); System.out.println("The association Id value is " + profileAssociationId); System.out.println("Replacing the profile for instance " + badInstanceId + " with a profile that contains bad credentials"); autoScaler.replaceInstanceProfile(badInstanceId, badCredsProfileName, profileAssociationId); System.out.println( """ Now, sending a GET request to the load balancer endpoint returns either a recommendation or a static response, depending on which instance is selected by the load balancer. """); demoChoices(loadBalancer); System.out.println(""" Let's implement a deep health check. For this demo, a deep health check tests whether the web service can access the DynamoDB table that it depends on for recommendations. Note that the deep health check is only for ELB routing and not for Auto Scaling instance health. This kind of deep health check is not recommended for Auto Scaling instance health, because it risks accidental termination of all instances in the Auto Scaling group when a dependent service fails. """); System.out.println(""" By implementing deep health checks, the load balancer can detect when one of the instances is failing and take that instance out of rotation. """); paramHelper.put(paramHelper.healthCheck, "deep"); System.out.println(""" Now, checking target health indicates that the instance with bad credentials is unhealthy. Note that it might take a minute or two for the load balancer to detect the unhealthy instance. Sending a GET request to the load balancer endpoint always returns a recommendation, because the load balancer takes unhealthy instances out of its rotation. """); demoChoices(loadBalancer); System.out.println( """ Because the instances in this demo are controlled by an auto scaler, the simplest way to fix an unhealthy instance is to terminate it and let the auto scaler start a new instance to replace it. """); autoScaler.terminateInstance(badInstanceId); System.out.println(""" Even while the instance is terminating and the new instance is starting, sending a GET request to the web service continues to get a successful recommendation response because the load balancer routes requests to the healthy instances. After the replacement instance starts and reports as healthy, it is included in the load balancing rotation. Note that terminating and replacing an instance typically takes several minutes, during which time you can see the changing health check status until the new instance is running and healthy. """); demoChoices(loadBalancer); System.out.println( "If the recommendation service fails now, deep health checks mean all instances report as unhealthy."); paramHelper.put(paramHelper.tableName, "this-is-not-a-table"); demoChoices(loadBalancer); paramHelper.reset(); } public static void demoChoices(LoadBalancer loadBalancer) throws IOException, InterruptedException { String[] actions = { "Send a GET request to the load balancer endpoint.", "Check the health of load balancer targets.", "Go to the next part of the demo." }; Scanner scanner = new Scanner(System.in); while (true) { System.out.println("-".repeat(88)); System.out.println("See the current state of the service by selecting one of the following choices:"); for (int i = 0; i < actions.length; i++) { System.out.println(i + ": " + actions[i]); } try { System.out.print("\nWhich action would you like to take? "); int choice = scanner.nextInt(); System.out.println("-".repeat(88)); switch (choice) { case 0 -> { System.out.println("Request:\n"); System.out.println("GET http://" + loadBalancer.getEndpoint(lbName)); CloseableHttpClient httpClient = HttpClients.createDefault(); // Create an HTTP GET request to the ELB. HttpGet httpGet = new HttpGet("http://" + loadBalancer.getEndpoint(lbName)); // Execute the request and get the response. HttpResponse response = httpClient.execute(httpGet); int statusCode = response.getStatusLine().getStatusCode(); System.out.println("HTTP Status Code: " + statusCode); // Display the JSON response BufferedReader reader = new BufferedReader( new InputStreamReader(response.getEntity().getContent())); StringBuilder jsonResponse = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { jsonResponse.append(line); } reader.close(); // Print the formatted JSON response. System.out.println("Full Response:\n"); System.out.println(jsonResponse.toString()); // Close the HTTP client. httpClient.close(); } case 1 -> { System.out.println("\nChecking the health of load balancer targets:\n"); List<TargetHealthDescription> health = loadBalancer.checkTargetHealth(targetGroupName); for (TargetHealthDescription target : health) { System.out.printf("\tTarget %s on port %d is %s%n", target.target().id(), target.target().port(), target.targetHealth().stateAsString()); } System.out.println(""" Note that it can take a minute or two for the health check to update after changes are made. """); } case 2 -> { System.out.println("\nOkay, let's move on."); System.out.println("-".repeat(88)); return; // Exit the method when choice is 2 } default -> System.out.println("You must choose a value between 0-2. Please select again."); } } catch (java.util.InputMismatchException e) { System.out.println("Invalid input. Please select again."); scanner.nextLine(); // Clear the input buffer. } } } public static String readFileAsString(String filePath) throws IOException { byte[] bytes = Files.readAllBytes(Paths.get(filePath)); return new String(bytes); } }

Create a class that wraps Auto Scaling and Amazon EC2 actions.

public class AutoScaler { private static Ec2Client ec2Client; private static AutoScalingClient autoScalingClient; private static IamClient iamClient; private static SsmClient ssmClient; private IamClient getIAMClient() { if (iamClient == null) { iamClient = IamClient.builder() .region(Region.US_EAST_1) .build(); } return iamClient; } private SsmClient getSSMClient() { if (ssmClient == null) { ssmClient = SsmClient.builder() .region(Region.US_EAST_1) .build(); } return ssmClient; } private Ec2Client getEc2Client() { if (ec2Client == null) { ec2Client = Ec2Client.builder() .region(Region.US_EAST_1) .build(); } return ec2Client; } private AutoScalingClient getAutoScalingClient() { if (autoScalingClient == null) { autoScalingClient = AutoScalingClient.builder() .region(Region.US_EAST_1) .build(); } return autoScalingClient; } /** * Terminates and instances in an EC2 Auto Scaling group. After an instance is * terminated, it can no longer be accessed. */ public void terminateInstance(String instanceId) { TerminateInstanceInAutoScalingGroupRequest terminateInstanceIRequest = TerminateInstanceInAutoScalingGroupRequest .builder() .instanceId(instanceId) .shouldDecrementDesiredCapacity(false) .build(); getAutoScalingClient().terminateInstanceInAutoScalingGroup(terminateInstanceIRequest); System.out.format("Terminated instance %s.", instanceId); } /** * Replaces the profile associated with a running instance. After the profile is * replaced, the instance is rebooted to ensure that it uses the new profile. * When * the instance is ready, Systems Manager is used to restart the Python web * server. */ public void replaceInstanceProfile(String instanceId, String newInstanceProfileName, String profileAssociationId) throws InterruptedException { // Create an IAM instance profile specification. software.amazon.awssdk.services.ec2.model.IamInstanceProfileSpecification iamInstanceProfile = software.amazon.awssdk.services.ec2.model.IamInstanceProfileSpecification .builder() .name(newInstanceProfileName) // Make sure 'newInstanceProfileName' is a valid IAM Instance Profile // name. .build(); // Replace the IAM instance profile association for the EC2 instance. ReplaceIamInstanceProfileAssociationRequest replaceRequest = ReplaceIamInstanceProfileAssociationRequest .builder() .iamInstanceProfile(iamInstanceProfile) .associationId(profileAssociationId) // Make sure 'profileAssociationId' is a valid association ID. .build(); try { getEc2Client().replaceIamInstanceProfileAssociation(replaceRequest); // Handle the response as needed. } catch (Ec2Exception e) { // Handle exceptions, log, or report the error. System.err.println("Error: " + e.getMessage()); } System.out.format("Replaced instance profile for association %s with profile %s.", profileAssociationId, newInstanceProfileName); TimeUnit.SECONDS.sleep(15); boolean instReady = false; int tries = 0; // Reboot after 60 seconds while (!instReady) { if (tries % 6 == 0) { getEc2Client().rebootInstances(RebootInstancesRequest.builder() .instanceIds(instanceId) .build()); System.out.println("Rebooting instance " + instanceId + " and waiting for it to be ready."); } tries++; try { TimeUnit.SECONDS.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } DescribeInstanceInformationResponse informationResponse = getSSMClient().describeInstanceInformation(); List<InstanceInformation> instanceInformationList = informationResponse.instanceInformationList(); for (InstanceInformation info : instanceInformationList) { if (info.instanceId().equals(instanceId)) { instReady = true; break; } } } SendCommandRequest sendCommandRequest = SendCommandRequest.builder() .instanceIds(instanceId) .documentName("AWS-RunShellScript") .parameters(Collections.singletonMap("commands", Collections.singletonList("cd / && sudo python3 server.py 80"))) .build(); getSSMClient().sendCommand(sendCommandRequest); System.out.println("Restarted the Python web server on instance " + instanceId + "."); } public void openInboundPort(String secGroupId, String port, String ipAddress) { AuthorizeSecurityGroupIngressRequest ingressRequest = AuthorizeSecurityGroupIngressRequest.builder() .groupName(secGroupId) .cidrIp(ipAddress) .fromPort(Integer.parseInt(port)) .build(); getEc2Client().authorizeSecurityGroupIngress(ingressRequest); System.out.format("Authorized ingress to %s on port %s from %s.", secGroupId, port, ipAddress); } /** * Detaches a role from an instance profile, detaches policies from the role, * and deletes all the resources. */ public void deleteInstanceProfile(String roleName, String profileName) { try { software.amazon.awssdk.services.iam.model.GetInstanceProfileRequest getInstanceProfileRequest = software.amazon.awssdk.services.iam.model.GetInstanceProfileRequest .builder() .instanceProfileName(profileName) .build(); GetInstanceProfileResponse response = getIAMClient().getInstanceProfile(getInstanceProfileRequest); String name = response.instanceProfile().instanceProfileName(); System.out.println(name); RemoveRoleFromInstanceProfileRequest profileRequest = RemoveRoleFromInstanceProfileRequest.builder() .instanceProfileName(profileName) .roleName(roleName) .build(); getIAMClient().removeRoleFromInstanceProfile(profileRequest); DeleteInstanceProfileRequest deleteInstanceProfileRequest = DeleteInstanceProfileRequest.builder() .instanceProfileName(profileName) .build(); getIAMClient().deleteInstanceProfile(deleteInstanceProfileRequest); System.out.println("Deleted instance profile " + profileName); DeleteRoleRequest deleteRoleRequest = DeleteRoleRequest.builder() .roleName(roleName) .build(); // List attached role policies. ListAttachedRolePoliciesResponse rolesResponse = getIAMClient() .listAttachedRolePolicies(role -> role.roleName(roleName)); List<AttachedPolicy> attachedPolicies = rolesResponse.attachedPolicies(); for (AttachedPolicy attachedPolicy : attachedPolicies) { DetachRolePolicyRequest request = DetachRolePolicyRequest.builder() .roleName(roleName) .policyArn(attachedPolicy.policyArn()) .build(); getIAMClient().detachRolePolicy(request); System.out.println("Detached and deleted policy " + attachedPolicy.policyName()); } getIAMClient().deleteRole(deleteRoleRequest); System.out.println("Instance profile and role deleted."); } catch (IamException e) { System.err.println(e.getMessage()); System.exit(1); } } public void deleteTemplate(String templateName) { getEc2Client().deleteLaunchTemplate(name -> name.launchTemplateName(templateName)); System.out.format(templateName + " was deleted."); } public void deleteAutoScaleGroup(String groupName) { DeleteAutoScalingGroupRequest deleteAutoScalingGroupRequest = DeleteAutoScalingGroupRequest.builder() .autoScalingGroupName(groupName) .forceDelete(true) .build(); getAutoScalingClient().deleteAutoScalingGroup(deleteAutoScalingGroupRequest); System.out.println(groupName + " was deleted."); } /* * Verify the default security group of the specified VPC allows ingress from * this * computer. This can be done by allowing ingress from this computer's IP * address. In some situations, such as connecting from a corporate network, you * must instead specify a prefix list ID. You can also temporarily open the port * to * any IP address while running this example. If you do, be sure to remove * public * access when you're done. * */ public GroupInfo verifyInboundPort(String VPC, int port, String ipAddress) { boolean portIsOpen = false; GroupInfo groupInfo = new GroupInfo(); try { Filter filter = Filter.builder() .name("group-name") .values("default") .build(); Filter filter1 = Filter.builder() .name("vpc-id") .values(VPC) .build(); DescribeSecurityGroupsRequest securityGroupsRequest = DescribeSecurityGroupsRequest.builder() .filters(filter, filter1) .build(); DescribeSecurityGroupsResponse securityGroupsResponse = getEc2Client() .describeSecurityGroups(securityGroupsRequest); String securityGroup = securityGroupsResponse.securityGroups().get(0).groupName(); groupInfo.setGroupName(securityGroup); for (SecurityGroup secGroup : securityGroupsResponse.securityGroups()) { System.out.println("Found security group: " + secGroup.groupId()); for (IpPermission ipPermission : secGroup.ipPermissions()) { if (ipPermission.fromPort() == port) { System.out.println("Found inbound rule: " + ipPermission); for (IpRange ipRange : ipPermission.ipRanges()) { String cidrIp = ipRange.cidrIp(); if (cidrIp.startsWith(ipAddress) || cidrIp.equals("0.0.0.0/0")) { System.out.println(cidrIp + " is applicable"); portIsOpen = true; } } if (!ipPermission.prefixListIds().isEmpty()) { System.out.println("Prefix lList is applicable"); portIsOpen = true; } if (!portIsOpen) { System.out .println("The inbound rule does not appear to be open to either this computer's IP," + " all IP addresses (0.0.0.0/0), or to a prefix list ID."); } else { break; } } } } } catch (AutoScalingException e) { System.err.println(e.awsErrorDetails().errorMessage()); } groupInfo.setPortOpen(portIsOpen); return groupInfo; } /* * Attaches an Elastic Load Balancing (ELB) target group to this EC2 Auto * Scaling group. * The target group specifies how the load balancer forward requests to the * instances * in the group. */ public void attachLoadBalancerTargetGroup(String asGroupName, String targetGroupARN) { try { AttachLoadBalancerTargetGroupsRequest targetGroupsRequest = AttachLoadBalancerTargetGroupsRequest.builder() .autoScalingGroupName(asGroupName) .targetGroupARNs(targetGroupARN) .build(); getAutoScalingClient().attachLoadBalancerTargetGroups(targetGroupsRequest); System.out.println("Attached load balancer to " + asGroupName); } catch (AutoScalingException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } } // Creates an EC2 Auto Scaling group with the specified size. public String[] createGroup(int groupSize, String templateName, String autoScalingGroupName) { // Get availability zones. software.amazon.awssdk.services.ec2.model.DescribeAvailabilityZonesRequest zonesRequest = software.amazon.awssdk.services.ec2.model.DescribeAvailabilityZonesRequest .builder() .build(); DescribeAvailabilityZonesResponse zonesResponse = getEc2Client().describeAvailabilityZones(zonesRequest); List<String> availabilityZoneNames = zonesResponse.availabilityZones().stream() .map(software.amazon.awssdk.services.ec2.model.AvailabilityZone::zoneName) .collect(Collectors.toList()); String availabilityZones = String.join(",", availabilityZoneNames); LaunchTemplateSpecification specification = LaunchTemplateSpecification.builder() .launchTemplateName(templateName) .version("$Default") .build(); String[] zones = availabilityZones.split(","); CreateAutoScalingGroupRequest groupRequest = CreateAutoScalingGroupRequest.builder() .launchTemplate(specification) .availabilityZones(zones) .maxSize(groupSize) .minSize(groupSize) .autoScalingGroupName(autoScalingGroupName) .build(); try { getAutoScalingClient().createAutoScalingGroup(groupRequest); } catch (AutoScalingException e) { System.err.println(e.awsErrorDetails().errorMessage()); System.exit(1); } System.out.println("Created an EC2 Auto Scaling group named " + autoScalingGroupName); return zones; } public String getDefaultVPC() { // Define the filter. Filter defaultFilter = Filter.builder() .name("is-default") .values("true") .build(); software.amazon.awssdk.services.ec2.model.DescribeVpcsRequest request = software.amazon.awssdk.services.ec2.model.DescribeVpcsRequest .builder() .filters(defaultFilter) .build(); DescribeVpcsResponse response = getEc2Client().describeVpcs(request); return response.vpcs().get(0).vpcId(); } // Gets the default subnets in a VPC for a specified list of Availability Zones. public List<Subnet> getSubnets(String vpcId, String[] availabilityZones) { List<Subnet> subnets = null; Filter vpcFilter = Filter.builder() .name("vpc-id") .values(vpcId) .build(); Filter azFilter = Filter.builder() .name("availability-zone") .values(availabilityZones) .build(); Filter defaultForAZ = Filter.builder() .name("default-for-az") .values("true") .build(); DescribeSubnetsRequest request = DescribeSubnetsRequest.builder() .filters(vpcFilter, azFilter, defaultForAZ) .build(); DescribeSubnetsResponse response = getEc2Client().describeSubnets(request); subnets = response.subnets(); return subnets; } // Gets data about the instances in the EC2 Auto Scaling group. public String getBadInstance(String groupName) { DescribeAutoScalingGroupsRequest request = DescribeAutoScalingGroupsRequest.builder() .autoScalingGroupNames(groupName) .build(); DescribeAutoScalingGroupsResponse response = getAutoScalingClient().describeAutoScalingGroups(request); AutoScalingGroup autoScalingGroup = response.autoScalingGroups().get(0); List<String> instanceIds = autoScalingGroup.instances().stream() .map(instance -> instance.instanceId()) .collect(Collectors.toList()); String[] instanceIdArray = instanceIds.toArray(new String[0]); for (String instanceId : instanceIdArray) { System.out.println("Instance ID: " + instanceId); return instanceId; } return ""; } // Gets data about the profile associated with an instance. public String getInstanceProfile(String instanceId) { Filter filter = Filter.builder() .name("instance-id") .values(instanceId) .build(); DescribeIamInstanceProfileAssociationsRequest associationsRequest = DescribeIamInstanceProfileAssociationsRequest .builder() .filters(filter) .build(); DescribeIamInstanceProfileAssociationsResponse response = getEc2Client() .describeIamInstanceProfileAssociations(associationsRequest); return response.iamInstanceProfileAssociations().get(0).associationId(); } public void deleteRolesPolicies(String policyName, String roleName, String InstanceProfile) { ListPoliciesRequest listPoliciesRequest = ListPoliciesRequest.builder().build(); ListPoliciesResponse listPoliciesResponse = getIAMClient().listPolicies(listPoliciesRequest); for (Policy policy : listPoliciesResponse.policies()) { if (policy.policyName().equals(policyName)) { // List the entities (users, groups, roles) that are attached to the policy. software.amazon.awssdk.services.iam.model.ListEntitiesForPolicyRequest listEntitiesRequest = software.amazon.awssdk.services.iam.model.ListEntitiesForPolicyRequest .builder() .policyArn(policy.arn()) .build(); ListEntitiesForPolicyResponse listEntitiesResponse = iamClient .listEntitiesForPolicy(listEntitiesRequest); if (!listEntitiesResponse.policyGroups().isEmpty() || !listEntitiesResponse.policyUsers().isEmpty() || !listEntitiesResponse.policyRoles().isEmpty()) { // Detach the policy from any entities it is attached to. DetachRolePolicyRequest detachPolicyRequest = DetachRolePolicyRequest.builder() .policyArn(policy.arn()) .roleName(roleName) // Specify the name of the IAM role .build(); getIAMClient().detachRolePolicy(detachPolicyRequest); System.out.println("Policy detached from entities."); } // Now, you can delete the policy. DeletePolicyRequest deletePolicyRequest = DeletePolicyRequest.builder() .policyArn(policy.arn()) .build(); getIAMClient().deletePolicy(deletePolicyRequest); System.out.println("Policy deleted successfully."); break; } } // List the roles associated with the instance profile ListInstanceProfilesForRoleRequest listRolesRequest = ListInstanceProfilesForRoleRequest.builder() .roleName(roleName) .build(); // Detach the roles from the instance profile ListInstanceProfilesForRoleResponse listRolesResponse = iamClient.listInstanceProfilesForRole(listRolesRequest); for (software.amazon.awssdk.services.iam.model.InstanceProfile profile : listRolesResponse.instanceProfiles()) { RemoveRoleFromInstanceProfileRequest removeRoleRequest = RemoveRoleFromInstanceProfileRequest.builder() .instanceProfileName(InstanceProfile) .roleName(roleName) // Remove the extra dot here .build(); getIAMClient().removeRoleFromInstanceProfile(removeRoleRequest); System.out.println("Role " + roleName + " removed from instance profile " + InstanceProfile); } // Delete the instance profile after removing all roles DeleteInstanceProfileRequest deleteInstanceProfileRequest = DeleteInstanceProfileRequest.builder() .instanceProfileName(InstanceProfile) .build(); getIAMClient().deleteInstanceProfile(r -> r.instanceProfileName(InstanceProfile)); System.out.println(InstanceProfile + " Deleted"); System.out.println("All roles and policies are deleted."); } }

Create a class that wraps Elastic Load Balancing actions.

public class LoadBalancer { public ElasticLoadBalancingV2Client elasticLoadBalancingV2Client; public ElasticLoadBalancingV2Client getLoadBalancerClient() { if (elasticLoadBalancingV2Client == null) { elasticLoadBalancingV2Client = ElasticLoadBalancingV2Client.builder() .region(Region.US_EAST_1) .build(); } return elasticLoadBalancingV2Client; } // Checks the health of the instances in the target group. public List<TargetHealthDescription> checkTargetHealth(String targetGroupName) { DescribeTargetGroupsRequest targetGroupsRequest = DescribeTargetGroupsRequest.builder() .names(targetGroupName) .build(); DescribeTargetGroupsResponse tgResponse = getLoadBalancerClient().describeTargetGroups(targetGroupsRequest); DescribeTargetHealthRequest healthRequest = DescribeTargetHealthRequest.builder() .targetGroupArn(tgResponse.targetGroups().get(0).targetGroupArn()) .build(); DescribeTargetHealthResponse healthResponse = getLoadBalancerClient().describeTargetHealth(healthRequest); return healthResponse.targetHealthDescriptions(); } // Gets the HTTP endpoint of the load balancer. public String getEndpoint(String lbName) { DescribeLoadBalancersResponse res = getLoadBalancerClient() .describeLoadBalancers(describe -> describe.names(lbName)); return res.loadBalancers().get(0).dnsName(); } // Deletes a load balancer. public void deleteLoadBalancer(String lbName) { try { // Use a waiter to delete the Load Balancer. DescribeLoadBalancersResponse res = getLoadBalancerClient() .describeLoadBalancers(describe -> describe.names(lbName)); ElasticLoadBalancingV2Waiter loadBalancerWaiter = getLoadBalancerClient().waiter(); DescribeLoadBalancersRequest request = DescribeLoadBalancersRequest.builder() .loadBalancerArns(res.loadBalancers().get(0).loadBalancerArn()) .build(); getLoadBalancerClient().deleteLoadBalancer( builder -> builder.loadBalancerArn(res.loadBalancers().get(0).loadBalancerArn())); WaiterResponse<DescribeLoadBalancersResponse> waiterResponse = loadBalancerWaiter .waitUntilLoadBalancersDeleted(request); waiterResponse.matched().response().ifPresent(System.out::println); } catch (ElasticLoadBalancingV2Exception e) { System.err.println(e.awsErrorDetails().errorMessage()); } System.out.println(lbName + " was deleted."); } // Deletes the target group. public void deleteTargetGroup(String targetGroupName) { try { DescribeTargetGroupsResponse res = getLoadBalancerClient() .describeTargetGroups(describe -> describe.names(targetGroupName)); getLoadBalancerClient() .deleteTargetGroup(builder -> builder.targetGroupArn(res.targetGroups().get(0).targetGroupArn())); } catch (ElasticLoadBalancingV2Exception e) { System.err.println(e.awsErrorDetails().errorMessage()); } System.out.println(targetGroupName + " was deleted."); } // Verify this computer can successfully send a GET request to the load balancer // endpoint. public boolean verifyLoadBalancerEndpoint(String elbDnsName) throws IOException, InterruptedException { boolean success = false; int retries = 3; CloseableHttpClient httpClient = HttpClients.createDefault(); // Create an HTTP GET request to the ELB. HttpGet httpGet = new HttpGet("http://" + elbDnsName); try { while ((!success) && (retries > 0)) { // Execute the request and get the response. HttpResponse response = httpClient.execute(httpGet); int statusCode = response.getStatusLine().getStatusCode(); System.out.println("HTTP Status Code: " + statusCode); if (statusCode == 200) { success = true; } else { retries--; System.out.println("Got connection error from load balancer endpoint, retrying..."); TimeUnit.SECONDS.sleep(15); } } } catch (org.apache.http.conn.HttpHostConnectException e) { System.out.println(e.getMessage()); } System.out.println("Status.." + success); return success; } /* * Creates an Elastic Load Balancing target group. The target group specifies * how * the load balancer forward requests to instances in the group and how instance * health is checked. */ public String createTargetGroup(String protocol, int port, String vpcId, String targetGroupName) { CreateTargetGroupRequest targetGroupRequest = CreateTargetGroupRequest.builder() .healthCheckPath("/healthcheck") .healthCheckTimeoutSeconds(5) .port(port) .vpcId(vpcId) .name(targetGroupName) .protocol(protocol) .build(); CreateTargetGroupResponse targetGroupResponse = getLoadBalancerClient().createTargetGroup(targetGroupRequest); String targetGroupArn = targetGroupResponse.targetGroups().get(0).targetGroupArn(); String targetGroup = targetGroupResponse.targetGroups().get(0).targetGroupName(); System.out.println("The " + targetGroup + " was created with ARN" + targetGroupArn); return targetGroupArn; } /* * Creates an Elastic Load Balancing load balancer that uses the specified * subnets * and forwards requests to the specified target group. */ public String createLoadBalancer(List<Subnet> subnetIds, String targetGroupARN, String lbName, int port, String protocol) { try { List<String> subnetIdStrings = subnetIds.stream() .map(Subnet::subnetId) .collect(Collectors.toList()); CreateLoadBalancerRequest balancerRequest = CreateLoadBalancerRequest.builder() .subnets(subnetIdStrings) .name(lbName) .scheme("internet-facing") .build(); // Create and wait for the load balancer to become available. CreateLoadBalancerResponse lsResponse = getLoadBalancerClient().createLoadBalancer(balancerRequest); String lbARN = lsResponse.loadBalancers().get(0).loadBalancerArn(); ElasticLoadBalancingV2Waiter loadBalancerWaiter = getLoadBalancerClient().waiter(); DescribeLoadBalancersRequest request = DescribeLoadBalancersRequest.builder() .loadBalancerArns(lbARN) .build(); System.out.println("Waiting for Load Balancer " + lbName + " to become available."); WaiterResponse<DescribeLoadBalancersResponse> waiterResponse = loadBalancerWaiter .waitUntilLoadBalancerAvailable(request); waiterResponse.matched().response().ifPresent(System.out::println); System.out.println("Load Balancer " + lbName + " is available."); // Get the DNS name (endpoint) of the load balancer. String lbDNSName = lsResponse.loadBalancers().get(0).dnsName(); System.out.println("*** Load Balancer DNS Name: " + lbDNSName); // Create a listener for the load balance. Action action = Action.builder() .targetGroupArn(targetGroupARN) .type("forward") .build(); CreateListenerRequest listenerRequest = CreateListenerRequest.builder() .loadBalancerArn(lsResponse.loadBalancers().get(0).loadBalancerArn()) .defaultActions(action) .port(port) .protocol(protocol) .defaultActions(action) .build(); getLoadBalancerClient().createListener(listenerRequest); System.out.println("Created listener to forward traffic from load balancer " + lbName + " to target group " + targetGroupARN); // Return the load balancer DNS name. return lbDNSName; } catch (ElasticLoadBalancingV2Exception e) { e.printStackTrace(); } return ""; } }

Create a class that uses DynamoDB to simulate a recommendation service.

public class Database { private static DynamoDbClient dynamoDbClient; public static DynamoDbClient getDynamoDbClient() { if (dynamoDbClient == null) { dynamoDbClient = DynamoDbClient.builder() .region(Region.US_EAST_1) .build(); } return dynamoDbClient; } // Checks to see if the Amazon DynamoDB table exists. private boolean doesTableExist(String tableName) { try { // Describe the table and catch any exceptions. DescribeTableRequest describeTableRequest = DescribeTableRequest.builder() .tableName(tableName) .build(); getDynamoDbClient().describeTable(describeTableRequest); System.out.println("Table '" + tableName + "' exists."); return true; } catch (ResourceNotFoundException e) { System.out.println("Table '" + tableName + "' does not exist."); } catch (DynamoDbException e) { System.err.println("Error checking table existence: " + e.getMessage()); } return false; } /* * Creates a DynamoDB table to use a recommendation service. The table has a * hash key named 'MediaType' that defines the type of media recommended, such * as * Book or Movie, and a range key named 'ItemId' that, combined with the * MediaType, * forms a unique identifier for the recommended item. */ public void createTable(String tableName, String fileName) throws IOException { // First check to see if the table exists. boolean doesExist = doesTableExist(tableName); if (!doesExist) { DynamoDbWaiter dbWaiter = getDynamoDbClient().waiter(); CreateTableRequest createTableRequest = CreateTableRequest.builder() .tableName(tableName) .attributeDefinitions( AttributeDefinition.builder() .attributeName("MediaType") .attributeType(ScalarAttributeType.S) .build(), AttributeDefinition.builder() .attributeName("ItemId") .attributeType(ScalarAttributeType.N) .build()) .keySchema( KeySchemaElement.builder() .attributeName("MediaType") .keyType(KeyType.HASH) .build(), KeySchemaElement.builder() .attributeName("ItemId") .keyType(KeyType.RANGE) .build()) .provisionedThroughput( ProvisionedThroughput.builder() .readCapacityUnits(5L) .writeCapacityUnits(5L) .build()) .build(); getDynamoDbClient().createTable(createTableRequest); System.out.println("Creating table " + tableName + "..."); // Wait until the Amazon DynamoDB table is created. DescribeTableRequest tableRequest = DescribeTableRequest.builder() .tableName(tableName) .build(); WaiterResponse<DescribeTableResponse> waiterResponse = dbWaiter.waitUntilTableExists(tableRequest); waiterResponse.matched().response().ifPresent(System.out::println); System.out.println("Table " + tableName + " created."); // Add records to the table. populateTable(fileName, tableName); } } public void deleteTable(String tableName) { getDynamoDbClient().deleteTable(table -> table.tableName(tableName)); System.out.println("Table " + tableName + " deleted."); } // Populates the table with data located in a JSON file using the DynamoDB // enhanced client. public void populateTable(String fileName, String tableName) throws IOException { DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder() .dynamoDbClient(getDynamoDbClient()) .build(); ObjectMapper objectMapper = new ObjectMapper(); File jsonFile = new File(fileName); JsonNode rootNode = objectMapper.readTree(jsonFile); DynamoDbTable<Recommendation> mappedTable = enhancedClient.table(tableName, TableSchema.fromBean(Recommendation.class)); for (JsonNode currentNode : rootNode) { String mediaType = currentNode.path("MediaType").path("S").asText(); int itemId = currentNode.path("ItemId").path("N").asInt(); String title = currentNode.path("Title").path("S").asText(); String creator = currentNode.path("Creator").path("S").asText(); // Create a Recommendation object and set its properties. Recommendation rec = new Recommendation(); rec.setMediaType(mediaType); rec.setItemId(itemId); rec.setTitle(title); rec.setCreator(creator); // Put the item into the DynamoDB table. mappedTable.putItem(rec); // Add the Recommendation to the list. } System.out.println("Added all records to the " + tableName); } }

Create a class that wraps Systems Manager actions.

public class ParameterHelper { String tableName = "doc-example-resilient-architecture-table"; String dyntable = "doc-example-recommendation-service"; String failureResponse = "doc-example-resilient-architecture-failure-response"; String healthCheck = "doc-example-resilient-architecture-health-check"; public void reset() { put(dyntable, tableName); put(failureResponse, "none"); put(healthCheck, "shallow"); } public void put(String name, String value) { SsmClient ssmClient = SsmClient.builder() .region(Region.US_EAST_1) .build(); PutParameterRequest parameterRequest = PutParameterRequest.builder() .name(name) .value(value) .overwrite(true) .type("String") .build(); ssmClient.putParameter(parameterRequest); System.out.printf("Setting demo parameter %s to '%s'.", name, value); } }

The following code example shows how to:

  • Create IAM policies by using the object-oriented API.

  • Use the IAM Policy Builder API with the IAM service.

SDK for Java 2.x
Note

There's more on GitHub. Find the complete example and learn how to set up and run in the AWS Code Examples Repository.

The examples use the following imports.

import org.slf4j.Logger; import org.slf4j.LoggerFactory; import software.amazon.awssdk.policybuilder.iam.IamConditionOperator; import software.amazon.awssdk.policybuilder.iam.IamEffect; import software.amazon.awssdk.policybuilder.iam.IamPolicy; import software.amazon.awssdk.policybuilder.iam.IamPolicyWriter; import software.amazon.awssdk.policybuilder.iam.IamPrincipal; import software.amazon.awssdk.policybuilder.iam.IamPrincipalType; import software.amazon.awssdk.policybuilder.iam.IamResource; import software.amazon.awssdk.policybuilder.iam.IamStatement; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.iam.IamClient; import software.amazon.awssdk.services.iam.model.GetPolicyResponse; import software.amazon.awssdk.services.iam.model.GetPolicyVersionResponse; import software.amazon.awssdk.services.sts.StsClient; import java.net.URLDecoder; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.List;

Create a time-based policy.

public String timeBasedPolicyExample() { IamPolicy policy = IamPolicy.builder() .addStatement(b -> b .effect(IamEffect.ALLOW) .addAction("dynamodb:GetItem") .addResource(IamResource.ALL) .addCondition(b1 -> b1 .operator(IamConditionOperator.DATE_GREATER_THAN) .key("aws:CurrentTime") .value("2020-04-01T00:00:00Z")) .addCondition(b1 -> b1 .operator(IamConditionOperator.DATE_LESS_THAN) .key("aws:CurrentTime") .value("2020-06-30T23:59:59Z"))) .build(); // Use an IamPolicyWriter to write out the JSON string to a more readable // format. return policy.toJson(IamPolicyWriter.builder() .prettyPrint(true) .build()); }

Create a policy with multiple conditions.

public String multipleConditionsExample() { IamPolicy policy = IamPolicy.builder() .addStatement(b -> b .effect(IamEffect.ALLOW) .addAction("dynamodb:GetItem") .addAction("dynamodb:BatchGetItem") .addAction("dynamodb:Query") .addAction("dynamodb:PutItem") .addAction("dynamodb:UpdateItem") .addAction("dynamodb:DeleteItem") .addAction("dynamodb:BatchWriteItem") .addResource("arn:aws:dynamodb:*:*:table/table-name") .addConditions(IamConditionOperator.STRING_EQUALS .addPrefix("ForAllValues:"), "dynamodb:Attributes", List.of("column-name1", "column-name2", "column-name3")) .addCondition(b1 -> b1 .operator(IamConditionOperator.STRING_EQUALS .addSuffix("IfExists")) .key("dynamodb:Select") .value("SPECIFIC_ATTRIBUTES"))) .build(); return policy.toJson(IamPolicyWriter.builder() .prettyPrint(true).build()); }

Use principals in a policy.

public String specifyPrincipalsExample() { IamPolicy policy = IamPolicy.builder() .addStatement(b -> b .effect(IamEffect.DENY) .addAction("s3:*") .addPrincipal(IamPrincipal.ALL) .addResource("arn:aws:s3:::BUCKETNAME/*") .addResource("arn:aws:s3:::BUCKETNAME") .addCondition(b1 -> b1 .operator(IamConditionOperator.ARN_NOT_EQUALS) .key("aws:PrincipalArn") .value("arn:aws:iam::444455556666:user/user-name"))) .build(); return policy.toJson(IamPolicyWriter.builder() .prettyPrint(true).build()); }

Allow cross-account access.

public String allowCrossAccountAccessExample() { IamPolicy policy = IamPolicy.builder() .addStatement(b -> b .effect(IamEffect.ALLOW) .addPrincipal(IamPrincipalType.AWS, "111122223333") .addAction("s3:PutObject") .addResource("arn:aws:s3:::amzn-s3-demo-bucket/*") .addCondition(b1 -> b1 .operator(IamConditionOperator.STRING_EQUALS) .key("s3:x-amz-acl") .value("bucket-owner-full-control"))) .build(); return policy.toJson(IamPolicyWriter.builder() .prettyPrint(true).build()); }

Build and upload an IamPolicy.

public String createAndUploadPolicyExample(IamClient iam, String accountID, String policyName) { // Build the policy. IamPolicy policy = IamPolicy.builder() // 'version' defaults to "2012-10-17". .addStatement(IamStatement.builder() .effect(IamEffect.ALLOW) .addAction("dynamodb:PutItem") .addResource("arn:aws:dynamodb:us-east-1:" + accountID + ":table/exampleTableName") .build()) .build(); // Upload the policy. iam.createPolicy(r -> r.policyName(policyName).policyDocument(policy.toJson())); return policy.toJson(IamPolicyWriter.builder().prettyPrint(true).build()); }

Download and work with an IamPolicy.

public String createNewBasedOnExistingPolicyExample(IamClient iam, String accountID, String policyName, String newPolicyName) { String policyArn = "arn:aws:iam::" + accountID + ":policy/" + policyName; GetPolicyResponse getPolicyResponse = iam.getPolicy(r -> r.policyArn(policyArn)); String policyVersion = getPolicyResponse.policy().defaultVersionId(); GetPolicyVersionResponse getPolicyVersionResponse = iam .getPolicyVersion(r -> r.policyArn(policyArn).versionId(policyVersion)); // Create an IamPolicy instance from the JSON string returned from IAM. String decodedPolicy = URLDecoder.decode(getPolicyVersionResponse.policyVersion().document(), StandardCharsets.UTF_8); IamPolicy policy = IamPolicy.fromJson(decodedPolicy); /* * All IamPolicy components are immutable, so use the copy method that creates a * new instance that * can be altered in the same method call. * * Add the ability to get an item from DynamoDB as an additional action. */ IamStatement newStatement = policy.statements().get(0).copy(s -> s.addAction("dynamodb:GetItem")); // Create a new statement that replaces the original statement. IamPolicy newPolicy = policy.copy(p -> p.statements(Arrays.asList(newStatement))); // Upload the new policy. IAM now has both policies. iam.createPolicy(r -> r.policyName(newPolicyName) .policyDocument(newPolicy.toJson())); return newPolicy.toJson(IamPolicyWriter.builder().prettyPrint(true).build()); }