From 1b57f997f910168fc439b0ee5a80d0db272ed650 Mon Sep 17 00:00:00 2001 From: Scott Macdonald Date: Thu, 4 Dec 2025 10:25:41 -0500 Subject: [PATCH 1/4] Add Java V2 examples for Control Tower --- javav2/example_code/controltower/README.md | 102 +++ javav2/example_code/controltower/pom.xml | 90 +++ .../controltower/ControlTowerActions.java | 588 ++++++++++++++++++ .../controltower/ControlTowerScenario.java | 159 +++++ .../controltower/HelloControlTower.java | 78 +++ .../src/main/java/resources/config.properties | 3 + .../src/main/java/resources/log4j2.xml | 32 + .../src/test/java/ControlTowerTest.java | 51 ++ 8 files changed, 1103 insertions(+) create mode 100644 javav2/example_code/controltower/README.md create mode 100644 javav2/example_code/controltower/pom.xml create mode 100644 javav2/example_code/controltower/src/main/java/com/example/controltower/ControlTowerActions.java create mode 100644 javav2/example_code/controltower/src/main/java/com/example/controltower/ControlTowerScenario.java create mode 100644 javav2/example_code/controltower/src/main/java/com/example/controltower/HelloControlTower.java create mode 100644 javav2/example_code/controltower/src/main/java/resources/config.properties create mode 100644 javav2/example_code/controltower/src/main/java/resources/log4j2.xml create mode 100644 javav2/example_code/controltower/src/test/java/ControlTowerTest.java diff --git a/javav2/example_code/controltower/README.md b/javav2/example_code/controltower/README.md new file mode 100644 index 00000000000..400f3615ae3 --- /dev/null +++ b/javav2/example_code/controltower/README.md @@ -0,0 +1,102 @@ +# AWS Control Tower code examples for the SDK for Java 2.x + +## Overview + +This is a workspace where you can find the following AWS SDK for Java 2.x AWS Control Tower examples. + +## ⚠ Important + +* Running this code might result in charges to your AWS account. +* Running the tests might result in charges to your AWS account. +* We recommend that you grant your code least privilege. + +## Code examples + +### Actions + +The following examples show you how to perform actions using the AWS SDK for Java 2.x. + +* [List landing zones](src/main/java/com/example/controltower/ControlTowerActions.java) (`ListLandingZones`) +* [List baselines](src/main/java/com/example/controltower/ControlTowerActions.java) (`ListBaselines`) +* [List enabled baselines](src/main/java/com/example/controltower/ControlTowerActions.java) (`ListEnabledBaselines`) +* [Enable baseline](src/main/java/com/example/controltower/ControlTowerActions.java) (`EnableBaseline`) +* [Disable baseline](src/main/java/com/example/controltower/ControlTowerActions.java) (`DisableBaseline`) +* [Get baseline operation](src/main/java/com/example/controltower/ControlTowerActions.java) (`GetBaselineOperation`) +* [List enabled controls](src/main/java/com/example/controltower/ControlTowerActions.java) (`ListEnabledControls`) +* [Enable control](src/main/java/com/example/controltower/ControlTowerActions.java) (`EnableControl`) +* [Disable control](src/main/java/com/example/controltower/ControlTowerActions.java) (`DisableControl`) +* [Get control operation](src/main/java/com/example/controltower/ControlTowerActions.java) (`GetControlOperation`) + +### Scenarios + +The following examples show you how to implement common scenarios. + +* [Learn the basics](src/main/java/com/example/controltower/ControlTowerScenario.java) - Learn the basics by checking setup, managing baselines and controls. + +### Hello + +* [Hello Control Tower](src/main/java/com/example/controltower/HelloControlTower.java) - Get started with AWS Control Tower. + +## Prerequisites + +- You must have an AWS account, and have your default credentials and AWS Region configured. +- Java 17 or later +- Maven 3.6 or later +- AWS Control Tower must be set up in your account + +## Install + +To build and run the examples, navigate to the directory that contains a `pom.xml` file and run the following command: + +``` +mvn compile +``` + +## Run the examples + +### Instructions + +All examples can be run individually. For example: + +``` +mvn exec:java -Dexec.mainClass="com.example.controltower.HelloControlTower" -Dexec.args="us-east-1" +``` + +### Hello Control Tower + +This example shows you how to get started using AWS Control Tower. + +``` +mvn exec:java -Dexec.mainClass="com.example.controltower.HelloControlTower" -Dexec.args="us-east-1" +``` + +### Learn the basics + +This interactive scenario runs at a command prompt and shows you how to use AWS Control Tower to do the following: + +1. Check Control Tower setup and list landing zones +2. List available baselines for governance +3. List currently enabled baselines +4. Enable baselines for organizational units +5. List and enable controls for compliance +6. Monitor operation status +7. Clean up resources + +``` +mvn exec:java -Dexec.mainClass="com.example.controltower.ControlTowerScenario" -Dexec.args="us-east-1" +``` + +## Run the tests + +Unit tests in this module use JUnit 5. To run all of the tests, +run the following in your [GitHub root]/javav2/example_code/controltower folder. + +``` +mvn test +``` + +## Additional resources + +- [AWS Control Tower User Guide](https://docs.aws.amazon.com/controltower/latest/userguide/) +- [AWS Control Tower API Reference](https://docs.aws.amazon.com/controltower/latest/APIReference/) +- [AWS SDK for Java 2.x (AWS Control Tower)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/controltower/package-summary.html) \ No newline at end of file diff --git a/javav2/example_code/controltower/pom.xml b/javav2/example_code/controltower/pom.xml new file mode 100644 index 00000000000..46e87718415 --- /dev/null +++ b/javav2/example_code/controltower/pom.xml @@ -0,0 +1,90 @@ + + + 4.0.0 + aws.example + controltower + 1.0-SNAPSHOT + + 17 + 17 + UTF-8 + + + + + software.amazon.awssdk + bom + 2.28.11 + pom + import + + + + + + software.amazon.awssdk + controltower + + + software.amazon.awssdk + controlcatalog + + + org.slf4j + slf4j-api + 2.0.7 + + + ch.qos.logback + logback-classic + 1.4.8 + + + + software.amazon.awssdk + url-connection-client + 2.36.2 + compile + + + software.amazon.awssdk + sdk-core + + + org.junit.jupiter + junit-jupiter-engine + 5.10.0 + test + + + org.junit.jupiter + junit-jupiter-api + 5.10.0 + test + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.11.0 + + 17 + 17 + + + + org.codehaus.mojo + exec-maven-plugin + 3.1.0 + + com.example.controltower.ControlTowerScenario + us-east-1 + + + + + \ No newline at end of file diff --git a/javav2/example_code/controltower/src/main/java/com/example/controltower/ControlTowerActions.java b/javav2/example_code/controltower/src/main/java/com/example/controltower/ControlTowerActions.java new file mode 100644 index 00000000000..29b2f6db20b --- /dev/null +++ b/javav2/example_code/controltower/src/main/java/com/example/controltower/ControlTowerActions.java @@ -0,0 +1,588 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package com.example.controltower; + +import software.amazon.awssdk.services.controltower.ControlTowerClient; +import software.amazon.awssdk.services.controltower.model.*; +import software.amazon.awssdk.services.controltower.paginators.ListBaselinesIterable; +import software.amazon.awssdk.services.controltower.paginators.ListEnabledBaselinesIterable; +import software.amazon.awssdk.services.controltower.paginators.ListEnabledControlsIterable; +import software.amazon.awssdk.services.controltower.paginators.ListLandingZonesIterable; +import software.amazon.awssdk.services.controlcatalog.ControlCatalogClient; +import software.amazon.awssdk.services.controlcatalog.paginators.ListControlsIterable; +import software.amazon.awssdk.core.exception.SdkException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; +import java.util.ArrayList; + +/** + * 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 + * + * This Java code example shows how to perform AWS Control Tower operations. + */ + +// snippet-start:[controltower.java2.controltower_actions.main] +public class ControlTowerActions { + + private static final Logger logger = LoggerFactory.getLogger(ControlTowerActions.class); + + // snippet-start:[controltower.java2.list_landing_zones.main] + /** + * Lists all landing zones using pagination to retrieve complete results. + * + * @param controlTowerClient the Control Tower client to use for the operation + * @return a list of all landing zones + * @throws ControlTowerException if a service-specific error occurs + * @throws SdkException if an SDK error occurs + */ + public static List listLandingZones(ControlTowerClient controlTowerClient) { + try { + List landingZones = new ArrayList<>(); + + String nextToken = null; + + do { + ListLandingZonesRequest.Builder requestBuilder = ListLandingZonesRequest.builder(); + if (nextToken != null) { + requestBuilder.nextToken(nextToken); + } + + ListLandingZonesResponse response = controlTowerClient.listLandingZones(requestBuilder.build()); + + if (response.landingZones() != null) { + landingZones.addAll(response.landingZones()); + } + + nextToken = response.nextToken(); + } while (nextToken != null); + + logger.info("Retrieved {} landing zones", landingZones.size()); + return landingZones; + + } catch (ControlTowerException e) { + String errorCode = e.awsErrorDetails().errorCode(); + switch (errorCode) { + case "AccessDeniedException": + logger.error("Access denied when listing landing zones: {}", e.getMessage()); + break; + default: + logger.error("Error listing landing zones: {}", e.getMessage()); + } + throw e; + } catch (SdkException e) { + logger.error("SDK error listing landing zones: {}", e.getMessage()); + throw e; + } + } + // snippet-end:[controltower.java2.list_landing_zones.main] + + // snippet-start:[controltower.java2.list_baselines.main] + /** + * Lists all available baselines using pagination to retrieve complete results. + * + * @param controlTowerClient the Control Tower client to use for the operation + * @return a list of all baselines + * @throws ControlTowerException if a service-specific error occurs + * @throws SdkException if an SDK error occurs + */ + public static List listBaselines(ControlTowerClient controlTowerClient) { + try { + List baselines = new ArrayList<>(); + + String nextToken = null; + + do { + ListBaselinesRequest.Builder requestBuilder = ListBaselinesRequest.builder(); + if (nextToken != null) { + requestBuilder.nextToken(nextToken); + } + + ListBaselinesResponse response = controlTowerClient.listBaselines(requestBuilder.build()); + + if (response.baselines() != null) { + baselines.addAll(response.baselines()); + } + + nextToken = response.nextToken(); + } while (nextToken != null); + + logger.info("Retrieved {} baselines", baselines.size()); + return baselines; + + } catch (ControlTowerException e) { + String errorCode = e.awsErrorDetails().errorCode(); + switch (errorCode) { + case "AccessDeniedException": + logger.error("Access denied when listing baselines: {}", e.getMessage()); + break; + default: + logger.error("Error listing baselines: {}", e.getMessage()); + } + throw e; + } catch (SdkException e) { + logger.error("SDK error listing baselines: {}", e.getMessage()); + throw e; + } + } + // snippet-end:[controltower.java2.list_baselines.main] + + // snippet-start:[controltower.java2.list_enabled_baselines.main] + /** + * Lists all enabled baselines using pagination to retrieve complete results. + * + * @param controlTowerClient the Control Tower client to use for the operation + * @return a list of all enabled baselines + * @throws ControlTowerException if a service-specific error occurs + * @throws SdkException if an SDK error occurs + */ + public static List listEnabledBaselines(ControlTowerClient controlTowerClient) { + try { + List enabledBaselines = new ArrayList<>(); + + String nextToken = null; + + do { + ListEnabledBaselinesRequest.Builder requestBuilder = ListEnabledBaselinesRequest.builder(); + if (nextToken != null) { + requestBuilder.nextToken(nextToken); + } + + ListEnabledBaselinesResponse response = controlTowerClient.listEnabledBaselines(requestBuilder.build()); + + if (response.enabledBaselines() != null) { + enabledBaselines.addAll(response.enabledBaselines()); + } + + nextToken = response.nextToken(); + } while (nextToken != null); + + logger.info("Retrieved {} enabled baselines", enabledBaselines.size()); + return enabledBaselines; + + } catch (ControlTowerException e) { + String errorCode = e.awsErrorDetails().errorCode(); + switch (errorCode) { + case "ResourceNotFoundException": + logger.error("Target not found when listing enabled baselines: {}", e.getMessage()); + break; + default: + logger.error("Error listing enabled baselines: {}", e.getMessage()); + } + throw e; + } catch (SdkException e) { + logger.error("SDK error listing enabled baselines: {}", e.getMessage()); + throw e; + } + } + // snippet-end:[controltower.java2.list_enabled_baselines.main] + + // snippet-start:[controltower.java2.enable_baseline.main] + /** + * Enables a baseline for a specified target. + * + * @param controlTowerClient the Control Tower client to use for the operation + * @param baselineIdentifier the identifier of the baseline to enable + * @param baselineVersion the version of the baseline to enable + * @param targetIdentifier the identifier of the target (e.g., OU ARN) + * @return the operation identifier + * @throws ControlTowerException if a service-specific error occurs + * @throws SdkException if an SDK error occurs + */ + public static String enableBaseline(ControlTowerClient controlTowerClient, + String baselineIdentifier, + String baselineVersion, + String targetIdentifier) { + try { + EnableBaselineRequest request = EnableBaselineRequest.builder() + .baselineIdentifier(baselineIdentifier) + .baselineVersion(baselineVersion) + .targetIdentifier(targetIdentifier) + .build(); + + EnableBaselineResponse response = controlTowerClient.enableBaseline(request); + String operationId = response.operationIdentifier(); + + logger.info("Enabled baseline with operation ID: {}", operationId); + return operationId; + + } catch (ControlTowerException e) { + String errorCode = e.awsErrorDetails().errorCode(); + switch (errorCode) { + case "ValidationException": + if (e.getMessage().contains("already enabled")) { + logger.info("Baseline is already enabled for this target"); + return null; + } + logger.error("Validation error enabling baseline: {}", e.getMessage()); + break; + case "ConflictException": + logger.error("Conflict enabling baseline: {}", e.getMessage()); + break; + default: + logger.error("Error enabling baseline: {}", e.getMessage()); + } + throw e; + } catch (SdkException e) { + logger.error("SDK error enabling baseline: {}", e.getMessage()); + throw e; + } + } + // snippet-end:[controltower.java2.enable_baseline.main] + + // snippet-start:[controltower.java2.disable_baseline.main] + /** + * Disables a baseline for a specified target. + * + * @param controlTowerClient the Control Tower client to use for the operation + * @param enabledBaselineIdentifier the identifier of the enabled baseline to disable + * @return the operation identifier + * @throws ControlTowerException if a service-specific error occurs + * @throws SdkException if an SDK error occurs + */ + public static String disableBaseline(ControlTowerClient controlTowerClient, + String enabledBaselineIdentifier) { + try { + DisableBaselineRequest request = DisableBaselineRequest.builder() + .enabledBaselineIdentifier(enabledBaselineIdentifier) + .build(); + + DisableBaselineResponse response = controlTowerClient.disableBaseline(request); + String operationId = response.operationIdentifier(); + + logger.info("Disabled baseline with operation ID: {}", operationId); + return operationId; + + } catch (ControlTowerException e) { + String errorCode = e.awsErrorDetails().errorCode(); + switch (errorCode) { + case "ConflictException": + logger.error("Conflict disabling baseline: {}", e.getMessage()); + break; + case "ResourceNotFoundException": + logger.error("Baseline not found for disabling: {}", e.getMessage()); + break; + default: + logger.error("Error disabling baseline: {}", e.getMessage()); + } + throw e; + } catch (SdkException e) { + logger.error("SDK error disabling baseline: {}", e.getMessage()); + throw e; + } + } + // snippet-end:[controltower.java2.disable_baseline.main] + + // snippet-start:[controltower.java2.get_baseline_operation.main] + /** + * Gets the status of a baseline operation. + * + * @param controlTowerClient the Control Tower client to use for the operation + * @param operationIdentifier the identifier of the operation + * @return the operation status + * @throws ControlTowerException if a service-specific error occurs + * @throws SdkException if an SDK error occurs + */ + public static BaselineOperationStatus getBaselineOperation(ControlTowerClient controlTowerClient, + String operationIdentifier) { + try { + GetBaselineOperationRequest request = GetBaselineOperationRequest.builder() + .operationIdentifier(operationIdentifier) + .build(); + + GetBaselineOperationResponse response = controlTowerClient.getBaselineOperation(request); + BaselineOperationStatus status = response.baselineOperation().status(); + + logger.info("Baseline operation status: {}", status); + return status; + + } catch (ControlTowerException e) { + String errorCode = e.awsErrorDetails().errorCode(); + switch (errorCode) { + case "ResourceNotFoundException": + logger.error("Baseline operation not found: {}", e.getMessage()); + break; + default: + logger.error("Error getting baseline operation status: {}", e.getMessage()); + } + throw e; + } catch (SdkException e) { + logger.error("SDK error getting baseline operation status: {}", e.getMessage()); + throw e; + } + } + // snippet-end:[controltower.java2.get_baseline_operation.main] + + // snippet-start:[controltower.java2.list_enabled_controls.main] + /** + * Lists all enabled controls for a specific target using pagination. + * + * @param controlTowerClient the Control Tower client to use for the operation + * @param targetIdentifier the identifier of the target (e.g., OU ARN) + * @return a list of enabled controls + * @throws ControlTowerException if a service-specific error occurs + * @throws SdkException if an SDK error occurs + */ + public static List listEnabledControls(ControlTowerClient controlTowerClient, + String targetIdentifier) { + try { + List enabledControls = new ArrayList<>(); + + // Use paginator to retrieve all results + ListEnabledControlsIterable listIterable = controlTowerClient.listEnabledControlsPaginator( + ListEnabledControlsRequest.builder() + .targetIdentifier(targetIdentifier) + .build() + ); + + listIterable.stream() + .flatMap(response -> response.enabledControls().stream()) + .forEach(enabledControls::add); + + logger.info("Retrieved {} enabled controls for target {}", enabledControls.size(), targetIdentifier); + return enabledControls; + + } catch (ControlTowerException e) { + String errorCode = e.awsErrorDetails().errorCode(); + switch (errorCode) { + case "AccessDeniedException": + logger.error("Access denied when listing enabled controls: {}", e.getMessage()); + break; + case "ResourceNotFoundException": + if (e.getMessage().contains("not registered with AWS Control Tower")) { + logger.error("Control Tower must be enabled to work with controls"); + } else { + logger.error("Target not found when listing enabled controls: {}", e.getMessage()); + } + break; + default: + logger.error("Error listing enabled controls: {}", e.getMessage()); + } + throw e; + } catch (SdkException e) { + logger.error("SDK error listing enabled controls: {}", e.getMessage()); + throw e; + } + } + // snippet-end:[controltower.java2.list_enabled_controls.main] + + // snippet-start:[controltower.java2.enable_control.main] + /** + * Enables a control for a specified target. + * + * @param controlTowerClient the Control Tower client to use for the operation + * @param controlIdentifier the identifier of the control to enable + * @param targetIdentifier the identifier of the target (e.g., OU ARN) + * @return the operation identifier + * @throws ControlTowerException if a service-specific error occurs + * @throws SdkException if an SDK error occurs + */ + public static String enableControl(ControlTowerClient controlTowerClient, + String controlIdentifier, + String targetIdentifier) { + try { + EnableControlRequest request = EnableControlRequest.builder() + .controlIdentifier(controlIdentifier) + .targetIdentifier(targetIdentifier) + .build(); + + EnableControlResponse response = controlTowerClient.enableControl(request); + String operationId = response.operationIdentifier(); + + logger.info("Enabled control with operation ID: {}", operationId); + return operationId; + + } catch (ControlTowerException e) { + String errorCode = e.awsErrorDetails().errorCode(); + switch (errorCode) { + case "ValidationException": + if (e.getMessage().contains("already enabled")) { + logger.info("Control is already enabled for this target"); + return null; + } + logger.error("Validation error enabling control: {}", e.getMessage()); + break; + case "ResourceNotFoundException": + if (e.getMessage().contains("not registered with AWS Control Tower")) { + logger.error("Control Tower must be enabled to work with controls"); + } else { + logger.error("Control not found: {}", e.getMessage()); + } + break; + default: + logger.error("Error enabling control: {}", e.getMessage()); + } + throw e; + } catch (SdkException e) { + logger.error("SDK error enabling control: {}", e.getMessage()); + throw e; + } + } + // snippet-end:[controltower.java2.enable_control.main] + + // snippet-start:[controltower.java2.disable_control.main] + /** + * Disables a control for a specified target. + * + * @param controlTowerClient the Control Tower client to use for the operation + * @param controlIdentifier the identifier of the control to disable + * @param targetIdentifier the identifier of the target (e.g., OU ARN) + * @return the operation identifier + * @throws ControlTowerException if a service-specific error occurs + * @throws SdkException if an SDK error occurs + */ + public static String disableControl(ControlTowerClient controlTowerClient, + String controlIdentifier, + String targetIdentifier) { + try { + DisableControlRequest request = DisableControlRequest.builder() + .controlIdentifier(controlIdentifier) + .targetIdentifier(targetIdentifier) + .build(); + + DisableControlResponse response = controlTowerClient.disableControl(request); + String operationId = response.operationIdentifier(); + + logger.info("Disabled control with operation ID: {}", operationId); + return operationId; + + } catch (ControlTowerException e) { + String errorCode = e.awsErrorDetails().errorCode(); + switch (errorCode) { + case "ResourceNotFoundException": + logger.error("Control not found for disabling: {}", e.getMessage()); + break; + default: + logger.error("Error disabling control: {}", e.getMessage()); + } + throw e; + } catch (SdkException e) { + logger.error("SDK error disabling control: {}", e.getMessage()); + throw e; + } + } + // snippet-end:[controltower.java2.disable_control.main] + + // snippet-start:[controltower.java2.get_control_operation.main] + /** + * Gets the status of a control operation. + * + * @param controlTowerClient the Control Tower client to use for the operation + * @param operationIdentifier the identifier of the operation + * @return the operation status + * @throws ControlTowerException if a service-specific error occurs + * @throws SdkException if an SDK error occurs + */ + public static ControlOperationStatus getControlOperation(ControlTowerClient controlTowerClient, + String operationIdentifier) { + try { + GetControlOperationRequest request = GetControlOperationRequest.builder() + .operationIdentifier(operationIdentifier) + .build(); + + GetControlOperationResponse response = controlTowerClient.getControlOperation(request); + ControlOperationStatus status = response.controlOperation().status(); + + logger.info("Control operation status: {}", status); + return status; + + } catch (ControlTowerException e) { + String errorCode = e.awsErrorDetails().errorCode(); + switch (errorCode) { + case "ResourceNotFoundException": + logger.error("Control operation not found: {}", e.getMessage()); + break; + default: + logger.error("Error getting control operation status: {}", e.getMessage()); + } + throw e; + } catch (SdkException e) { + logger.error("SDK error getting control operation status: {}", e.getMessage()); + throw e; + } + } + // snippet-end:[controltower.java2.get_control_operation.main] + + // snippet-start:[controltower.java2.list_controls.main] + /** + * Lists all controls in the Control Tower control catalog. + * + * @param controlCatalogClient the Control Catalog client to use for the operation + * @return a list of controls + * @throws SdkException if a service-specific error occurs + */ + public static List listControls( + ControlCatalogClient controlCatalogClient) { + try { + List controls = new ArrayList<>(); + + ListControlsIterable paginator = controlCatalogClient.listControlsPaginator( + software.amazon.awssdk.services.controlcatalog.model.ListControlsRequest.builder().build()); + + paginator.stream() + .flatMap(response -> response.controls().stream()) + .forEach(controls::add); + + logger.info("Retrieved {} controls", controls.size()); + return controls; + + } catch (SdkException e) { + if (e.getMessage().contains("AccessDeniedException")) { + logger.error("Access denied. Please ensure you have the necessary permissions."); + } else { + logger.error("Couldn't list controls. Here's why: {}", e.getMessage()); + } + throw e; + } + } + // snippet-end:[controltower.java2.list_controls.main] + + // snippet-start:[controltower.java2.reset_enabled_baseline.main] + /** + * Resets an enabled baseline for a specific target. + * + * @param controlTowerClient the Control Tower client to use for the operation + * @param enabledBaselineIdentifier the identifier of the enabled baseline to reset + * @return the operation identifier + * @throws ControlTowerException if a service-specific error occurs + * @throws SdkException if an SDK error occurs + */ + public static String resetEnabledBaseline(ControlTowerClient controlTowerClient, + String enabledBaselineIdentifier) { + try { + ResetEnabledBaselineRequest request = ResetEnabledBaselineRequest.builder() + .enabledBaselineIdentifier(enabledBaselineIdentifier) + .build(); + + ResetEnabledBaselineResponse response = controlTowerClient.resetEnabledBaseline(request); + String operationId = response.operationIdentifier(); + + logger.info("Reset enabled baseline with operation ID: {}", operationId); + return operationId; + + } catch (ControlTowerException e) { + String errorCode = e.awsErrorDetails().errorCode(); + switch (errorCode) { + case "ResourceNotFoundException": + logger.error("Target not found: {}", e.getMessage()); + break; + default: + logger.error("Couldn't reset enabled baseline. Here's why: {}", e.getMessage()); + } + throw e; + } catch (SdkException e) { + logger.error("SDK error resetting enabled baseline: {}", e.getMessage()); + throw e; + } + } + // snippet-end:[controltower.java2.reset_enabled_baseline.main] +} +// snippet-end:[controltower.java2.controltower_actions.main] \ No newline at end of file diff --git a/javav2/example_code/controltower/src/main/java/com/example/controltower/ControlTowerScenario.java b/javav2/example_code/controltower/src/main/java/com/example/controltower/ControlTowerScenario.java new file mode 100644 index 00000000000..89d75092781 --- /dev/null +++ b/javav2/example_code/controltower/src/main/java/com/example/controltower/ControlTowerScenario.java @@ -0,0 +1,159 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package com.example.controltower; + +import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider; +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.services.controltower.ControlTowerClient; +import software.amazon.awssdk.services.controltower.model.*; + +import java.util.List; +import java.util.Scanner; + +/** + * 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 + * + * This Java code example performs the following tasks: + * + * 1. Check Control Tower setup and list landing zones + * 2. List available baselines for governance + * 3. List currently enabled baselines + * 4. Enable a baseline for a target organizational unit + * 5. List enabled controls for the target + * 6. Enable a control for a target organizational unit + * 7. Monitor operation status + * 8. Clean up by disabling controls and baselines + */ + +// snippet-start:[controltower.java2.controltower_scenario.main] +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.services.controltower.ControlTowerClient; +import software.amazon.awssdk.services.controltower.model.ControlTowerException; +import software.amazon.awssdk.services.controltower.model.LandingZoneSummary; +import software.amazon.awssdk.services.controltower.model.BaselineSummary; +import software.amazon.awssdk.http.urlconnection.UrlConnectionHttpClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; +import java.util.Scanner; + +public class ControlTowerScenario { + private static final Logger logger = LoggerFactory.getLogger(ControlTowerScenario.class); + public static final String DASHES = new String(new char[80]).replace("\0", "-"); + static Scanner scanner = new Scanner(System.in); + + public static void main(String[] args) { + // Suppress AWS SDK internal debug logs + System.setProperty("software.amazon.awssdk.logging.level", "WARN"); + + logger.info(DASHES); + logger.info("Welcome to the AWS Control Tower basics scenario!"); + logger.info(DASHES); + logger.info(""" + AWS Control Tower is a service that enables you to set up and govern + a secure, multi-account AWS environment based on best practices. + Control Tower orchestrates several other AWS services to build a landing zone. + + This scenario will guide you through the basic operations of + Control Tower, including managing baselines and controls for + governance and compliance. + """); + + // waitForInputToContinue(scanner); + + try { + + ControlTowerClient controlTowerClient = ControlTowerClient.builder() + .region(Region.US_EAST_1) + .credentialsProvider(DefaultCredentialsProvider.create()) + .httpClientBuilder(UrlConnectionHttpClient.builder()) // avoids Apache HTTP client + .build() ; + + runScenario(controlTowerClient); + + } catch (ControlTowerException e) { + logger.error("Control Tower service error: {}", e.awsErrorDetails().errorMessage()); + } catch (Exception e) { + logger.error("Unexpected error: {}", e.getMessage(), e); + } + } + + private static void runScenario(ControlTowerClient controlTowerClient) { + try { + // Step 1: Check Control Tower setup + logger.info(DASHES); + logger.info("Step 1: Checking Control Tower setup..."); + + /* + List landingZones = ControlTowerActions.listLandingZones(controlTowerClient); + if (landingZones.isEmpty()) { + logger.warn("⚠️ No landing zones found. Control Tower may not be set up."); + logger.warn("Please set up Control Tower in the AWS Console first."); + return; + } + + logger.info("Found {} landing zone(s):", landingZones.size()); + for (LandingZoneSummary landingZone : landingZones) { + logger.info(" - ARN: {}", landingZone.arn()); + } + + waitForInputToContinue(scanner); + + */ + + // Step 2: List available baselines + logger.info(DASHES); + logger.info("Step 2: Listing available baselines..."); + + List baselines = ControlTowerActions.listBaselines(controlTowerClient); + if (baselines.isEmpty()) { + logger.warn("No baselines available."); + } else { + logger.info("Available baselines:"); + for (BaselineSummary baseline : baselines) { + logger.info(" - Name: {}", baseline.name()); + logger.info(" ARN: {}", baseline.arn()); + logger.info(" Description: {}", baseline.description()); + } + } + + waitForInputToContinue(scanner); + /* + + logger.info(DASHES); + logger.info("🎉 Control Tower Basics scenario completed successfully!"); + + + */ + } catch (ControlTowerException e) { + logger.error("Control Tower service error: {}", e.awsErrorDetails().errorMessage()); + throw e; + } catch (Exception e) { + logger.error("Unexpected error: {}", e.getMessage(), e); + throw e; + } + } + + private static void waitForInputToContinue(Scanner scanner) { + while (true) { + System.out.println(""); + System.out.println("Enter 'c' followed by to continue:"); + String input = scanner.nextLine(); + + if (input.trim().equalsIgnoreCase("c")) { + logger.info("Continuing with the program...\n"); + break; + } else { + System.out.println("Invalid input. Please try again."); + } + } + } +} +// snippet-end:[controltower.java2.controltower_scenario.main] \ No newline at end of file diff --git a/javav2/example_code/controltower/src/main/java/com/example/controltower/HelloControlTower.java b/javav2/example_code/controltower/src/main/java/com/example/controltower/HelloControlTower.java new file mode 100644 index 00000000000..aba26c4ee84 --- /dev/null +++ b/javav2/example_code/controltower/src/main/java/com/example/controltower/HelloControlTower.java @@ -0,0 +1,78 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package com.example.controltower; + +import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider; +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.services.controltower.ControlTowerClient; +import software.amazon.awssdk.services.controltower.model.ControlTowerException; +import software.amazon.awssdk.services.controltower.model.ListBaselinesRequest; +import software.amazon.awssdk.services.controltower.paginators.ListBaselinesIterable; +import java.util.ArrayList; +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 + * + * Use the AWS SDK for Java (v2) to create an AWS Control Tower client + * and list all available baselines. + * This example uses the default settings specified in your shared credentials + * and config files. + */ + +// snippet-start:[python.example_code.controltower.Hello] +public class HelloControlTower { + + public static void main(String[] args) { + try { + ControlTowerClient controlTowerClient = ControlTowerClient.builder() + .region(Region.US_EAST_1) + .build() ; + helloControlTower(controlTowerClient); + } catch (ControlTowerException e) { + System.err.println("Control Tower error occurred: " + e.awsErrorDetails().errorMessage()); + } + } + + /** + * Use the AWS SDK for Java (v2) to create an AWS Control Tower client + * and list all available baselines. + * This example uses the default settings specified in your shared credentials + * and config files. + * + * @param controlTowerClient A ControlTowerClient object. This object wraps + * the low-level AWS Control Tower service API. + */ + public static void helloControlTower(ControlTowerClient controlTowerClient) { + System.out.println("Hello, AWS Control Tower! Let's list available baselines:\n"); + + ListBaselinesIterable paginator = controlTowerClient.listBaselinesPaginator( + ListBaselinesRequest.builder().build()); + List baselineNames = new ArrayList<>(); + + try { + paginator.stream() + .flatMap(response -> response.baselines().stream()) + .forEach(baseline -> baselineNames.add(baseline.name())); + + System.out.println(baselineNames.size() + " baseline(s) retrieved."); + for (String baselineName : baselineNames) { + System.out.println("\t" + baselineName); + } + + } catch (ControlTowerException e) { + if ("AccessDeniedException".equals(e.awsErrorDetails().errorCode())) { + System.out.println("Access denied. Please ensure you have the necessary permissions."); + } else { + System.out.println("An error occurred: " + e.getMessage()); + } + } + } +} +// snippet-end:[python.example_code.controltower.Hello] diff --git a/javav2/example_code/controltower/src/main/java/resources/config.properties b/javav2/example_code/controltower/src/main/java/resources/config.properties new file mode 100644 index 00000000000..c18495c2f4c --- /dev/null +++ b/javav2/example_code/controltower/src/main/java/resources/config.properties @@ -0,0 +1,3 @@ +dataAccessRoleArn = +s3Uri = +documentClassifier = diff --git a/javav2/example_code/controltower/src/main/java/resources/log4j2.xml b/javav2/example_code/controltower/src/main/java/resources/log4j2.xml new file mode 100644 index 00000000000..fcef26f34b8 --- /dev/null +++ b/javav2/example_code/controltower/src/main/java/resources/log4j2.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/javav2/example_code/controltower/src/test/java/ControlTowerTest.java b/javav2/example_code/controltower/src/test/java/ControlTowerTest.java new file mode 100644 index 00000000000..c16e0049dc0 --- /dev/null +++ b/javav2/example_code/controltower/src/test/java/ControlTowerTest.java @@ -0,0 +1,51 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import com.example.controltower.ControlTowerActions; +import com.example.controltower.HelloControlTower; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.TestMethodOrder; +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.services.controltower.ControlTowerClient; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + +@TestInstance(TestInstance.Lifecycle.PER_METHOD) +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +public class ControlTowerTest { + private static ControlTowerClient controlTowerClient; + + @BeforeAll + public static void setUp() { + controlTowerClient = ControlTowerClient.builder() + .region(Region.US_EAST_1) + .build(); + } + + @Test + @Order(1) + public void testHelloService() { + assertDoesNotThrow(() -> { + HelloControlTower.helloControlTower(controlTowerClient); + }); + System.out.println("Test 1 passed"); + } + + @Test + @Order(2) + public void testControlTowerActions() { + assertDoesNotThrow(() -> { + ControlTowerActions.listLandingZones(controlTowerClient); + ControlTowerActions.listBaselines(controlTowerClient); + ControlTowerActions.listEnabledBaselines(controlTowerClient); + + // Note: Enable/disable operations require valid ARNs and are not tested here + // to avoid modifying the actual Control Tower configuration + }); + System.out.println("Test 2 passed"); + } +} \ No newline at end of file From 57bc663956837d6a9c2ffd0336e138cdacc9a93e Mon Sep 17 00:00:00 2001 From: Scott Macdonald Date: Thu, 4 Dec 2025 11:17:36 -0500 Subject: [PATCH 2/4] Updated the Control Tower YAML file --- .doc_gen/metadata/controltower_metadata.yaml | 118 ++++++++++++++++++ .../controltower/HelloControlTower.java | 1 - 2 files changed, 118 insertions(+), 1 deletion(-) diff --git a/.doc_gen/metadata/controltower_metadata.yaml b/.doc_gen/metadata/controltower_metadata.yaml index 083079b4db1..1029f90fcc3 100644 --- a/.doc_gen/metadata/controltower_metadata.yaml +++ b/.doc_gen/metadata/controltower_metadata.yaml @@ -4,6 +4,15 @@ controltower_Hello: synopsis: get started using &CTower;. category: Hello languages: + Java: + versions: + - sdk_version: 2 + github: javav2/example_code/controltower + sdkguide: + excerpts: + - description: + snippet_tags: + - controltower.java2.hello.main Python: versions: - sdk_version: 3 @@ -25,6 +34,15 @@ controltower_Hello: controltower_ListBaselines: languages: + Java: + versions: + - sdk_version: 2 + github: javav2/example_code/controltower + sdkguide: + excerpts: + - description: + snippet_tags: + - controltower.java2.list_baselines.main Python: versions: - sdk_version: 3 @@ -47,6 +65,15 @@ controltower_ListBaselines: controltower_ListEnabledBaselines: languages: + Java: + versions: + - sdk_version: 2 + github: javav2/example_code/controltower + sdkguide: + excerpts: + - description: + snippet_tags: + - controltower.java2.list_enabled_baselines.main Python: versions: - sdk_version: 3 @@ -69,6 +96,15 @@ controltower_ListEnabledBaselines: controltower_EnableBaseline: languages: + Java: + versions: + - sdk_version: 2 + github: javav2/example_code/controltower + sdkguide: + excerpts: + - description: + snippet_tags: + - controltower.java2.enable_baseline.main Python: versions: - sdk_version: 3 @@ -91,6 +127,15 @@ controltower_EnableBaseline: controltower_ResetEnabledBaseline: languages: + Java: + versions: + - sdk_version: 2 + github: javav2/example_code/controltower + sdkguide: + excerpts: + - description: + snippet_tags: + - controltower.java2.reset_enabled_baseline.main Python: versions: - sdk_version: 3 @@ -113,6 +158,15 @@ controltower_ResetEnabledBaseline: controltower_DisableBaseline: languages: + Java: + versions: + - sdk_version: 2 + github: javav2/example_code/controltower + sdkguide: + excerpts: + - description: + snippet_tags: + - controltower.java2.disable_baseline.main Python: versions: - sdk_version: 3 @@ -135,6 +189,15 @@ controltower_DisableBaseline: controltower_ListEnabledControls: languages: + Java: + versions: + - sdk_version: 2 + github: javav2/example_code/controltower + sdkguide: + excerpts: + - description: + snippet_tags: + - controltower.java2.list_enabled_controls.main Python: versions: - sdk_version: 3 @@ -157,6 +220,15 @@ controltower_ListEnabledControls: controltower_EnableControl: languages: + Java: + versions: + - sdk_version: 2 + github: javav2/example_code/controltower + sdkguide: + excerpts: + - description: + snippet_tags: + - controltower.java2.enable_control.main Python: versions: - sdk_version: 3 @@ -179,6 +251,15 @@ controltower_EnableControl: controltower_GetControlOperation: languages: + Java: + versions: + - sdk_version: 2 + github: javav2/example_code/controltower + sdkguide: + excerpts: + - description: + snippet_tags: + - controltower.java2.get_control_operation.main Python: versions: - sdk_version: 3 @@ -201,6 +282,15 @@ controltower_GetControlOperation: controltower_DisableControl: languages: + Java: + versions: + - sdk_version: 2 + github: javav2/example_code/controltower + sdkguide: + excerpts: + - description: + snippet_tags: + - controltower.java2.disable_control.main Python: versions: - sdk_version: 3 @@ -223,6 +313,15 @@ controltower_DisableControl: controltower_ListLandingZones: languages: + Java: + versions: + - sdk_version: 2 + github: javav2/example_code/controltower + sdkguide: + excerpts: + - description: + snippet_tags: + - controltower.java2.list_landing_zones.main Python: versions: - sdk_version: 3 @@ -245,6 +344,15 @@ controltower_ListLandingZones: controltower_GetBaselineOperation: languages: + Java: + versions: + - sdk_version: 2 + github: javav2/example_code/controltower + sdkguide: + excerpts: + - description: + snippet_tags: + - controltower.java2.list_landing_zones.main Python: versions: - sdk_version: 3 @@ -272,6 +380,16 @@ controltower_Scenario: - List, enable, get, and disable controls. category: Basics languages: + Java: + versions: + - sdk_version: 2 + github: javav2/example_code/controltower + sdkguide: + excerpts: + - description: un an interactive scenario demonstrating &CTowerlong; features. + snippet_tags: + - controltower.java2.controltower_scenario.main + - controltower.java2.controltower_actions.main Python: versions: - sdk_version: 3 diff --git a/javav2/example_code/controltower/src/main/java/com/example/controltower/HelloControlTower.java b/javav2/example_code/controltower/src/main/java/com/example/controltower/HelloControlTower.java index aba26c4ee84..5e948676491 100644 --- a/javav2/example_code/controltower/src/main/java/com/example/controltower/HelloControlTower.java +++ b/javav2/example_code/controltower/src/main/java/com/example/controltower/HelloControlTower.java @@ -3,7 +3,6 @@ package com.example.controltower; -import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider; import software.amazon.awssdk.regions.Region; import software.amazon.awssdk.services.controltower.ControlTowerClient; import software.amazon.awssdk.services.controltower.model.ControlTowerException; From e4099ba090b9123378fce8f3e3df527094f23018 Mon Sep 17 00:00:00 2001 From: Scott Macdonald Date: Thu, 4 Dec 2025 14:14:44 -0500 Subject: [PATCH 3/4] fixed a tag issue --- .../main/java/com/example/controltower/HelloControlTower.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/javav2/example_code/controltower/src/main/java/com/example/controltower/HelloControlTower.java b/javav2/example_code/controltower/src/main/java/com/example/controltower/HelloControlTower.java index 5e948676491..d3c223dd182 100644 --- a/javav2/example_code/controltower/src/main/java/com/example/controltower/HelloControlTower.java +++ b/javav2/example_code/controltower/src/main/java/com/example/controltower/HelloControlTower.java @@ -25,7 +25,7 @@ * and config files. */ -// snippet-start:[python.example_code.controltower.Hello] +// snippet-start:[controltower.java2.hello.main] public class HelloControlTower { public static void main(String[] args) { @@ -74,4 +74,4 @@ public static void helloControlTower(ControlTowerClient controlTowerClient) { } } } -// snippet-end:[python.example_code.controltower.Hello] +// snippet-end:[controltower.java2.hello.main] From 84dcb641c06802c9e20667acd06f8a33016f97a0 Mon Sep 17 00:00:00 2001 From: Scott Macdonald Date: Fri, 5 Dec 2025 09:45:41 -0500 Subject: [PATCH 4/4] fixed a tag issue om YAML --- .doc_gen/metadata/controltower_metadata.yaml | 2 +- javav2/example_code/controltower/README.md | 135 +++++++++++-------- 2 files changed, 77 insertions(+), 60 deletions(-) diff --git a/.doc_gen/metadata/controltower_metadata.yaml b/.doc_gen/metadata/controltower_metadata.yaml index 1029f90fcc3..01f3fcfc2ab 100644 --- a/.doc_gen/metadata/controltower_metadata.yaml +++ b/.doc_gen/metadata/controltower_metadata.yaml @@ -386,7 +386,7 @@ controltower_Scenario: github: javav2/example_code/controltower sdkguide: excerpts: - - description: un an interactive scenario demonstrating &CTowerlong; features. + - description: Run an interactive scenario demonstrating &CTowerlong; features. snippet_tags: - controltower.java2.controltower_scenario.main - controltower.java2.controltower_actions.main diff --git a/javav2/example_code/controltower/README.md b/javav2/example_code/controltower/README.md index 400f3615ae3..09d4fcc4a63 100644 --- a/javav2/example_code/controltower/README.md +++ b/javav2/example_code/controltower/README.md @@ -2,101 +2,118 @@ ## Overview -This is a workspace where you can find the following AWS SDK for Java 2.x AWS Control Tower examples. +Shows how to use the AWS SDK for Java 2.x to work with AWS Control Tower. + + + + +_AWS Control Tower enables you to enforce and manage governance rules for security, operations, and compliance at scale across all your organizations and accounts._ ## ⚠ Important -* Running this code might result in charges to your AWS account. +* Running this code might result in charges to your AWS account. For more details, see [AWS Pricing](https://aws.amazon.com/pricing/) and [Free Tier](https://aws.amazon.com/free/). * Running the tests might result in charges to your AWS account. -* We recommend that you grant your code least privilege. +* We recommend that you grant your code least privilege. At most, grant only the minimum permissions required to perform the task. For more information, see [Grant least privilege](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege). +* This code is not tested in every AWS Region. For more information, see [AWS Regional Services](https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services). + + + ## Code examples -### Actions +### Prerequisites + +For prerequisites, see the [README](../../README.md#Prerequisites) in the `javav2` folder. + -The following examples show you how to perform actions using the AWS SDK for Java 2.x. + + -* [List landing zones](src/main/java/com/example/controltower/ControlTowerActions.java) (`ListLandingZones`) -* [List baselines](src/main/java/com/example/controltower/ControlTowerActions.java) (`ListBaselines`) -* [List enabled baselines](src/main/java/com/example/controltower/ControlTowerActions.java) (`ListEnabledBaselines`) -* [Enable baseline](src/main/java/com/example/controltower/ControlTowerActions.java) (`EnableBaseline`) -* [Disable baseline](src/main/java/com/example/controltower/ControlTowerActions.java) (`DisableBaseline`) -* [Get baseline operation](src/main/java/com/example/controltower/ControlTowerActions.java) (`GetBaselineOperation`) -* [List enabled controls](src/main/java/com/example/controltower/ControlTowerActions.java) (`ListEnabledControls`) -* [Enable control](src/main/java/com/example/controltower/ControlTowerActions.java) (`EnableControl`) -* [Disable control](src/main/java/com/example/controltower/ControlTowerActions.java) (`DisableControl`) -* [Get control operation](src/main/java/com/example/controltower/ControlTowerActions.java) (`GetControlOperation`) +### Get started -### Scenarios +- [Hello AWS Control Tower](src/main/java/com/example/controltower/HelloControlTower.java#L28) (`ListBaselines`) -The following examples show you how to implement common scenarios. -* [Learn the basics](src/main/java/com/example/controltower/ControlTowerScenario.java) - Learn the basics by checking setup, managing baselines and controls. +### Basics -### Hello +Code examples that show you how to perform the essential operations within a service. -* [Hello Control Tower](src/main/java/com/example/controltower/HelloControlTower.java) - Get started with AWS Control Tower. +- [Learn the basics](src/main/java/com/example/controltower/ControlTowerActions.java) -## Prerequisites -- You must have an AWS account, and have your default credentials and AWS Region configured. -- Java 17 or later -- Maven 3.6 or later -- AWS Control Tower must be set up in your account +### Single actions -## Install +Code excerpts that show you how to call individual service functions. -To build and run the examples, navigate to the directory that contains a `pom.xml` file and run the following command: +- [DisableBaseline](src/main/java/com/example/controltower/ControlTowerActions.java#L241) +- [DisableControl](src/main/java/com/example/controltower/ControlTowerActions.java#L431) +- [EnableBaseline](src/main/java/com/example/controltower/ControlTowerActions.java#L188) +- [EnableControl](src/main/java/com/example/controltower/ControlTowerActions.java#L377) +- [GetBaselineOperation](src/main/java/com/example/controltower/ControlTowerActions.java#L38) +- [GetControlOperation](src/main/java/com/example/controltower/ControlTowerActions.java#L474) +- [ListBaselines](src/main/java/com/example/controltower/ControlTowerActions.java#L88) +- [ListEnabledBaselines](src/main/java/com/example/controltower/ControlTowerActions.java#L138) +- [ListEnabledControls](src/main/java/com/example/controltower/ControlTowerActions.java#L324) +- [ListLandingZones](src/main/java/com/example/controltower/ControlTowerActions.java#L38) +- [ResetEnabledBaseline](src/main/java/com/example/controltower/ControlTowerActions.java#L548) -``` -mvn compile -``` + + + ## Run the examples ### Instructions -All examples can be run individually. For example: -``` -mvn exec:java -Dexec.mainClass="com.example.controltower.HelloControlTower" -Dexec.args="us-east-1" -``` + + -### Hello Control Tower +#### Hello AWS Control Tower This example shows you how to get started using AWS Control Tower. -``` -mvn exec:java -Dexec.mainClass="com.example.controltower.HelloControlTower" -Dexec.args="us-east-1" -``` -### Learn the basics +#### Learn the basics + +This example shows you how to do the following: + +- List landing zones. +- List, enable, get, reset, and disable baselines. +- List, enable, get, and disable controls. + + + -This interactive scenario runs at a command prompt and shows you how to use AWS Control Tower to do the following: -1. Check Control Tower setup and list landing zones -2. List available baselines for governance -3. List currently enabled baselines -4. Enable baselines for organizational units -5. List and enable controls for compliance -6. Monitor operation status -7. Clean up resources + + -``` -mvn exec:java -Dexec.mainClass="com.example.controltower.ControlTowerScenario" -Dexec.args="us-east-1" -``` -## Run the tests +### Tests -Unit tests in this module use JUnit 5. To run all of the tests, -run the following in your [GitHub root]/javav2/example_code/controltower folder. +⚠ Running tests might result in charges to your AWS account. -``` -mvn test -``` + +To find instructions for running these tests, see the [README](../../README.md#Tests) +in the `javav2` folder. + + + + + ## Additional resources -- [AWS Control Tower User Guide](https://docs.aws.amazon.com/controltower/latest/userguide/) -- [AWS Control Tower API Reference](https://docs.aws.amazon.com/controltower/latest/APIReference/) -- [AWS SDK for Java 2.x (AWS Control Tower)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/controltower/package-summary.html) \ No newline at end of file +- [AWS Control Tower User Guide](https://docs.aws.amazon.com/controltower/latest/userguide/what-is-control-tower.html) +- [AWS Control Tower API Reference](https://docs.aws.amazon.com/controltower/latest/APIReference/Welcome.html) +- [SDK for Java 2.x AWS Control Tower reference](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/controltower/package-summary.html) + + + + +--- + +Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0