Tuan-Anh Tran
February 20, 2023

Assume role without instance profile

Posted on February 20, 2023  •  3 minutes  • 620 words

Is it even possible?

AWS Systems Manager có 1 tính năng là Default Host Management Configuration (DHMC). Cái này có gì hay ho? DHMC giúp bạn manage EC2 instances. Benefits bao gồm nhưng ko giới hạn những việc như:

Nhưng hôm nay mình ko nói nhiều về nó. Mình vô tình đọc đoạn code này trong repo của ssm-agent.

Nó có gì hay ho?

// registerManagedInstance checks for activation credentials and performs managed instance registration when present
func registerManagedInstance(log logger.T) (managedInstanceID string, err error) {
    // try to activate the instance with the activation credentials
    publicKey, privateKey, keyType, err := registration.GenerateKeyPair()
    if err != nil {
        return managedInstanceID, fmt.Errorf("error generating signing keys. %v", err)
    }

    // checking write access before registering
    err = registration.UpdateServerInfo("", "", "", privateKey, keyType, "", registration.RegVaultKey)
    if err != nil {
        return managedInstanceID,
            fmt.Errorf("Unable to save registration information. %v\nTry running as sudo/administrator.", err)
    }

    // generate fingerprint
    fingerprint, err := registration.Fingerprint(log)
    if err != nil {
        return managedInstanceID, fmt.Errorf("error generating instance fingerprint. %v", err)
    }

    service := anonauth.NewClient(log, region)
    managedInstanceID, err = service.RegisterManagedInstance(
        activationCode,
        activationID,
        publicKey,
        keyType,
        fingerprint,
    )

    if err != nil {
        return managedInstanceID, fmt.Errorf("error registering the instance with AWS SSM. %v", err)
    }

    err = registration.UpdateServerInfo(managedInstanceID, region, "", privateKey, keyType, "", registration.RegVaultKey)
    if err != nil {
        return managedInstanceID, fmt.Errorf("error persisting the instance registration information. %v", err)
    }

    // saving registration information to the registration file
    reg := map[string]string{
        "ManagedInstanceID": managedInstanceID,
        "Region":            region,
    }

    var regData []byte
    if regData, err = json.Marshal(reg); err != nil {
        return "", fmt.Errorf("Failed to marshal registration info. %v", err)
    }

    if err = ioutil.WriteFile(registrationFile, regData, appconfig.ReadWriteAccess); err != nil {
        return "", fmt.Errorf("Failed to write registration info to file. %v", err)
    }

    return managedInstanceID, nil
}

Đoạn code ngắn này có gì đặc biệt? Nó giúp bạn đăng kí 1 instance trở thành managed instance của DHMC. Yêu cầu của việc này là gì?

Yêu cầu là instance đó cần có access tới IMDS v2 để có thể get về instance identity credential. Sử dụng credential này, chúng ta có thể gọi sang System Manager để đăng kí trở thành managed instance. Đơn giản vậy thôi.

Việc hay ho hơn nằm ở đoạn sau. Sau khi request trở thành managed instance, chúng ta có thể gọi request managed role token sử dụng instance identity credential và SSM key authorization ở bước trước.

System Manager sẽ gọi sang STS để assume role vào role của DHMC và trả lại credential cho EC2 instance.

Nếu bạn chú ý 1 chút trong docs có note lại là

If you prefer to use a custom role, the role’s trust policy must allow Systems Manager as a trusted entity.

Việc bên trên chính là lý do vì sao bạn phải làm như vậy :) Đôi khi, nếu đọc docs kĩ 1 chút, bạn sẽ hiểu rõ hơn đằng sau AWS làm những gì :)

Vậy là bạn đã “assume role” đc vào DHMC role rồi đó, một cách không trực tiếp.

Kết luận

Mình chỉ hơi ngạc nhiên là việc đăng kí trở thành managed instance lại dễ dàng như vậy. Mặc dù ai cũng hiểu khi enable DHMC lên thì chỉ gắn 1 role minimal thôi.

Việc này cũng như kiểu 1 club mà ai cũng có thể đăng kí hội viên và người đó có thể trở thành hội viên ngay lập tức và có tất cả các đặc quyền của hội viên mà ko phải xác nhận gì cả.

Follow me

Here's where I hang out in social media