# How to Manage AWS SSO Account Assignments in CloudFormaton

## Here's a sample template
https://github.com/hayao-k/aws-sso-cloudformation-sample

## Introduction
On 9/10/2020, AWS SSO API (sso-admin) was finally added to AWS Single Sign-On and operations through the AWS CLI/SDK and CloudFormation are now supported.

🚀 [AWS Single Sign-On adds account assignment APIs and AWS CloudFormation support to automate multi-account access management](
https://aws.amazon.com/jp/about-aws/whats-new/2020/09/aws-single-sign-on-adds-account-assignment-apis-and-aws-cloudformation-support-to-automate-multi-account-access-management/)

Until now, operations such as permission sets and assigning users/groups to AWS accounts had to be configured manually in the console.  
This update paves the way for automating account assignment settings and getting to IaC!

## Supported CloudFormation resources
As of September 2020, CloiudFormation will support the following two resources.

* [AWS::SSO::PermissionSet](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sso-permissionset.html)
Specifies the permissions to be set on the AWS SSO instance.

* [AWS::SSO::Assignment](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sso-assignment.html)
Assign access to your AWS account using the specified permission set.

## Points to note
Creating an AWS SSO resource in CloudFormation requires various IDs such as InstanceArn, Identiy-Store-Id, UserId, and GroupId.  
These IDs are not display in the AWS SSO console and must be obtained via API.  
To use the AWS SSO API (sso-admin), make sure you have AWS CLI version 1.18.136 or 2.0.48 or higher.

## Example of a permission set
This is an example of creating a simple set of permissions using AWS management policies.

```yaml
PermissionSet:
  Type: AWS::SSO::PermissionSet
  Properties:
    InstanceArn: 'arn:aws:sso:::instance/ssoins-xxxxxxxxxxxxxxxx'
    Name: 'AdministratorAccess'
    ManagedPolicies:
    - 'arn:aws:iam::aws:policy/AdministratorAccess'
```

For InstanceArn, specify the ARN of the SSO instance.
This value is obtained from list-instances in sso-admin.

```shell
$ aws sso-admin list-instances
{
    "Instances": [
        {
            "InstanceArn": "arn:aws:sso:::instance/ssoins-xxxxxxxxxxxxxxxx",
            "IdentityStoreId": "d-xxxxxxxxxx"
        }
    ]
}
```

## Example of Account Assignment
Specify the AWS account, privilege set, and principal as follows.

```yaml
Assignment: 
  Type: AWS::SSO::Assignment
  Properties: 
    InstanceArn: 'arn:aws:sso:::instance/ssoins-xxxxxxxxxxxxxxxx'
    PermissionSetArn: 'arn:aws:sso:::permissionSet/ssoins-xxxxxxxxxxxxxxxx/ps-xxxxxxxxxxxxxxxx'
    TargetId: '123456789012'
    TargetType: AWS_ACCOUNT
    PrincipalId: 'f81d4fae-7dec-11d0-a765-00a0c91e6bf6'
    PrincipalType: 'GROUP'
```

You can check the PermissionSetArn with sso-admin's describe-permission-set.

```shell
$ aws sso-admin list-permission-sets \
> --instance-arn arn:aws:sso:::instance/ssoins-xxxxxxxxxxxxxxxx 
{
    "PermissionSets": [
        "arn:aws:sso:::permissionSet/ssoins-xxxxxxxxxxxxxxxx/ps-xxxxxxxxxxxxxxxx",
        "arn:aws:sso:::permissionSet/ssoins-xxxxxxxxxxxxxxxx/ps-yyyyyyyyyyyyyyyy",
        "arn:aws:sso:::permissionSet/ssoins-xxxxxxxxxxxxxxxx/ps-zzzzzzzzzzzzzzzz"
    ]
}

$ aws sso-admin describe-permission-set \
> --instance-arn arn:aws:sso:::instance/ssoins-xxxxxxxxxxxxxxx \
> --permission-set-arn arn:aws:sso:::permissionSet/ssoins-xxxxxxxxxxxxxxx/ps-xxxxxxxxxxxxxxx
{
    "PermissionSet": {
        "Name": "AdministratorAccess",
        "PermissionSetArn": "arn:aws:sso:::permissionSet/ssoins-xxxxxxxxxxxxxxx/ps-xxxxxxxxxxxxxxx",
        "CreatedDate": "2020-09-09T19:01:06.758000+09:00",
        "SessionDuration": "PT1H"
    }
}
```

If you have created a permission set in CloudFormation, use the built-in Fn::GetAtt function.

```yaml
    PermissionSetArn: !GetAtt LogicalId.PermissionSetArn
```

Only AWS_ACCOUNT can be specified for TargetType.
Specify the AWS account ID to be assigned for TargetId.

```yaml
    TargetId: '123456789012'
    TargetType: AWS_ACCOUNT
```

PrincipalType can be specified as either USER or GROUP.  
PrincipalId must be specified as the GUID of the user/group to be assigned.

```yaml
    PrincipalId: 'f81d4fae-7dec-11d0-a765-00a0c91e6bf6'
    PrincipalType: 'GROUP'
```

Many operations of the AWS SSO API (sso-admin) rely on user and group identifiers called principals.  
Use the AWS SSO Identity Store API (identitystore) to get the GUIDs for a user/group.

Specify the identity store identifier obtained from list-instances in sso-admin for `--identity-store-id`.  
For list-users you can specify a UserName and for list-group you can specify a DisplayName as filter.

```shell
$ aws identitystore list-users \
> --identity-store-id d-xxxxxxxxxx \
> --filters AttributePath=UserName,AttributeValue="user@example.com"
{
    "Users": [
        {
            "UserName": "userXX@examle.com",
            "UserId": "f81d4faxge-7dec11d8-a765-3at5-80e4-00a0c91e6bf6"
        }
    ]
}

$ aws identitystore list-groups \
> --identity-store-id d-xxxxxxxxxx \
> --filters AttributePath=DisplayName,AttributeValue="TestGroup"
{
    "Groups": [
        {
            "GroupId": "f81d4faxge-789fcfa5-005c-4379-89ba-10a11e641c17"
            "DisplayName": "TestGroup"
        }
    ]
}
```

See the GitHub link at the top for the entire template.

## Summary
* The AWS SSO API (sso-admin) has been added, enabling partial automation of administrative tasks and IaC
* CloudFormation supports permission set creation and account assignment
* User/Group IDs needed to identify principals must be obtained through the IdentityStore API
  * Full automation seems to be difficult at the moment because of the need to search for IDs when assigning accounts
  * AWS SSO console does not display these IDs and ARNs, which is a bit inconvenient
* That said, it's exciting to be able to manage AWS SSO with APIs!

## References
AWS CloudFormation User Guide - SSO resource type reference  
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/AWS_SSO.html

AWS CLI Command Reference - sso-admin  
https://awscli.amazonaws.com/v2/documentation/api/latest/reference/sso-admin/index.html

AWS CLI Command Reference - identitystore  
https://awscli.amazonaws.com/v2/documentation/api/latest/reference/identitystore/index.html
