Get IAM Role information programatically using Scala - amazon-web-services

I want to receive the role information for a role name. For example getting the exact ARN identifier.
Somehow this code below is not working. Sadly there is no error message in cloudwatch
import software.amazon.awssdk.services.iam.*;
import com.amazonaws.services.identitymanagement.model._
import com.amazonaws.services.identitymanagement.{AmazonIdentityManagementClient, AmazonIdentityManagement, AmazonIdentityManagementClientBuilder}
// ....
val iamClient = AmazonIdentityManagementClient
.builder()
.withRegion("eu-central-1")
.build()
val roleRequest = new GetRoleRequest();
roleRequest.setRoleName("InfrastructureStack-StandardRoleD-HBLE12VPTWQ")
val result = iamClient.getRole(roleRequest) // <-- Nothing happens after this line
println("wont execute this println statement")
Other services like CognitoIdentityProvider are working perfectly fine.
I also tried the builder pattern for the GetRoleRequest and IamClient.

I got this IAM V2 code working fine. As stated in my comment, setup your dev environment to use AWS SDK for Java V2.
package com.example.iam;
import software.amazon.awssdk.services.iam.model.*;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.iam.IamClient;
public class GetRole {
public static void main(String[] args) {
final String USAGE = "\n" +
"Usage:\n" +
" <policyArn> \n\n" +
"Where:\n" +
" policyArn - a policy ARN that you can obtain from the AWS Management Console. \n\n" ;
// if (args.length != 1) {
// System.out.println(USAGE);
//// System.exit(1);
// }
String roleName = "DynamoDBAutoscaleRole" ; //args[0];
Region region = Region.AWS_GLOBAL;
IamClient iam = IamClient.builder()
.region(region)
.build();
getRoleInformation(iam, roleName);
System.out.println("Done");
iam.close();
}
public static void getRoleInformation(IamClient iam, String roleName) {
try {
GetRoleRequest roleRequest = GetRoleRequest.builder()
.roleName(roleName)
.build();
GetRoleResponse response = iam.getRole(roleRequest) ;
System.out.println("The ARN of the role is " +response.role().arn());
} catch (IamException e) {
System.err.println(e.awsErrorDetails().errorMessage());
System.exit(1);
}
}
}
Output:

Related

How do I find if all the S3 objects are restored

I recently have restored S3 Deep Archive objects using Python.
There are over a million of them and I need to make it sure clearly.
If possible, I would like to use python to check if all objects have been restored.
Can someone please advice me how to do this?
Thank you
From restore_object() documentation:
To get the status of object restoration, you can send a HEAD request. Operations return the x-amz-restore header, which provides information about the restoration status, in the response.
And under head_object():
If an archive copy is already restored, the header value indicates when Amazon S3 is scheduled to delete the object copy. For example:
x-amz-restore: ongoing-request="false", expiry-date="Fri, 21 Dec 2012 00:00:00 GMT"
Although not Python, here is the logic to perform this use case using AWS SDK for Java v2.
package com.example.s3;
import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.HeadObjectRequest;
import software.amazon.awssdk.services.s3.model.HeadObjectResponse;
import software.amazon.awssdk.services.s3.model.S3Exception;
public class GetObjectRestoreStatus {
public static void main(String[] args) {
final String usage = "\n" +
"Usage:\n" +
" <bucketName> <keyName> \n\n" +
"Where:\n" +
" bucketName - The Amazon S3 bucket name. \n\n"+
" keyName - A key name that represents the object. \n\n";
if (args.length != 2) {
System.out.println(usage);
System.exit(1);
}
String bucketName = args[0];
String keyName = args[1];
ProfileCredentialsProvider credentialsProvider = ProfileCredentialsProvider.create();
Region region = Region.US_EAST_1;
S3Client s3 = S3Client.builder()
.region(region)
.credentialsProvider(credentialsProvider)
.build();
checkStatus(s3,bucketName,keyName);
s3.close();
}
// snippet-start:[s3.java2.getrestorestatus.main]
public static void checkStatus(S3Client s3, String bucketName, String keyName) {
try {
HeadObjectRequest headObjectRequest = HeadObjectRequest.builder()
.bucket(bucketName)
.key(keyName)
.build();
HeadObjectResponse response = s3.headObject(headObjectRequest);
System.out.println("The Amazon S3 object restoration status is "+response.restore());
} catch (S3Exception e) {
System.err.println(e.awsErrorDetails().errorMessage());
System.exit(1);
}
}
// snippet-end:[s3.java2.getrestorestatus.main]
}

