#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