By attaching an instance RAM role to an ECS instance, you can use the Simple Log Service (SLS) SDK without an AccessKey. The instance automatically obtains and refreshes temporary credentials, eliminating the risk of AccessKey leaks and enabling fine-grained access control.
-
An instance RAM role uses an Alibaba Cloud service as the trusted principal, allowing a cloud service to assume the role for cross-service access. For more information, see What is a RAM role?.
-
An AccessKey pair is a security credential used to sign API requests for identity and permission verification. For more information, see AccessKey pair.
-
For more information about custom policies for Simple Log Service, see RAM custom policy examples.
Limitations
-
This feature is supported only by Simple Log Service SDK for Java and Simple Log Service SDK for Go.
-
The ECS instance must reside in a VPC.
-
You can attach only one RAM role to an ECS instance.
Step 1: Create and attach an instance RAM role
Console
-
Log on to the RAM console and create a RAM role that uses an Alibaba Cloud service as the principal.
Choose Identities > Roles and click Create Role. Follow the on-screen instructions to create the role, noting the following parameters. For other parameters, configure them as needed. For more information, see Create a common service role.
-
Select Trusted Entity: Select Alibaba Cloud Service.
-
For Role Type, select Normal Service Role. Then, from the Trusted Service drop-down list, select ECS.
-
-
Grant permissions to the instance RAM role.
Attach a system or custom policy to the RAM role to grant the required permissions. For example, attach the AliyunLogReadOnlyAccess policy to grant read-only access to Simple Log Service.
NoteYou can add a System Policy or a Custom Policy. If the system policies do not meet your requirements, you can create a custom policy. For more information, see Create a custom policy.
-
Attach the instance RAM role to an ECS instance.
-
Log on to the ECS console.
-
In the left-side navigation pane, choose .
-
In the top navigation bar, select the region and resource group to which the target instance belongs.
-
Find the target ECS instance and choose in the Actions column.
-
In the dialog box that appears, select the instance RAM role that you created and click OK.
-
API
-
Create and configure an instance RAM role.
-
Call CreateRole to create an instance RAM role.
Set the AssumeRolePolicyDocument parameter to the following policy:
{ "Statement": [ { "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { "Service": [ "ecs.aliyuncs.com" ] } } ], "Version": "1" } -
(Optional) Call CreatePolicy to create a permission policy.
You can skip this step if you have an available permission policy.
Set the
PolicyDocumentparameter as follows:{ "Statement": [ { "Action": [ "oss:Get*", "oss:List*" ], "Effect": "Allow", "Resource": "*" } ], "Version": "1" }
-
-
Call the AttachPolicyToRole operation to attach the permission policy to the instance RAM role.
-
Call the AttachInstanceRamRole operation to attach the instance RAM role to the ECS instance.
Step 2: Access the SLS SDK
Java
Java SDK
-
To use Simple Log Service SDK for Java in a Maven project, add the following dependency to the pom.xml file. For more information, see Simple Log Service SDK for Java.
ImportantThe minimum required version of the Simple Log Service SDK for Java is 0.6.110.
<dependency> <groupId>com.aliyun.openservices</groupId> <artifactId>aliyun-log</artifactId> <version>0.6.110</version> </dependency> -
For the
Clientclass, pass the name of the instance RAM role that you created in Step 1 as an input parameter.import com.aliyun.openservices.log.exception.LogException; import com.aliyun.openservices.log.response.GetProjectResponse; public class Main { public static void main(String[] args) throws LogException { // Replace RoleName with the name of the RAM role that you created. Client client = new Client("cn-hangzhou.log.aliyuncs.com", "RoleName"); GetProjectResponse resp = client.GetProject("your-project"); System.out.println(resp.GetProjectDescription()); } }
Java Producer
-
To use Aliyun Log Java Producer in a Maven project, add the following dependency to the pom.xml file. For more information, see Aliyun Log Java Producer.
ImportantThe minimum required version of Aliyun Log Java Producer is 0.3.22.
<dependency> <groupId>com.aliyun.openservices</groupId> <artifactId>aliyun-log-producer</artifactId> <version>0.3.22</version> </dependency> -
In Configure a Log Project, specify the name of the instance RAM role that you created in Step 1 for the
ProjectConfigparameter.import com.aliyun.openservices.aliyun.log.producer.*; import com.aliyun.openservices.aliyun.log.producer.errors.ProducerException; import com.aliyun.openservices.log.common.LogItem; import com.aliyun.openservices.log.common.auth.CredentialsProvider; import com.aliyun.openservices.log.common.auth.ECSRoleCredentialsProvider; public class ExampleUsage { public static void main(String[] args) throws ProducerException, InterruptedException { String endpoint = "cn-hangzhou.log.aliyuncs.com"; String project = "your-project"; String logStore = "your-logstore"; // Configure ProducerConfig. Config producerConfig = new ProducerConfig(); // Create a producer. Producer producer = new LogProducer(new ProducerConfig()); // Replace your-ecs-ram-role-name with the name of the RAM role that you created. CredentialsProvider provider = new ECSRoleCredentialsProvider("your-ecs-ram-role-name"); // Configure the project. ProjectConfig projectConfig = new ProjectConfig(project, endpoint, provider, null); producer.putProjectConfig(projectConfig); // Send logs. producer.send(project, logStore, buildLogItem()); producer.send(project, logStore, null, null, buildLogItem()); producer.send(project, logStore, "", "", buildLogItem()); producer.close(); } public static LogItem buildLogItem() { LogItem logItem = new LogItem(); logItem.PushBack("k1", "v1"); logItem.PushBack("k2", "v2"); return logItem; } }
Java Consumer
-
To use Aliyun Log Java Consumer in a Maven project, add the following dependency to the pom.xml file. For more information, see Use consumer groups to consume logs.
ImportantThe minimum required version of Aliyun Log Java Consumer is 0.6.47.
<dependency> <groupId>com.aliyun.openservices</groupId> <artifactId>loghub-client-lib</artifactId> <version>0.6.47</version> </dependency> -
To create a consumer, set the
LogHubConfigparameter to the name of the instance RAM role that you created in Step 1.import com.aliyun.openservices.log.common.auth.ECSRoleCredentialsProvider; import com.aliyun.openservices.log.common.auth.CredentialsProvider; import com.aliyun.openservices.loghub.client.ClientWorker; import com.aliyun.openservices.loghub.client.config.LogHubConfig; import com.aliyun.openservices.loghub.client.exceptions.LogHubClientWorkerException; public class Main { private static String Endpoint = "cn-hangzhou.log.aliyuncs.com"; private static String Project = "your-project"; private static String Logstore = "your-logstore"; private static String ConsumerGroup = "consumerGroupX"; public static void main(String[] args) throws LogHubClientWorkerException, InterruptedException { // Replace your-ecs-ram-role-name with the name of the RAM role that you created. CredentialsProvider provider = new ECSRoleCredentialsProvider("your-ecs-ram-role-name"); LogHubConfig config = new LogHubConfig(ConsumerGroup, "consumer_1", Endpoint, Project, Logstore, provider, LogHubConfig.ConsumePosition.BEGIN_CURSOR); config.setMaxFetchLogGroupSize(1000); ClientWorker worker = new ClientWorker(new SampleLogHubProcessorFactory(), config); Thread thread = new Thread(worker); thread.start(); Thread.sleep(60 * 60 * 1000); worker.shutdown(); Thread.sleep(30 * 1000); } }
Go
To use Simple Log Service SDK for Go without an AccessKey, you must use version 0.1.83 or later. To upgrade the SDK, see Install or upgrade the SDK.
Go SDK
provider specifies the name of the instance RAM role that you created in Step 1.
package main
import (
"fmt"
sls "github.com/aliyun/aliyun-log-go-sdk"
)
func main() {
// The endpoint of Simple Log Service. This example uses the China (Chengdu) region. Replace the value with the actual endpoint.
Endpoint := "cn-chengdu.log.aliyuncs.com"
// Replace your-ecs-ram-role-name with the name of the RAM role that you created.
provider := sls.NewEcsRamRoleCredentialsProvider("your-ecs-ram-role-name")
// Create a Simple Log Service client.
client := sls.CreateNormalInterfaceV2(Endpoint, provider)
resp, err := client.GetProject("your-project")
if err != nil {
panic(err)
}
fmt.Println(resp.Description)
}
Go Producer
In Configure ProducerConfig, set the provider parameter to the name of the instance RAM role that you created in Step 1.
package main
import (
"fmt"
"os"
"os/signal"
"sync"
"time"
sls "github.com/aliyun/aliyun-log-go-sdk"
"github.com/aliyun/aliyun-log-go-sdk/producer"
"github.com/gogo/protobuf/proto"
)
func main() {
producerConfig := producer.GetDefaultProducerConfig()
producerConfig.Endpoint = "cn-hangzhou.log-aliyuncs.com"
// Replace your-ecs-ram-role-name with the name of the RAM role that you created.
provider := sls.NewEcsRamRoleCredentialsProvider("your-ecs-ram-role-name")
producerConfig.CredentialsProvider = provider
producerInstance := producer.InitProducer(producerConfig)
ch := make(chan os.Signal)
signal.Notify(ch, os.Kill, os.Interrupt)
producerInstance.Start()
var m sync.WaitGroup
for i := 0; i < 10; i++ {
m.Add(1)
go func() {
defer m.Done()
for i := 0; i < 1000; i++ {
log := producer.GenerateLog(uint32(time.Now().Unix()), map[string]string{"content": "test", "content2": fmt.Sprintf("%v", i)})
err := producerInstance.SendLog("log-project", "log-store", "topic", "127.0.0.1", log)
if err != nil {
fmt.Println(err)
}
}
}()
}
m.Wait()
fmt.Println("Send completion")
if _, ok := <-ch; ok {
fmt.Println("Get the shutdown signal and start to shut down")
producerInstance.Close(60000)
}
}
Go Consumer
For the CredentialsProvider input parameter, pass the name of the instance RAM role that you created in Step 1.
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
sls "github.com/aliyun/aliyun-log-go-sdk"
consumerLibrary "github.com/aliyun/aliyun-log-go-sdk/consumer"
"github.com/go-kit/kit/log/level"
)
func main() {
option := consumerLibrary.LogHubConfig{
Endpoint: "cn-hangzhou.log-aliyuncs.com",
// Replace your-ecs-ram-role-name with the name of the RAM role that you created.
CredentialsProvider: sls.NewEcsRamRoleCredentialsProvider("your-ecs-ram-role-name"),
Project: "your-project",
Logstore: "your-logstore",
ConsumerGroupName: "your-consumer-group",
ConsumerName: "your-consumer-group-consumer-1",
CursorPosition: consumerLibrary.END_CURSOR,
}
consumerWorker := consumerLibrary.InitConsumerWorkerWithCheckpointTracker(option, process)
ch := make(chan os.Signal, 1)
signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)
consumerWorker.Start()
if _, ok := <-ch; ok {
level.Info(consumerWorker.Logger).Log("msg", "get stop signal, start to stop consumer worker", "consumer worker name", option.ConsumerName)
consumerWorker.StopAndWait()
}
}
// Implement the data consumption logic.
func process(shardId int, logGroupList *sls.LogGroupList, checkpointTracker consumerLibrary.CheckPointTracker) (string, error) {
fmt.Println(shardId, logGroupList)
checkpointTracker.SaveCheckPoint(false)
return "", nil
}
Related documentation
-
If your application is deployed on an Alibaba Cloud ECS instance and needs to access Key Management Service (KMS), you can use an instance RAM role to securely access KMS.
-
If an ECS instance no longer requires certain resource access permissions, you can revoke permissions from a RAM role.
-
Hard-coding an AccessKey pair in your code poses a security risk if the code repository is not properly managed. For more information, see Use credentials to access Alibaba Cloud OpenAPI.
> Instance Settings > Attach/Detach RAM Role