AWS code-library documentation change
Summary
Added detailed .NET code example demonstrating AWS Control Tower operations including managing landing zones, baselines, controls, and organizational units with interactive scenario flow
Security assessment
The changes demonstrate security-related features of AWS Control Tower (baseline management, control enforcement, organizational unit setup) but do not address a specific security vulnerability. The code shows proper security practices for governance rather than fixing a security issue.
Diff
diff --git a/code-library/latest/ug/controltower_example_controltower_Scenario_section.md b/code-library/latest/ug/controltower_example_controltower_Scenario_section.md index d6fc61cef..a7a1b93ce 100644 --- a//code-library/latest/ug/controltower_example_controltower_Scenario_section.md +++ b//code-library/latest/ug/controltower_example_controltower_Scenario_section.md @@ -9 +9 @@ There are more AWS SDK examples available in the [AWS Doc SDK Examples](https:// -The following code example shows how to: +The following code examples show how to: @@ -19,0 +20,823 @@ The following code example shows how to: +.NET + + +**SDK for .NET (v4)** + + +###### Note + +There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/dotnetv4/ControlTower#code-examples). + +Run an interactive scenario demonstrating AWS Control Tower features. + + + using Amazon.ControlCatalog; + using Amazon.ControlTower; + using Amazon.ControlTower.Model; + using Amazon.Organizations; + using Amazon.Organizations.Model; + using Amazon.SecurityToken; + using Amazon.SecurityToken.Model; + using ControlTowerActions; + using Microsoft.Extensions.DependencyInjection; + using Microsoft.Extensions.Hosting; + using Microsoft.Extensions.Logging; + + namespace ControlTowerBasics; + + /// <summary> + /// Scenario class for AWS Control Tower basics. + /// </summary> + public class ControlTowerBasics + { + public static bool isInteractive = true; + public static ILogger logger = null!; + public static IAmazonOrganizations? orgClient = null; + public static IAmazonSecurityTokenService? stsClient = null; + public static ControlTowerWrapper? wrapper = null; + private static string? ouArn; + private static bool useLandingZone = false; + + /// <summary> + /// Main entry point for the AWS Control Tower basics scenario. + /// </summary> + /// <param name="args">Command line arguments.</param> + public static async Task Main(string[] args) + { + using var host = Host.CreateDefaultBuilder(args) + .ConfigureServices((_, services) => + services.AddAWSService<IAmazonControlTower>() + .AddAWSService<IAmazonControlCatalog>() + .AddAWSService<IAmazonOrganizations>() + .AddAWSService<IAmazonSecurityTokenService>() + .AddTransient<ControlTowerWrapper>() + ) + .Build(); + + logger = LoggerFactory.Create(builder => { builder.AddConsole(); }) + .CreateLogger<ControlTowerBasics>(); + + wrapper = host.Services.GetRequiredService<ControlTowerWrapper>(); + orgClient = host.Services.GetRequiredService<IAmazonOrganizations>(); + stsClient = host.Services.GetRequiredService<IAmazonSecurityTokenService>(); + + await RunScenario(); + } + + /// <summary> + /// Runs the example scenario. + /// </summary> + public static async Task RunScenario() + { + Console.WriteLine(new string('-', 88)); + Console.WriteLine("\tWelcome to the AWS Control Tower with ControlCatalog example scenario."); + Console.WriteLine(new string('-', 88)); + Console.WriteLine("This demo will walk you through working with AWS Control Tower for landing zones,"); + Console.WriteLine("managing baselines, and working with controls."); + + try + { + var accountId = (await stsClient!.GetCallerIdentityAsync(new GetCallerIdentityRequest())).Account; + Console.WriteLine($"\nAccount ID: {accountId}"); + + Console.WriteLine("\nSome demo operations require the use of a landing zone."); + Console.WriteLine("You can use an existing landing zone or opt out of these operations in the demo."); + Console.WriteLine("For instructions on how to set up a landing zone,"); + Console.WriteLine("see https://docs.aws.amazon.com/controltower/latest/userguide/getting-started-from-console.html"); + + // List available landing zones + var landingZones = await wrapper!.ListLandingZonesAsync(); + if (landingZones.Count > 0) + { + Console.WriteLine("\nAvailable Landing Zones:"); + for (int i = 0; i < landingZones.Count; i++) + { + Console.WriteLine($"{i + 1}. {landingZones[i].Arn}"); + } + + Console.Write($"\nDo you want to use the first landing zone in the list ({landingZones[0].Arn})? (y/n): "); + if (GetUserConfirmation()) + { + useLandingZone = true; + Console.WriteLine($"Using landing zone: {landingZones[0].Arn}"); + ouArn = await SetupOrganizationAsync(); + } + } + + // Managing Baselines + Console.WriteLine("\nManaging Baselines:"); + var baselines = await wrapper.ListBaselinesAsync(); + Console.WriteLine("\nListing available Baselines:"); + BaselineSummary? controlTowerBaseline = null; + foreach (var baseline in baselines) + { + if (baseline.Name == "AWSControlTowerBaseline") + controlTowerBaseline = baseline; + Console.WriteLine($" - {baseline.Name}"); + } + + EnabledBaselineSummary? identityCenterBaseline = null; + string? baselineArn = null; + + if (useLandingZone && ouArn != null) + { + Console.WriteLine("\nListing enabled baselines:"); + var enabledBaselines = await wrapper.ListEnabledBaselinesAsync(); + foreach (var baseline in enabledBaselines) + { + if (baseline.BaselineIdentifier.Contains("baseline/LN25R72TTG6IGPTQ")) + identityCenterBaseline = baseline; + Console.WriteLine($" - {baseline.BaselineIdentifier}"); + } + + if (controlTowerBaseline != null) + { + Console.Write("\nDo you want to enable the Control Tower Baseline? (y/n): "); + if (GetUserConfirmation()) + { + Console.WriteLine("\nEnabling Control Tower Baseline."); + var icBaselineArn = identityCenterBaseline?.Arn; + baselineArn = await wrapper.EnableBaselineAsync(ouArn, + controlTowerBaseline.Arn, "4.0", icBaselineArn ?? ""); + var alreadyEnabled = false; + if (baselineArn != null) + { + Console.WriteLine($"Enabled baseline ARN: {baselineArn}"); + } + else + { + // Find the enabled baseline + foreach (var enabled in enabledBaselines) + { + if (enabled.BaselineIdentifier == controlTowerBaseline.Arn) + { + baselineArn = enabled.Arn; + break; + } + } + + alreadyEnabled = true; + Console.WriteLine("No change, the selected baseline was already enabled."); + } + + if (baselineArn != null) + { + Console.Write("\nDo you want to reset the Control Tower Baseline? (y/n): "); + if (GetUserConfirmation()) + { + Console.WriteLine($"\nResetting Control Tower Baseline: {baselineArn}"); + var operationId = await wrapper.ResetEnabledBaselineAsync(baselineArn); + Console.WriteLine($"Reset baseline operation id: {operationId}"); + } + + Console.Write("\nDo you want to disable the Control Tower Baseline? (y/n): "); + if (GetUserConfirmation()) + { + Console.WriteLine($"Disabling baseline ARN: {baselineArn}"); + var operationId = await wrapper.DisableBaselineAsync(baselineArn); + Console.WriteLine($"Disabled baseline operation id: {operationId}"); + if (alreadyEnabled) + { + Console.WriteLine($"\nRe-enabling Control Tower Baseline: {baselineArn}"); + // Re-enable the Control Tower baseline if it was originally enabled. + await wrapper.EnableBaselineAsync(ouArn, + controlTowerBaseline.Arn, "4.0", icBaselineArn ?? ""); + } + } + } + } + } + } + + // Managing Controls