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ư:
- Connect to your instances securely using Session Manager.
- Perform automated patch scans using Patch Manager.
- View detailed information about your instances using Systems Manager Inventory.
- Track and manage instances using Fleet Manager.
- Keep the SSM Agent up to date automatically.
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ả.