#refarch (2024-04)

Cloud Posse Reference Architecture

2024-04-15

Taimur Gibson avatar
Taimur Gibson

Hi, I’m trying to use the iam-role module to create some custom policy documents to allow an EC2 instance to access an S3 bucket. Can someone provide an example of how the policy_documents and policy_name variables are used?

Do I need to specify the JSON within the yaml file for the IAM role I am creating? Or do I need to create a [policy-POLICYNAME.tf](http://policy-POLICYNAME.tf) file similar to how it’s setup for aws-sso ?

https://github.com/cloudposse/terraform-aws-components/tree/main/modules/iam-role#input_policy_documents

Dan Miller (Cloud Posse) avatar
Dan Miller (Cloud Posse)

policy_name can be whatever you’d like, and if not specified will use module.this.id. for example

policy_name = "myPolicyName"
Dan Miller (Cloud Posse) avatar
Dan Miller (Cloud Posse)

there are 2 different approaches to defining policy_documents

Dan Miller (Cloud Posse) avatar
Dan Miller (Cloud Posse)

first, you could create an additional file and define your policies in terraform like this:

data "aws_iam_policy_document" "resource_full_access" {
  statement {
    sid       = "FullAccess"
    effect    = "Allow"
    resources = ["arn:aws:s3:::bucketname/path/*"]

    actions = [
      "s3:PutObject",
      "s3:PutObjectAcl",
      "s3:GetObject",
      "s3:DeleteObject",
      "s3:ListBucket",
      "s3:ListBucketMultipartUploads",
      "s3:GetBucketLocation",
      "s3:AbortMultipartUpload"
    ]
  }
}

data "aws_iam_policy_document" "base" {
  statement {
    sid = "BaseAccess"

    actions = [
      "s3:ListBucket",
      "s3:ListBucketVersions"
    ]

    resources = ["arn:aws:s3:::bucketname"]
    effect    = "Allow"
  }
}

Then extend / override the module to include these policies: [main_override.tf](http://main_override.tf)

module "role" {
  policy_documents = [
    data.aws_iam_policy_document.resource_full_access.json,
    data.aws_iam_policy_document.base.json
  ]
}

https://github.com/cloudposse/terraform-aws-iam-role?tab=readme-ov-file#usage

Dan Miller (Cloud Posse) avatar
Dan Miller (Cloud Posse)

Or you can define the policy in JSON directly in you stack catalog, like this:

components:
  terraform:
    example-iam-role:
      metadata:
        component: iam-role
      vars:
        policy_documents:
          - |
            {
              "Version": "2012-10-17",
              "Statement": [
                {
                  "Sid": "",
                  "Effect": "Allow",
                  "Action": "ec2:*",
                  "Resource": "*"
                },
                {
                  "Sid": "",
                  "Effect": "Allow",
                  "Action": "lambda:*",
                  "Resource": "*"
                }
              ]
            }

Or you should be able to list it as YAML directly

        policy_documents:
          - Version: "2012-10-17"
            Statement:
              - Sid: ""
                Effect": "Allow"
                Action": "ec2:*"
                Resource": "*"
...

2024-04-16

Marat Bakeev avatar
Marat Bakeev

Guys, sorry if this is stupid - but what exactly is the role of aws-teams and aws-teams-roles components? If I have aws-sso for users, why would I need teams and team-roles? Or is it just for system roles? And where in there the system users are created?

Andriy Knysh (Cloud Posse) avatar
Andriy Knysh (Cloud Posse)

aws-teams and aws-teams-roles are components to create static IAM roles (in contrast to aws-sso which creates dynamic roles)

aws-teams is used to create the primary IAM roles in the identity account (which is the accoiunt that manages access, it’s not a root account)

aws-team-roles is used to provision delegated IAM roles in other accounts (not identity)

You assume a primary role in the identity account, then can assume a delegated role in the other accounts to access them

1
Marat Bakeev avatar
Marat Bakeev

I thought you guys moved away from using the identity account? Or it was just for the SSO component, and users and roles are still created in identity ?

Marat Bakeev avatar
Marat Bakeev

And what is the process to create a system identity? For example, I want to run terraform from some private CI\CD, then it needs an aws user it would use to assume a role, right? So, what’s the pattern to create that system user?

Andriy Knysh (Cloud Posse) avatar
Andriy Knysh (Cloud Posse)

if your CI/CD can run on EC2 instances that you provision (e.g. GHA or Spacelift on EC2 private workers), then we create a primary cicd IAM role using aws-teams and allow the role to assume the delegated roles in the other acounts created by aws-team-roles. Then you can use, e.g. a GH action (which runs on your EC2) to assume that primary cicd role

      # <https://github.com/marketplace/actions/configure-aws-credentials-action-for-github-actions>
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-region: ${{ env.AWS_REGION }}
          role-to-assume: ${{ env.IAM_ROLE_ARN }}
          role-session-name: ${{ env.IAM_ROLE_SESSION_NAME }}
1
Andriy Knysh (Cloud Posse) avatar
Andriy Knysh (Cloud Posse)

if you don’t control that process (e.g. you are using an external SaaS CI/CD), then you can create an IAM user and store the access keys as secrets in the CI/CD secrets)

Andriy Knysh (Cloud Posse) avatar
Andriy Knysh (Cloud Posse)

for example, this can be used to crerte such a system user https://github.com/cloudposse/terraform-aws-iam-system-user

cloudposse/terraform-aws-iam-system-user

Terraform Module to Provision a Basic IAM System User Suitable for CI/CD Systems (E.g. TravisCI, CircleCI)

1
Marat Bakeev avatar
Marat Bakeev

Thank you so much for explaining this.

Marat Bakeev avatar
Marat Bakeev

Could you also tell me about identity vs root account? I’ve seen discussions here that people are using root account for deploying sso, so I have to configure it as the ‘idenity’ account.

Marat Bakeev avatar
Marat Bakeev

CloudPosse position on using a non-root account to control SSO reverted. They use root for SSO as do I now.

Andriy Knysh (Cloud Posse) avatar
Andriy Knysh (Cloud Posse)

identity vs root

root is your Org management account which is created by AWS. You want to restrict access to it as much as possible (since it controls the entire Org and billing)

Dan Miller (Cloud Posse) avatar
Dan Miller (Cloud Posse)

To chime in here, if you have access to our reference architecture this page may help too. We recently added videos that explain the “what” “why” and “how” of each of our core topics https://docs.cloudposse.com/reference-architecture/fundamentals/iam-identity/

2
Andriy Knysh (Cloud Posse) avatar
Andriy Knysh (Cloud Posse)

you create identity for a single purpose to manage IAM roles for people and machines. People then assume a role in identity, then a role in another account to access it. The root account is not involved at all in this process (so it’s more secure, protected, and audited)

Marat Bakeev avatar
Marat Bakeev

I wish I had access to reference architecture.. But it’s not always possible. It would be awesome, if you guys had a way to get access to just the documentation for a smaller fee or a subscription for a year or something.

Andriy Knysh (Cloud Posse) avatar
Andriy Knysh (Cloud Posse)

@Dan Miller (Cloud Posse) @Erik Osterman (Cloud Posse) ^

Marat Bakeev avatar
Marat Bakeev

Guys, one more thing - are you open to explain the benefits of dynamic and static roles? Why would I want to use static roles for humans, if I have sso?

Dan Miller (Cloud Posse) avatar
Dan Miller (Cloud Posse)

The primary reason is because we can use static roles to apply Terraform. We can assume 1 role in the identity account and then assume with Terraform another role in every other account. That way the human only has to assume 1 role and then can apply terraform everywhere.

Plus since the role is static, we can grant this specific role access to a centralized Terraform state

Dan Miller (Cloud Posse) avatar
Dan Miller (Cloud Posse)

For example, here you can have a “devops” role and a “gitops” role in your identity account. Then we have “terraform” roles in dev and prod accounts.

The human user only has to assume “devops”, whereas the machine user assumes “gitops”. But both assume the same “terraform” role in the target accounts

1
Andriy Knysh (Cloud Posse) avatar
Andriy Knysh (Cloud Posse)

another thing, when you provision an EKS cluster, you have to use a static role (not SSO) since the role that provisions the cluster becomes the Kubernetes admin. You can’t use dynamic SSO roles to provision EKS clusters

1
    keyboard_arrow_up