#refarch (2024-04)
Cloud Posse Reference Architecture
2024-04-15
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 ?
policy_name can be whatever you’d like, and if not specified will use module.this.id. for example
policy_name = "myPolicyName"
there are 2 different approaches to defining policy_documents
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
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
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?
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
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 ?
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?
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 }}
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)
for example, this can be used to crerte such a system user https://github.com/cloudposse/terraform-aws-iam-system-user
Terraform Module to Provision a Basic IAM System User Suitable for CI/CD Systems (E.g. TravisCI, CircleCI)
Thank you so much for explaining this.
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.
Like, this guy here - https://sweetops.slack.com/archives/CDYGZCLDQ/p1698857535957889?thread_ts=1690386438.192609&cid=CDYGZCLDQ
CloudPosse position on using a non-root account to control SSO reverted. They use root for SSO as do I now.
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)
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/
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)
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.
@Dan Miller (Cloud Posse) @Erik Osterman (Cloud Posse) ^
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?
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
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
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