Lambda 函式在無伺服器架構中扮演著重要的角色,允許開發者專注於程式碼邏輯而無需管理伺服器。本文將探討如何利用 AWS Lambda 執行 IAM 操作,包含建立、檢查和刪除 IAM 使用者。我們將使用 AWS Java SDK 與 IAM 服務互動,並透過 CloudFormation 進行佈署和管理。同時,我們也會介紹如何實作依賴注入和單元測試,提升程式碼品質和可維護性。文章中會提供完整的 Java 程式碼範例,並逐步引導讀者完成 Lambda 函式的建立、佈署和驗證。此外,我們也會探討如何使用 CloudFormation 範本定義 Lambda 函式及其相關資源,例如執行角色和策略,簡化佈署流程並確保基礎設施的一致性。

使用AWS進行無伺服器運算的入門 - 第一章:建立IAM操作的Lambda函式

在無伺服器運算的世界中,AWS Lambda是一種非常流行的服務,它允許開發者執行程式碼而無需管理伺服器。在本章中,我們將探討如何使用AWS SDK和CloudFormation建立一個Lambda函式,以執行AWS Identity and Access Management(IAM)操作。

建立IAM客戶端物件

首先,我們需要建立一個IAM客戶端物件,用於與IAM服務進行互動。以下程式碼展示瞭如何建立一個AmazonIdentityManagement型別的客戶端物件:

private final AmazonIdentityManagement iamClient;
public IAMService() {
    iamClient = AmazonIdentityManagementClientBuilder.defaultClient();
}

內容解密:

  • AmazonIdentityManagementClientBuilder.defaultClient()用於建立一個預設的IAM客戶端物件。
  • AmazonIdentityManagement是AWS SDK中用於與IAM服務互動的介面。

建立、檢查和刪除IAM使用者

接下來,我們將實作三個方法,分別用於建立、檢查和刪除IAM使用者。

建立IAM使用者

CreateUserRequest request = new CreateUserRequest().withUserName(userName);
CreateUserResult response = iamClient.createUser(request);
// 從response中取得使用者詳細資訊

內容解密:

  • CreateUserRequest用於建立一個新的IAM使用者請求。
  • withUserName(userName)設定要建立的使用者名稱。
  • iamClient.createUser(request)呼叫IAM服務以建立使用者。

檢查IAM使用者是否存在

boolean done = false;
ListUsersRequest request = new ListUsersRequest();
while (!done) {
    ListUsersResult response = iamClient.listUsers(request);
    for (User user : response.getUsers()) {
        if (user.getUserName().equals(userName)) {
            // 傳回成功訊息
        }
    }
    request.setMarker(response.getMarker());
    if (!response.getIsTruncated()) {
        done = true;
    }
}
// 傳回錯誤訊息

內容解密:

  • ListUsersRequest用於列出IAM使用者的請求。
  • iamClient.listUsers(request)呼叫IAM服務以列出使用者。
  • 迴圈遍歷所有使用者,以檢查特定使用者是否存在。

刪除IAM使用者

DeleteUserRequest request = new DeleteUserRequest().withUserName(userName);
try {
    iamClient.deleteUser(request);
} catch (DeleteConflictException e) {
    // 處理例外
}

內容解密:

  • DeleteUserRequest用於刪除IAM使用者的請求。
  • withUserName(userName)設定要刪除的使用者名稱。
  • iamClient.deleteUser(request)呼叫IAM服務以刪除使用者。

建立Lambda函式處理程式

接下來,我們需要建立一個Lambda函式處理程式,用於處理輸入請求並呼叫適當的服務方法。

public final class HelloWorldLambdaHandler implements RequestHandler<IAMOperationRequest, IAMOperationResponse> {
    public IAMOperationResponse handleRequest(final IAMOperationRequest request, final Context context) {
        context.getLogger().log("Requested operation = " + request.getOperation() + ". User name = " + request.getUserName());
        switch (request.getOperation()) {
            case "CREATE":
                return this.service.createUser(request.getUserName());
            case "CHECK":
                return this.service.checkUser(request.getUserName());
            case "DELETE":
                return this.service.deleteUser(request.getUserName());
            default:
                return new IAMOperationResponse(null, "Invalid operation " + request.getOperation() + ". Allowed: CREATE, CHECK, DELETE.");
        }
    }
}

內容解密:

  • RequestHandler是AWS Lambda的介面,用於處理輸入請求。
  • handleRequest方法根據輸入請求的操作型別呼叫適當的服務方法。

封裝和上傳Lambda函式

使用Maven封裝Lambda函式及其依賴項到一個Uber JAR檔案中,並將其上傳到S3儲存桶。

mvn clean package
aws s3 cp target/serverless-cookbook-iam-operations-0.0.1-SNAPSHOT.jar s3://serverless-cookbook/iam-operations-0.0.1-SNAPSHOT.jar --profile admin

建立CloudFormation範本

