Categories
AWS Java

Getting Started with AWS

Create an IAM user

I want to start with some practical experiences in AWS, so I go to https://aws.amazon.com, login with my Root user and open the Identity and Access Management (IAM ), where I create aa new IAM user, that I call "MyFirstProgrammaticAccessTestUser", because the user is of access type Programmatic access. For now, I do not add the user to any group and add only one tag (that I name tag-key) to the user.
AWS is warning, that this user has not permissons, but this is fine for now, I will add any permission as soon as the user needs one.
Finally I note down the user name, Access key ID and the secret access key.

Set up AWS credentials and region

I am working on a Windows machine, so I create a folder .aws in C:\Users\USERNAME. In this folder I create a file credentials:

[default]
aws_access_key_id = your_access_key_id
aws_secret_access_key = your_secret_access_key

To set the default AWS Region I have to create another file in .aws folder: config:

[default]
region = eu-central-1

Additionally I have to set this information as environment variables.

I am really not sure, if this is the correct way to set this environment variables, but hey, this is only a test.

AWS SDK

I have to go to https://github.com/aws/aws-sdk-java-v2 to get the Clone with HTTPS URL.
Then open Eclipse and use the IMPORT dialog to import the project from GIT.
After checkout use the Configure -> Convert to Maven project dialog.
Then I tried Run as -> Maven install. But this results in a Build Failure:

[ERROR] Failed to execute goal com.github.spotbugs:spotbugs-maven-plugin:3.1.11:spotbugs (spotbugs) on project annotations: Execution spotbugs of goal com.github.spotbugs:spotbugs-maven-plugin:3.1.11:spotbugs failed: java.lang.IllegalArgumentException: Unsupported class file major version 57 -> [Help 1]

I found a clue, that I have to use Java 11 instead of my Java 13. So I downloaded a Java 11 JDK and added it to my Eclipse.
But unfortunately I have no clue, how to tell the embedded Eclipse Maven to use this Java 11 instead of Java 13. Great....NOT

Next try: Start a WSL Bash. Need to install Java and Maven first:

sudo apt install -y openjdk-11-jre maven
cd /mnt/[...]/aws-sdk-java-v2
mvn clean install

Now it took 15 minutes to run until it ends wit an ERROR: There are test failures.

While I was waiting for the WSL-Maven to finish, I figured out, how to tell the Eclipse-Maven to run with the Java 11: I have to create a new Run Configuration where I explicite select the JRE:

The Eclipse-Maven also ends with an ERROR: There are test failures.

But for today I am fine with this result.

Create an AWS Maven Project

I create a new Maven project in Eclipse where I pull in the entire AWS SDK. This is not a good choice for a real world application, where you should only pull in components you need, but for a test project it's a good start.
This is my pom.xml:


    4.0.0
    test
    aws
    0.0.1-SNAPSHOT
    war

    
        1.8
        UTF-8
        2.14.7
    

    
        
            
                software.amazon.awssdk
                bom
                ${aws.java.sdk.version}
                pom
                import
            
        
    

    
        
            software.amazon.awssdk
            aws-sdk-java
            ${aws.java.sdk.version}
        
        
            org.apache.tomcat
            tomcat-catalina
            8.5.33
            provided
        
    

    
        
            
                org.apache.maven.plugins
                maven-compiler-plugin
                3.8.0
                
                    ${java.version}
                    ${java.version}
                
            
            
                org.apache.maven.plugins
                maven-war-plugin
                3.2.2
                
                    false
                    ROOT
                    ROOT
                
            
        
    

Add AWS SDK Logging

I wanted to add some logging so I put Log4J Libs dependencies to pom.xml and create a log4j2.xml file for configuration in src/main/resources folder.

log4j2.xml:



  
    
      
    
  

  
    
     
    
    
    
    
  

pom.xml:

   
        2.13.3
    

    
        
            org.apache.logging.log4j
            log4j-core
            ${org.apache.logging.log4j.version}
        
        
            org.apache.logging.log4j
            log4j-api
            ${org.apache.logging.log4j.version}
        
        
            org.apache.logging.log4j
            log4j-slf4j-impl
            ${org.apache.logging.log4j.version}
        
    

First Test Application

A fist simple Test application to get some CloudeWatch metrics:

package aws;

import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.cloudwatch.CloudWatchClient;
import software.amazon.awssdk.services.cloudwatch.model.ListMetricsRequest;
import software.amazon.awssdk.services.cloudwatch.model.ListMetricsResponse;
import software.amazon.awssdk.services.cloudwatch.model.Metric;

public class TestMain {

