Skip to main content

DoiT Flexsave accounts

DoiT Flexsave accounts are created and owned by DoiT. They contain no workloads but only Savings Plans and Reserved Instances.

DoiT Flexsave optimizes your savings by adjusting the blend of plans available to you. If you're on a dedicated resold or a SaaS account, you'll see Flexsave accounts join or leave your AWS Organization whenever your plans are adjusted.

Identify Flexsave accounts

DoiT Flexsave accounts have account names as fsXXXXX in the AWS Console. They may appear with the following domain names: doit-intl.com, flexsave.market, flexsave.work, or flexsave.app. Once you've filtered by name, you can also group accounts by account ID.

In DoiT Cloud Analytics reports, all the Flexsave accounts added to your AWS organization are aggregated into one single item under the Project/Account name Flexsave. See Flexsave projects/accounts for an example.

Flexsave accounts activities

DoiT Flexsave accounts join or leave your AWS Organization via actions from the DoiT management role.

When a DoiT Flexsave account leaves your Organization, we clean up the account and delete all the related resources (including default VPCs, roles, policies, security tools, etc.) to ensure the best security posture. The cleanup process may trigger security warnings, for example, AWS CloudTrail logs deleted, AWS GuardDuty detector deleted, or a DeleteServiceLinkedRole request sent. As long as they are from a DoiT Flexsave account, they are not suspicious activities.

AWS Service Control Policies

Flexsave is compatible with AWS Service Control Policies (SCPs).

If you're on a dedicated resold or a SaaS account and have a policy that denies the organizations:LeaveOrganization or the organizations:DescribeOrganization action, you must add a Condition to make an exception for the DoiT management role (alternatively, you can move all the Flexsave accounts to an OU and exclude the SCP from the OU).

For example:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Action": ["organizations:LeaveOrganization", "organizations:DescribeOrganization"],
"Resource": "*",
"Condition": {
"ArnNotEquals": {
"aws:PrincipalArn": "arn:aws:iam::*:role/doitintl-mgmt-role"
}
}
}
]
}

Move Flexsave accounts to an OU

We recommend grouping all Flexsave accounts together using an organizational unit (OU) to simplify the account management. For example, you can attach an SCP to the OU.

You can deploy a Lambda function in your environment to move matching Flexsave accounts to an OU of your choice. As you own the Lambda function, you do not need to grant extra permissions to DoiT.

Lambda function

Below is an example Lambda function. Before using it in your environment, fill in the ORG_ROOT and DESTINATION_OU or set them as environment variables using os.environ['ORG_ROOT'] and os.environ['DESTINATION_OU']. You can also modify the Lambda function for additional tasks, for example, tagging an account when moving it into the OU.

import boto3

ORG_ROOT = "XXX"
DESTINATION_OU = "XXX"


def handle_flexsave(event, context):
details = event["detail"]

if details["eventName"] == "AcceptHandshake":
if "responseElements" in details and "handshake" in details["responseElements"]:
handshake = details["responseElements"]["handshake"]
if handshake["action"] == "INVITE" and handshake["state"] == "ACCEPTED":
account_id = next(
(
resource["value"]
for resource in handshake["resources"]
if resource["type"] == "ACCOUNT"
),
None,
)
if account_id:
handle_account(account_id)
return
print(f"can't find account in payload")
return
print("Not a relevant event")


def handle_account(account_id):
print(f"Processing event for account {account_id}")
org_client = boto3.client("organizations")

response = org_client.describe_account(AccountId=account_id)
account_name = response["Account"]["Name"]

if account_name.startswith("fs"):
org_client.move_account(
AccountId=account_id,
SourceParentId=ORG_ROOT,
DestinationParentId=DESTINATION_OU,
)
else:
print(f"Account {account_name} not associated with Flexsave")

Policy for the Lambda

Attach the following policy to the execution role of your Lambda function (assuming the Lambda function is named flexsave-move and the Lambda function handler is flexsave_move.handle_flexsave).

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "LogOperations",
"Effect": "Allow",
"Action": ["logs:PutLogEvents", "logs:CreateLogStream", "logs:CreateLogGroup"],
"Resource": [
"arn:aws:logs:us-east-1:XXX:log-group:/aws/lambda/flexsave-move:*:*",
"arn:aws:logs:us-east-1:XXX:log-group:/aws/lambda/flexsave-move:*"
]
},
{
"Sid": "FlexsaveManagement",
"Effect": "Allow",
"Action": ["organizations:DescribeAccount", "organizations:MoveAccount"],
"Resource": "*"
}
]
}

EventBridge trigger

If you have configured a trail for management events, you can add an EventBridge trigger as follows and point to your Lambda.

{
"source": ["aws.organizations"],
"detail-type": ["AWS API Call via CloudTrail"],
"detail": {
"eventSource": ["organizations.amazonaws.com"],
"eventName": ["AcceptHandshake"]
}
}