|
1 | | -## My Project |
| 1 | +## AWS CloudFormation Java Plugin Test Framework |
2 | 2 |
|
3 | | -TODO: Fill this README out! |
| 3 | +This provides an easier foundation for testing handlers for CRUD along with integated support for KMS. Developers |
| 4 | +can easily write sequence of CRUD lifecycle test with expectations and will be tested. There is also a mock based |
| 5 | +test based for local unit testing. |
4 | 6 |
|
5 | | -Be sure to: |
| 7 | +The framework leverages support for [Named Profiles](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html) that allows |
| 8 | +developers to test using roles and credentials, to test the exact way in which they expect to work inside CFN for their handlers. Here is the |
| 9 | +sample for now this can be used for injecting credentials using the role based profile specified. |
| 10 | + |
| 11 | +**Sample AWS Named Profile Setup** |
| 12 | + |
| 13 | + ~/.aws/credentials |
| 14 | + ... |
| 15 | + **cfn-assume-role** |
| 16 | + aws_access_key_id=[YOUR_ACCESS_KEY_ID] |
| 17 | + aws_secret_access_key=[YOUR_SECRET_ACCESS_KEY] |
| 18 | + ... |
| 19 | + |
| 20 | + ~/.aws/config |
| 21 | + [profilei **cfn-integration**] |
| 22 | + role_arn = arn:aws:iam::<AWS_ACCOUNT_ID>:role/<ROLE_NAME> |
| 23 | + source_profile = *cfn-assume-role* |
| 24 | + |
| 25 | +**Using the named profile for testing** |
| 26 | + |
| 27 | +<b>How to setup IAM managed policies, user and role credentials for above setup</b> |
| 28 | + |
| 29 | +<ol> |
| 30 | + <li><u>Create a Managed Policy for the user</u> |
| 31 | + Here the credentials section has an user credentials that is provided with only sts:assumeRole |
| 32 | + permission. Here is the policy that is associated with cfn-assume-role user in the account. |
| 33 | + |
| 34 | + <pre> |
| 35 | + { |
| 36 | + "Version": "2012-10-17", |
| 37 | + "Statement": [ |
| 38 | + { |
| 39 | + "Sid": "VisualEditor0", |
| 40 | + "Effect": "Allow", |
| 41 | + "Action": "sts:AssumeRole", |
| 42 | + "Resource": "*" |
| 43 | + } |
| 44 | + ] |
| 45 | + } |
| 46 | + </pre> |
| 47 | + </li> |
| 48 | + <li><u>Create a Managed Policy for the services you are testing with</u> |
| 49 | + This is needed to test all integration for CRUD+L needed for logs. You can always narrow it down further. |
| 50 | + Recommended approach is to define the above policies as customer managed policies in IAM in the account and |
| 51 | + associate with the role and users as appropriate. This is an example policy to test CloudWatch LogGroup |
| 52 | + and KMS integration |
| 53 | + |
| 54 | + <pre> |
| 55 | + { |
| 56 | + "Version": "2012-10-17", |
| 57 | + "Statement": [ |
| 58 | + { |
| 59 | + "Sid": "VisualEditor0", |
| 60 | + "Effect": "Allow", |
| 61 | + "Action": [ |
| 62 | + "kms:*", |
| 63 | + "[INSERT_YOUR_SERVICE]:*" |
| 64 | + ], |
| 65 | + "Resource": "*" |
| 66 | + } |
| 67 | + ] |
| 68 | + } |
| 69 | + </pre> |
| 70 | + </li> |
| 71 | + <li><u>Create a user cfn-assume-role with Managed Policy create in (1)</u> |
| 72 | + Download the access_key, secret_key for this user and add it to the credentials file under |
| 73 | + cfn-assume-role |
| 74 | + </li> |
| 75 | + <li><u>Create cfn-integration role with the con</u></li> |
| 76 | + <li><u>Update your poml.xml</u> |
| 77 | + Here is how to use this for unit testing. First add the dependency to you maven <u>pom.xml</u> |
| 78 | + |
| 79 | + <pre>{@code |
| 80 | + <!-- for sts support to assume role setup above --> |
| 81 | + <dependency> |
| 82 | + <groupId>software.amazon.awssdk</groupId> |
| 83 | + <artifactId>sts</artifactId> |
| 84 | + <version>2.10.91</version> |
| 85 | + <scope>test</scope> |
| 86 | + </dependency> |
| 87 | + |
| 88 | + <!-- for kms key handling support --> |
| 89 | + <dependency> |
| 90 | + <groupId>software.amazon.awssdk</groupId> |
| 91 | + <artifactId>kms</artifactId> |
| 92 | + <version>2.10.91</version> |
| 93 | + </dependency> |
| 94 | + |
| 95 | + <dependency> |
| 96 | + <groupId>software.amazon.cloudformation.test</groupId> |
| 97 | + <artifactId>cloudformation-cli-java-plugin-testing-support</artifactId> |
| 98 | + <version>1.0-SNAPSHOT</version> |
| 99 | + <scope>test</scope> |
| 100 | + </dependency> |
| 101 | + }</pre> |
| 102 | + </li> |
| 103 | +</ol> |
| 104 | + |
| 105 | +<b>How to use it?</b> |
| 106 | +<p> |
| 107 | +Sample code illustrating how to use this setup with KMS. To make scheduling the key for delete in case of abort to |
| 108 | +testing the key is aliased using the alias name [KEY_ALIAS](src/software/amazon/cloudformation/test/KMSKeyEnabledServiceIntegrationTestBase.java) |
| 109 | +The test when it runs to completion will automatically move the KMS key for delete. If test is rerun |
| 110 | +the KMS key will be made active again for the duration of he test run and disable and scheduled to be deleted. |
| 111 | +Regardless of how many times we run these tests there is only one key with the alias managed in the account. |
| 112 | + |
| 113 | +To ensure that this test does not run for build environments like Travis etc. we enable is using system properties using |
| 114 | +{@link org.junit.jupiter.api.condition.EnabledIfSystemProperty}. To run the test with maven we would |
| 115 | +use |
| 116 | + |
| 117 | +``` |
| 118 | + mvn -Ddesktop=true test |
| 119 | +``` |
| 120 | + |
| 121 | +to run the test code shown below |
| 122 | + |
| 123 | +```java |
| 124 | + |
| 125 | + package software.amazon.logs.loggroup; |
| 126 | + |
| 127 | + import org.junit.jupiter.api.*; |
| 128 | + import static org.assertj.core.api.Assertions.assertThat; |
| 129 | + |
| 130 | + import software.amazon.awssdk.auth.credentials.AwsSessionCredentials; |
| 131 | + import software.amazon.cloudformation.proxy.*; |
| 132 | + import software.amazon.cloudformation.test.*; |
| 133 | + |
| 134 | + @TestMethodOrder(MethodOrderer.OrderAnnotation.class) // we order the tests to follows C to U to D |
| 135 | + @ExtendWith(InjectProfileCredentials.class) // extend with profile based credentials |
| 136 | + @EnabledIfSystemProperty(named = "desktop", matches = "true") |
| 137 | + @TestInstance(TestInstance.Lifecycle.PER_CLASS) // IMP PER_CLASS |
| 138 | + public class LifecycleTest extends KMSKeyEnabledServiceIntegrationTestBase { |
| 139 | + |
| 140 | + // |
| 141 | + // At the annotation software.amazon.cloudformation.test.annotations.InjectSessionCredentials to the |
| 142 | + // constructor. This will inject the role's credentials |
| 143 | + // |
| 144 | + public LifecycleTest(@InjectSessionCredentials(profile = "cfn-integration") AwsSessionCredentials awsCredentials) { |
| 145 | + super(awsCredentials, ((apiCall, provided) -> override)); |
| 146 | + } |
| 147 | + ... |
| 148 | + ... |
| 149 | + @Order(300) |
| 150 | + @Test |
| 151 | + void addValidKMS() { |
| 152 | + final ResourceModel current = ResourceModel.builder().arn(model.getArn()) |
| 153 | + .logGroupName(model.getLogGroupName()).retentionInDays(model.getRetentionInDays()).build(); |
| 154 | + // Access a KMS key. The test ensures to only create one key and recycles despite any number of runs |
| 155 | + String kmsKeyId = getKmsKeyId(); |
| 156 | + String kmsKeyArn = getKmsKeyArn(); |
| 157 | + // Add your service to use KMS key |
| 158 | + addServiceAccess("logs", kmsKeyId); |
| 159 | + model.setKMSKey(kmsKeyArn); |
| 160 | + ProgressEvent<ResourceModel, CallbackContext> event = new UpdateHandler() |
| 161 | + .handleRequest(getProxy(), createRequest(model, current), null, getLoggerProxy()); |
| 162 | + assertThat(event.isSuccess()).isTrue(); |
| 163 | + model = event.getResourceModel(); |
| 164 | + } |
| 165 | + ... |
| 166 | + ... |
| 167 | + } |
| 168 | +``` |
| 169 | + |
| 170 | +**See Also** |
| 171 | + |
| 172 | +software.amazon.cloudformation.test.KMSKeyEnabledServiceIntegrationTestBase |
| 173 | +software.amazon.cloudformation.test.AbstractLifecycleTestBase |
6 | 174 |
|
7 | | -* Change the title in this README |
8 | | -* Edit your repository description on GitHub |
9 | 175 |
|
10 | 176 | ## License |
11 | 177 |
|
12 | 178 | This project is licensed under the Apache-2.0 License. |
13 | | - |
|
0 commit comments