建立一個CloudFormation範本,用於定義Lambda函式及其相關資源,包括執行角色和策略。

# cf-template-iam-operations.yml 的部分內容
Resources:
  LambdaFunction:
    Type: 'AWS::Lambda::Function'
    Properties:
      FunctionName: !Sub 'aws-sdk-iam-with-cf-cli'
      Runtime: java11
      Handler: HelloWorldLambdaHandler
      Role: !GetAtt 'LambdaExecutionRole.Arn'
      Code:
        S3Bucket: serverless-cookbook
        S3ObjectKey: iam-operations-0.0.1-SNAPSHOT.jar

內容解密:

  • AWS::Lambda::Function資源型別用於定義Lambda函式。
  • Properties部分指定了Lambda函式的屬性,包括執行角色和程式碼位置。

上傳CloudFormation範本並建立堆積疊

上傳CloudFormation範本到S3,並使用AWS CLI建立堆積疊。

aws s3 cp ../resources/cf-template-iam-operations.yml s3://serverless-cookbook/cf-template-iam-operations.yml --profile admin
aws cloudformation create-stack --stack-name myteststack --template-url https://s3.amazonaws.com/serverless-cookbook/cf-template-iam-operations.yml --capabilities CAPABILITY_NAMED_IAM --profile admin

驗證佈署

使用AWS CLI呼叫Lambda函式,以驗證其是否正確佈署。

aws lambda invoke --invocation-type RequestResponse --function-name aws-sdk-iam-with-cf-cli --log-type Tail --payload '{"operation":"CREATE", "userName":"abcd"}' --profile admin outputfile.txt

伺服器less運算在AWS上的起步 Chapter 1

實作:依賴注入與單元測試

本章節將介紹在建立Lambda函式時,如何實施常見的開發實踐,例如使用輕量級框架進行依賴注入和撰寫單元測試。

依賴注入與單元測試的重要性

依賴注入是一種軟體設計模式,用於實作控制反轉(IoC),使得元件之間的耦合度降低。單元測試則是驗證程式碼中最小單元(通常是函式或方法)是否按照預期執行的測試方法。

準備工作

在開始之前,您需要具備以下條件:

  1. 活躍的AWS帳戶
  2. 閱讀並遵循「您的第一個AWS Lambda」和「使用AWS CLI的Lambda」章節的指引,設定Java、Maven、父專案(serverless-cookbook-parent-aws-java)以及AWS CLI
  3. 熟悉軟體開發的基本概念和實踐,如依賴注入、單元測試和介面導向程式設計
  4. 熟悉JUnit和Mockito等函式庫的使用

程式碼重構

首先,我們需要重構之前建立的程式碼,使其遵循介面導向程式設計的原則。

/**
 * IAM操作的介面。
 */
public interface IAMService {
    // 定義介面方法
}

/**
 * {@link IAMService}的實作。
 */
@AllArgsConstructor
public class IAMServiceImpl implements IAMService {
    // 實作介面方法
}

接著,將服務類別重構為介面和其實作,並使用Lombok的@AllArgsConstructor註解產生一個全參建構子,以便在單元測試中注入模擬物件。

private IAMService service;

public MyLambdaHandler() {
    service = new IAMServiceImpl();
}

如何進行依賴注入

我們將使用Guice,一個由AWS建議的輕量級依賴注入框架,來進行依賴注入。

  1. 新增Maven依賴
<dependency>
    <groupId>com.google.inject</groupId>
    <artifactId>guice</artifactId>
    <version>4.2.0</version>
</dependency>
  1. 建立Guice組態類別
public class ApplicationModule extends AbstractModule {
    @Override
    protected void configure() {
        bind(IAMService.class).to(IAMServiceImpl.class);
    }
}
  1. 組態處理器類別以使用Guice
public final class MyLambdaHandler implements RequestHandler<IAMOperationRequest, IAMOperationResponse> {
    private static final Injector INJECTOR = Guice.createInjector(new ApplicationModule());
    private IAMService service;

    public MyLambdaHandler() {
        INJECTOR.injectMembers(this);
        Objects.requireNonNull(service);
    }

    @Inject
    public void setService(final IAMService service) {
        this.service = service;
    }
}

內容解密:

  1. 新增Maven依賴:在專案的pom.xml檔案中新增Guice的依賴,以便在專案中使用Guice框架。
  2. 建立Guice組態類別:定義一個繼承自AbstractModule的類別,並在configure方法中指定介面與其實作之間的繫結關係。
  3. 組態處理器類別:在處理器類別中使用Guice進行依賴注入,首先建立一個Injector例項,然後使用@Inject註解標記需要注入的欄位或方法。

重點分析

  • 使用Guice進行依賴注入,可以使程式碼更加模組化和易於測試。
  • 將服務類別重構為介面和其實作,有助於降低元件之間的耦合度。
  • 正確組態Guice和處理器類別,可以實作自動化的依賴注入。