    public static void main(String[] args) {
        String namespace = "";
        Region region = Region.EU_CENTRAL_1;
        CloudWatchClient cw = CloudWatchClient.builder()
                .region(region)
                .build();
        listMets(cw, namespace) ;
    }
    public static void listMets( CloudWatchClient cw, String namespace) {

        boolean done = false;
        String nextToken = null;

        while(!done) {

            ListMetricsResponse response;

            if (nextToken == null) {
                ListMetricsRequest request = ListMetricsRequest.builder()
                        .namespace(namespace)
                        .build();

                response = cw.listMetrics(request);
            } else {
                ListMetricsRequest request = ListMetricsRequest.builder()
                        .namespace(namespace)
                        .nextToken(nextToken)
                        .build();

                response = cw.listMetrics(request);
            }

            for (Metric metric : response.metrics()) {
                System.out.printf(
                        "Retrieved metric %s", metric.metricName());
                System.out.println();
            }

            if(response.nextToken() == null) {
                done = true;
            } else {
                nextToken = response.nextToken();
            }
        }
    }
}

Result:

020-09-01 19:23:07 [main] DEBUG software.amazon.awssdk.request:84 - Sending Request: DefaultSdkHttpFullRequest(httpMethod=POST, protocol=https, host=monitoring.eu-central-1.amazonaws.com, encodedPath=, headers=[amz-sdk-invocation-id, Content-Length, Content-Type, User-Agent], queryParameters=[])
2020-09-01 19:23:08 [main] DEBUG software.amazon.awssdk.request:84 - Received error response: software.amazon.awssdk.services.cloudwatch.model.CloudWatchException: User: arn:aws:iam::175335015168:user/MyFirstProgrammaticAccessTestUser is not authorized to perform: cloudwatch:ListMetrics (Service: CloudWatch, Status Code: 403, Request ID: 75f02535-28c7-49c8-930a-b8d8449c625a, Extended Request ID: null)
Exception in thread "main" software.amazon.awssdk.services.cloudwatch.model.CloudWatchException: User: arn:aws:iam::175335015168:user/MyFirstProgrammaticAccessTestUser is not authorized to perform: cloudwatch:ListMetrics (Service: CloudWatch, Status Code: 403, Request ID: 75f02535-28c7-49c8-930a-b8d8449c625a, Extended Request ID: null)
    at software.amazon.awssdk.core.internal.http.CombinedResponseHandler.handleErrorResponse(CombinedResponseHandler.java:123)
    at software.amazon.awssdk.core.internal.http.CombinedResponseHandler.handleResponse(CombinedResponseHandler.java:79)
    at software.amazon.awssdk.core.internal.http.CombinedResponseHandler.handle(CombinedResponseHandler.java:59)
    at software.amazon.awssdk.core.internal.http.CombinedResponseHandler.handle(CombinedResponseHandler.java:40)
    at software.amazon.awssdk.core.internal.http.pipeline.stages.HandleResponseStage.execute(HandleResponseStage.java:40)
    at software.amazon.awssdk.core.internal.http.pipeline.stages.HandleResponseStage.execute(HandleResponseStage.java:30)
    at software.amazon.awssdk.core.internal.http.pipeline.RequestPipelineBuilder$ComposingRequestPipelineStage.execute(RequestPipelineBuilder.java:206)
    at software.amazon.awssdk.core.internal.http.pipeline.stages.ApiCallAttemptTimeoutTrackingStage.execute(ApiCallAttemptTimeoutTrackingStage.java:73)
    at software.amazon.awssdk.core.internal.http.pipeline.stages.ApiCallAttemptTimeoutTrackingStage.execute(ApiCallAttemptTimeoutTrackingStage.java:42)
    at software.amazon.awssdk.core.internal.http.pipeline.stages.TimeoutExceptionHandlingStage.execute(TimeoutExceptionHandlingStage.java:77)
    at software.amazon.awssdk.core.internal.http.pipeline.stages.TimeoutExceptionHandlingStage.execute(TimeoutExceptionHandlingStage.java:39)
    at software.amazon.awssdk.core.internal.http.pipeline.stages.ApiCallAttemptMetricCollectionStage.execute(ApiCallAttemptMetricCollectionStage.java:50)
    at software.amazon.awssdk.core.internal.http.pipeline.stages.ApiCallAttemptMetricCollectionStage.execute(ApiCallAttemptMetricCollectionStage.java:36)
    at software.amazon.awssdk.core.internal.http.pipeline.stages.RetryableStage.execute(RetryableStage.java:64)
    at software.amazon.awssdk.core.internal.http.pipeline.stages.RetryableStage.execute(RetryableStage.java:34)
    at software.amazon.awssdk.core.internal.http.pipeline.RequestPipelineBuilder$ComposingRequestPipelineStage.execute(RequestPipelineBuilder.java:206)
    at software.amazon.awssdk.core.internal.http.StreamManagingStage.execute(StreamManagingStage.java:56)
    at software.amazon.awssdk.core.internal.http.StreamManagingStage.execute(StreamManagingStage.java:36)
    at software.amazon.awssdk.core.internal.http.pipeline.stages.ApiCallTimeoutTrackingStage.executeWithTimer(ApiCallTimeoutTrackingStage.java:80)
    at software.amazon.awssdk.core.internal.http.pipeline.stages.ApiCallTimeoutTrackingStage.execute(ApiCallTimeoutTrackingStage.java:60)
    at software.amazon.awssdk.core.internal.http.pipeline.stages.ApiCallTimeoutTrackingStage.execute(ApiCallTimeoutTrackingStage.java:42)
    at software.amazon.awssdk.core.internal.http.pipeline.stages.ApiCallMetricCollectionStage.execute(ApiCallMetricCollectionStage.java:48)
    at software.amazon.awssdk.core.internal.http.pipeline.stages.ApiCallMetricCollectionStage.execute(ApiCallMetricCollectionStage.java:31)
    at software.amazon.awssdk.core.internal.http.pipeline.RequestPipelineBuilder$ComposingRequestPipelineStage.execute(RequestPipelineBuilder.java:206)
    at software.amazon.awssdk.core.internal.http.pipeline.RequestPipelineBuilder$ComposingRequestPipelineStage.execute(RequestPipelineBuilder.java:206)
    at software.amazon.awssdk.core.internal.http.pipeline.stages.ExecutionFailureExceptionReportingStage.execute(ExecutionFailureExceptionReportingStage.java:37)
    at software.amazon.awssdk.core.internal.http.pipeline.stages.ExecutionFailureExceptionReportingStage.execute(ExecutionFailureExceptionReportingStage.java:26)
    at software.amazon.awssdk.core.internal.http.AmazonSyncHttpClient$RequestExecutionBuilderImpl.execute(AmazonSyncHttpClient.java:193)
    at software.amazon.awssdk.core.internal.handler.BaseSyncClientHandler.invoke(BaseSyncClientHandler.java:128)
    at software.amazon.awssdk.core.internal.handler.BaseSyncClientHandler.doExecute(BaseSyncClientHandler.java:154)
    at software.amazon.awssdk.core.internal.handler.BaseSyncClientHandler.lambda$execute$1(BaseSyncClientHandler.java:107)
    at software.amazon.awssdk.core.internal.handler.BaseSyncClientHandler.measureApiCallSuccess(BaseSyncClientHandler.java:162)
    at software.amazon.awssdk.core.internal.handler.BaseSyncClientHandler.execute(BaseSyncClientHandler.java:91)
    at software.amazon.awssdk.core.client.handler.SdkSyncClientHandler.execute(SdkSyncClientHandler.java:45)
    at software.amazon.awssdk.awscore.client.handler.AwsSyncClientHandler.execute(AwsSyncClientHandler.java:55)
    at software.amazon.awssdk.services.cloudwatch.DefaultCloudWatchClient.listMetrics(DefaultCloudWatchClient.java:1877)
    at aws.TestMain.listMets(TestMain.java:33)
    at aws.TestMain.main(TestMain.java:17)

So the Error is:

user/MyFirstProgrammaticAccessTestUser is not authorized to perform: cloudwatch:ListMetrics

I try to solve this by going back to the IAM console and add the user to a new created group with attached policy "CloudWatchFullAccess".

Result:

2020-09-01 19:38:27 [main] DEBUG software.amazon.awssdk.request:84 - Sending Request: DefaultSdkHttpFullRequest(httpMethod=POST, protocol=https, host=monitoring.eu-central-1.amazonaws.com, encodedPath=, headers=[amz-sdk-invocation-id, Content-Length, Content-Type, User-Agent], queryParameters=[])
2020-09-01 19:38:28 [main] DEBUG software.amazon.awssdk.request:84 - Received successful response: 200

So this worked, this was quite intuitive 🙂
The result is empty, I guess because of the metric-namespace that I initaly set with placeholder name. I looked into my CloudWatch Dashboard, but could not find any metric with data. I guess, I have to create a metric and find a way to create data for the metric. TBC

One reply on “Getting Started with AWS”

Leave a Reply

Your email address will not be published. Required fields are marked *