AWS Redshift serverless - how to get the cluster id value

I'm following the AWS documentation about how to connect to redshift [generating user credentials][1]
But the get-cluster-credentials API requires a cluster id parameter, which i don't have for a serverless endpoint. What id should I use?
EDIT:
[![enter image description here][2]][2]
This is the screen of a serverless endpoint dashboard. There is no cluster ID.
[1]: https://docs.aws.amazon.com/redshift/latest/mgmt/generating-user-credentials.html
[2]: https://i.stack.imgur.com/VzvIs.png
Look at this Guide (a newer one) that talks about Connecting to Amazon Redshift Serverless. https://docs.aws.amazon.com/redshift/latest/mgmt/serverless-connecting.html
See this information that answers your question:
Connecting to the serverless endpoint with the Data API
You can also use the Amazon Redshift Data API to connect to serverless endpoint. Leave off the cluster-identifier parameter in your AWS CLI calls to route your query to serverless endpoint.
UPDATE
I wanted to test this to make sure that a successful connection can be made. I followed this doc to setup a Serverless instance.
Get started with Amazon Redshift Serverless
I loaded sample data and now have this.
Now I attemped to connect to it using software.amazon.awssdk.services.redshiftdata.RedshiftDataClient.
The Java V2 code:
try {
ExecuteStatementRequest statementRequest = ExecuteStatementRequest.builder()
.database(database)
.sql(sqlStatement)
.build();
ExecuteStatementResponse response = redshiftDataClient.executeStatement(statementRequest);
return response.id();
} catch (RedshiftDataException e) {
System.err.println(e.getMessage());
System.exit(1);
}
return "";
}
Notice there is no cluster id or user. Only a database name (sample_data_dev). The call worked perfectly.
HEre is the full code example that successfully queries data from a serverless instance using the AWS SDK for Java V2.
package com.example.redshiftdata;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.redshiftdata.model.*;
import software.amazon.awssdk.services.redshiftdata.RedshiftDataClient;
import software.amazon.awssdk.services.redshiftdata.model.DescribeStatementRequest;
import java.util.List;
/**
* To run this Java V2 code example, ensure that you have setup 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 RetrieveDataServerless {
public static void main(String[] args) {
final String USAGE = "\n" +
"Usage:\n" +
" RetrieveData <database> <sqlStatement> \n\n" +
"Where:\n" +
" database - the name of the database (for example, sample_data_dev). \n" +
" sqlStatement - the sql statement to use. \n" ;
String database = "sample_data_dev" ;
String sqlStatement = "Select * from tickit.sales" ;
Region region = Region.US_WEST_2;
RedshiftDataClient redshiftDataClient = RedshiftDataClient.builder()
.region(region)
.build();
String id = performSQLStatement(redshiftDataClient, database, sqlStatement);
System.out.println("The identifier of the statement is "+id);
checkStatement(redshiftDataClient,id );
getResults(redshiftDataClient, id);
redshiftDataClient.close();
}
public static void checkStatement(RedshiftDataClient redshiftDataClient,String sqlId ) {
try {
DescribeStatementRequest statementRequest = DescribeStatementRequest.builder()
.id(sqlId)
.build() ;
// Wait until the sql statement processing is finished.
boolean finished = false;
String status = "";
while (!finished) {
DescribeStatementResponse response = redshiftDataClient.describeStatement(statementRequest);
status = response.statusAsString();
System.out.println("..."+status);
if (status.compareTo("FINISHED") == 0) {
break;
}
Thread.sleep(1000);
}
System.out.println("The statement is finished!");
} catch (RedshiftDataException | InterruptedException e) {
System.err.println(e.getMessage());
System.exit(1);
}
}
public static String performSQLStatement(RedshiftDataClient redshiftDataClient,
String database,
String sqlStatement) {
try {
ExecuteStatementRequest statementRequest = ExecuteStatementRequest.builder()
.database(database)
.sql(sqlStatement)
.build();
ExecuteStatementResponse response = redshiftDataClient.executeStatement(statementRequest);
return response.id();
} catch (RedshiftDataException e) {
System.err.println(e.getMessage());
System.exit(1);
}
return "";
}
public static void getResults(RedshiftDataClient redshiftDataClient, String statementId) {
try {
GetStatementResultRequest resultRequest = GetStatementResultRequest.builder()
.id(statementId)
.build();
GetStatementResultResponse response = redshiftDataClient.getStatementResult(resultRequest);
// Iterate through the List element where each element is a List object.
List<List<Field>> dataList = response.records();
// Print out the records.
for (List list: dataList) {
for (Object myField:list) {
Field field = (Field) myField;
String value = field.stringValue();
if (value != null)
System.out.println("The value of the field is " + value);
}
}
} catch (RedshiftDataException e) {
System.err.println(e.getMessage());
System.exit(1);
}
}
}

Amazon S3 files sharing

In my project there is a need for creating share link for external users without aws user from my researching found out a couple ways for doing so
Bucket policy based on tag
Lambda that creates sign url every time some user request the file
The question is what is the best practice for doing so
I need the download to be available until the user sharing the file stopes it
Thank guys for any answers
Using the AWS SDK, you can use Amazon S3 Pre-sign functionality. You can perform this task in any of the supported programming languages (Java, JS, Python, etc).
The following code shows how to sign an object via the Amazon S3 Java V2 API.
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.time.Duration;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import software.amazon.awssdk.services.s3.model.S3Exception;
import software.amazon.awssdk.services.s3.presigner.model.GetObjectPresignRequest;
import software.amazon.awssdk.services.s3.presigner.model.PresignedGetObjectRequest;
import software.amazon.awssdk.services.s3.presigner.S3Presigner;
import software.amazon.awssdk.utils.IoUtils;
// snippet-end:[presigned.java2.getobjectpresigned.import]
/**
* To run this AWS code example, ensure that you have setup your development environment, including your AWS credentials.
*
* For information, see this documentation topic:
*
* https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
*/
public class GetObjectPresignedUrl {
public static void main(String[] args) {
final String USAGE = "\n" +
"Usage:\n" +
" GetObjectPresignedUrl <bucketName> <keyName> \n\n" +
"Where:\n" +
" bucketName - the Amazon S3 bucket name. \n\n"+
" keyName - a key name that represents a text file. \n\n";
if (args.length != 2) {
System.out.println(USAGE);
System.exit(1);
}
String bucketName = args[0];
String keyName = args[1];
Region region = Region.US_WEST_2;
S3Presigner presigner = S3Presigner.builder()
.region(region)
.build();
getPresignedUrl(presigner, bucketName, keyName);
presigner.close();
}
// snippet-start:[presigned.java2.getobjectpresigned.main]
public static void getPresignedUrl(S3Presigner presigner, String bucketName, String keyName ) {
try {
GetObjectRequest getObjectRequest =
GetObjectRequest.builder()
.bucket(bucketName)
.key(keyName)
.build();
GetObjectPresignRequest getObjectPresignRequest = GetObjectPresignRequest.builder()
.signatureDuration(Duration.ofMinutes(10))
.getObjectRequest(getObjectRequest)
.build();
// Generate the presigned request
PresignedGetObjectRequest presignedGetObjectRequest =
presigner.presignGetObject(getObjectPresignRequest);
// Log the presigned URL
System.out.println("Presigned URL: " + presignedGetObjectRequest.url());
HttpURLConnection connection = (HttpURLConnection) presignedGetObjectRequest.url().openConnection();
presignedGetObjectRequest.httpRequest().headers().forEach((header, values) -> {
values.forEach(value -> {
connection.addRequestProperty(header, value);
});
});
// Send any request payload that the service needs (not needed when isBrowserExecutable is true)
if (presignedGetObjectRequest.signedPayload().isPresent()) {
connection.setDoOutput(true);
try (InputStream signedPayload = presignedGetObjectRequest.signedPayload().get().asInputStream();
OutputStream httpOutputStream = connection.getOutputStream()) {
IoUtils.copy(signedPayload, httpOutputStream);
}
}
// Download the result of executing the request
try (InputStream content = connection.getInputStream()) {
System.out.println("Service returned response: ");
IoUtils.copy(content, System.out);
}
} catch (S3Exception e) {
e.getStackTrace();
} catch (IOException e) {
e.getStackTrace();
}
// snippet-end:[presigned.java2.getobjectpresigned.main]
}
}

