Logo

Autoschematic

AWS IAM Users, Roles, Groups and Policies

In this guide, we'll be using the AWS IAM connector (autoschematic-connector-aws-iam).

As opposed to the last guide, where we imported existing infrastructure and modified it, here we'll be creating new IAM resources from scratch.

There's a demo repo for this example, too - all it contains is autoschematic.ron, so skip it if you feel you can handle setting it up yourself.

autoschematic.ron
AutoschematicConfig(
    prefixes: {
        "main": Prefix(
            connectors: [
                Connector(
                    shortname: "aws/iam",
                    spec: Cargo(
                        name: "autoschematic-connector-aws-iam",
                        version: "0.9.0"
                    )
                ),
            ]
        )
    },
)

Scaffolding resources with autoschematic create

To help users quickly draft and create new resources, the Autoschematic protocol allows each connector to supply skeleton resources of various types. You can see what skeletons are available by using autoschematic create to select your prefix and connector interactively, and fill in the address template like so:

autoschematic create
Select connector: aws/iam
Select object: aws/iam/roles/[role_name].ron
role_name: minecraft-server-support
Writing main/aws/iam/roles/minecraft-server-support.ron
autoschematic create
Select connector: aws/iam
Select object: aws/iam/policies/[policy_name].ron
policy_name: minecraft-support-access
Writing main/aws/iam/policies/minecraft-support-access.ron

Now, we'll modify our policy to grant access to a certain S3 bucket, and we'll attach that policy by its ARN output value to the IAM role:

main/aws/iam/policies/minecraft-support-access.ron
IamPolicy(
    policy_document: {
        "Statement": [
            {
                "Action": [
                    "s3:GetObject",
                    "s3:ListBucket",
                ],
                "Condition": {
                    "StringEquals": {
                        "aws:PrincipalTag/Department": "Data",
                    },
                },
                "Effect": "Allow",
                "Resource": [
                    "arn:aws:s3:::minecraft-logs",
                    "arn:aws:s3:::minecraft-logs/*",
                ],
            },
        ],
        "Version": "2012-10-17",
    },
    tags: {},
)
main/aws/iam/roles/minecraft-server-support.ron
IamRole(
    attached_policies: [
        "out://aws/iam/policies/minecraft-support-access.ron[arn]"
    ],
    assume_role_policy_document: {
        "Statement": [
            {
                "Action": "sts:AssumeRole",
                "Effect": "Allow",
                "Principal": {
                    "Service": "ec2.amazonaws.com",
                },
            },
        ],
        "Version": "2012-10-17",
    },
    tags: {},
)

See the "out://" syntax in the IAM role? That's a reference to an output provided by another file. Since the IAM policy doesn't exist yet, Autoschematic will have to handle creating the IAM policy first before the IAM role.

Let's git add what we have so far, and apply it!

git add main/aws/iam/
autoschematic apply
╔══════════════════════════════════════════════════════════════════════════════╗
║ At main/aws/iam/policies/minecraft-support-access.ron:
║  ⟣ Create new IAM policy minecraft-support-access
╚══════════════════════════════════════════════════════════════════════════════╝
 ◇ Plan complete.
Type 2109 to execute all of the above actions and commit.
Hit Ctrl-c to cancel.
>2109
╔══════════════════════════════════════════════════════════════════════════════╗
║ At main/aws/iam/policies/minecraft-support-access.ron:
║  ⟖ Created IAM policy `/minecraft-support-access`
╚══════════════════════════════════════════════════════════════════════════════╝
 ⊬ Some files were not applied as they were missing outputs.
║ At main/aws/iam/roles/minecraft-server-support.ron:
 [SET!] aws/iam/policies/minecraft-support-access.ron[arn]  
 ◈ Apply succeeded! Some resources were deferred on outputs that are now available. Do you wish to continue applying? yes
╔══════════════════════════════════════════════════════════════════════════════╗
║ At main/aws/iam/roles/minecraft-server-support.ron:
║  ⟣ Create new IAM role /minecraft-server-support
║  ⟣ Attach policy `arn:aws:iam::467992565187:policy/minecraft-support-access` for IAM role `/minecraft-server-support`
╚══════════════════════════════════════════════════════════════════════════════╝
 ◇ Plan complete.
Type 0438 to execute all of the above actions and commit.
Hit Ctrl-c to cancel.
>0438
╔══════════════════════════════════════════════════════════════════════════════╗
║ At main/aws/iam/roles/minecraft-server-support.ron:
║  ⟖ Created IAM role `/minecraft-server-support`
║  ⟖ Attached policy `arn:aws:iam::467992565187:policy/minecraft-support-access` to role `/minecraft-server-support`
╚══════════════════════════════════════════════════════════════════════════════╝
 ◈ Apply succeeded! Do you wish to run git commit to track the new state? 

Nice. So, this is a sort of multi-stage plan-apply flow. Autoschematic is designed to be very explicit at all stages in terms of what actions it will take. Terraform, on the other hand, can be a little less deterministic.

If you're wondering whether there are other AWS connectors available, there are! They're in varying stages of stability, but you can have similar fun with Route53, S3, VPCs, and more.

Up next: Github Repos and Repo Policies