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 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 accounts by name, you can further group them 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 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"]
}
}