S3 - PutObject results in 403 - forbidden - public access?

I am confused by the S3 bucket privacy settings.
I have created a Bucket that blocks all public access and I have created an IAM user which has the permission AmazonS3FullAccess.
Then I use the Access Key and Access Secret of that IAM user to place objects in the bucket, but this fails as PutObject returns a 403-forbidden error. I don't understand why, because the user has the role to access S3 fully.
My bucket permissions looks like this:
So now I have two questions:
Did I forgot something to get this working?
I know it works when I enable public access - but what does that mean exactly? Can any S3 user access my bucket to download/upload/access the files in that bucket or only the user which is displayed in the ACL - which is currently only the owner of the bucket?
Thanks for clarification!
You did not specify you how are placing an object in the bucket. Lets make an assumption here. Assume you want to use code to perform this task. Now assume you set your IAM creds in a file named credentials in C:\Users\USERNAME.aws\credentials on Windows or ~/.aws/credentials on Linux, macOS, or Unix. Assume you setup you IAM user by following this doc:
https://docs.aws.amazon.com/IAM/latest/UserGuide/getting-started_create-admin-group.html#getting-started_create-admin-group-console
(I suspect you have a wrong setting for IAM - check this doc)
You can upload an object to an Amazon S3 bucket using this code (this is the Java example - but you can find other examples for different programming languages).
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.model.PutObjectResponse;
import software.amazon.awssdk.services.s3.model.S3Exception;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class PutObject {
public static void main(String[] args) {
final String USAGE = "\n" +
"Usage:\n" +
" PutObject <bucketName> <objectKey> <objectPath> \n\n" +
"Where:\n" +
" bucketName - the Amazon S3 bucket to upload an object into.\n" +
" objectKey - the object to upload (for example, book.pdf).\n" +
" objectPath - the path where the file is located (for example, C:/AWS/book2.pdf). \n\n" ;
if (args.length != 3) {
System.out.println(USAGE);
System.exit(1);
}
String bucketName = args[0];
String objectKey = args[1];
String objectPath = args[2];
System.out.println("Putting object " + objectKey +" into bucket "+bucketName);
System.out.println(" in bucket: " + bucketName);
Region region = Region.US_EAST_1;
S3Client s3 = S3Client.builder()
.region(region)
.build();
String result = putS3Object(s3, bucketName, objectKey, objectPath);
System.out.println("Tag information: "+result);
s3.close();
}
// snippet-start:[s3.java2.s3_object_upload.main]
public static String putS3Object(S3Client s3,
String bucketName,
String objectKey,
String objectPath) {
try {
Map<String, String> metadata = new HashMap<>();
metadata.put("myVal", "test");
PutObjectRequest putOb = PutObjectRequest.builder()
.bucket(bucketName)
.key(objectKey)
.metadata(metadata)
.build();
PutObjectResponse response = s3.putObject(putOb,
RequestBody.fromBytes(getObjectFile(objectPath)));
return response.eTag();
} catch (S3Exception e) {
System.err.println(e.getMessage());
System.exit(1);
}
return "";
}
// Return a byte array
private static byte[] getObjectFile(String filePath) {
FileInputStream fileInputStream = null;
byte[] bytesArray = null;
try {
File file = new File(filePath);
bytesArray = new byte[(int) file.length()];
fileInputStream = new FileInputStream(file);
fileInputStream.read(bytesArray);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fileInputStream != null) {
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return bytesArray;
}
}

Get all the failed executions of a state machine in AWS Step function and execute dynamically. (In java)

I want to fetch all the failed executions and need to re-trigger them dynamically.
PS: In stepfunction definition I had proper retry mechanism, now I want to rerun the failed executions dynamically.
I need to implement it in java. Please help me with the approach.
Thanks in advance.
You can use the AWS Step Functions API to get a list of excutions:
https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sfn/SfnClient.html#listExecutions-
Then you can get a list of ExecutionListItem by calling the executions() method that belongs to the ListExecutionsResponse object (returned by the listExecutions method)
https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sfn/model/ExecutionListItem.html
Using this object - you can do two things:
1 - check status - https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sfn/model/ExecutionStatus.html
2 - get state machine ARN value - https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sfn/model/ExecutionListItem.html#stateMachineArn--
Using the state machine ARN value, you can execute a state machine with the AWS Step Functions Java API V2:
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.sfn.SfnClient;
import software.amazon.awssdk.services.sfn.model.*;
import java.io.FileReader;
import java.io.IOException;
import java.util.UUID;
// snippet-end:[stepfunctions.java2.start_execute.import]
public class StartExecution {
public static void main(String[] args) {
final String USAGE = "\n" +
"Usage:\n" +
" StartExecution <stateMachineArn> <jsonFile>\n\n" +
"Where:\n" +
" stateMachineArn - the ARN of the state machine.\n\n" +
" jsonFile - A JSON file that contains the values to pass to the worflow.\n" ;
if (args.length != 2) {
System.out.println(USAGE);
System.exit(1);
}
String stateMachineArn = args[0];
String jsonFile = args[1];
Region region = Region.US_EAST_1;
SfnClient sfnClient = SfnClient.builder()
.region(region)
.build();
String exeArn = startWorkflow(sfnClient,stateMachineArn, jsonFile);
System.out.println("The execution ARN is" +exeArn);
sfnClient.close();
}
// snippet-start:[stepfunctions.java2.start_execute.main]
public static String startWorkflow(SfnClient sfnClient, String stateMachineArn, String jsonFile) {
String json = getJSONString(jsonFile);
// Specify the name of the execution by using a GUID value.
UUID uuid = UUID.randomUUID();
String uuidValue = uuid.toString();
try {
StartExecutionRequest executionRequest = StartExecutionRequest.builder()
.input(json)
.stateMachineArn(stateMachineArn)
.name(uuidValue)
.build();
StartExecutionResponse response = sfnClient.startExecution(executionRequest);
return response.executionArn();
} catch (SfnException e) {
System.err.println(e.awsErrorDetails().errorMessage());
System.exit(1);
}
return "";
}
private static String getJSONString(String path) {
try {
JSONParser parser = new JSONParser();
JSONObject data = (JSONObject) parser.parse(new FileReader(path));//path to the JSON file.
String json = data.toJSONString();
return json;
} catch (IOException | org.json.simple.parser.ParseException e) {
e.printStackTrace();
}
return "";
}
// snippet-end:[stepfunctions.java2.start_execute.main]
}