Terraform - AWS IAM user with Programmatic access - amazon-web-services

I'm working with aws via terraform.
I'm trying to create an IAM user with Access type of "Programmatic access".
With the AWS management console this is quite simple:
When trying with Terraform (reference to docs) it seems that only the following arguments are supported:
name
path
permissions_boundary
force_destroy
tags
Maybe this should be configured via a policy?
Any help will be appreciated.
(*) Related question with different scenario.

You can use aws_iam_access_key (https://www.terraform.io/docs/providers/aws/r/iam_access_key.html) terraform resource to create Access keys for the user and that should imply that user has Programmatic Access.
Hope this helps.

The aws_iam_user resource needs to also have an aws_iam_access_key resource created for it.
The iam-user module has a comprehensive example of using it.
You could also use that module straight from the registry and let that do everything for you.

If you dont want to encrypt and just looking for Access key & Secret key into plain text you can use this
main.tf
resource "aws_iam_access_key" "sagemaker" {
user = aws_iam_user.user.name
}
resource "aws_iam_user" "user" {
name = "user-name"
path = "/"
}
data "aws_iam_policy" "sagemaker_policy" {
arn = "arn:aws:iam::aws:policy/AmazonSageMakerFullAccess"
}
resource "aws_iam_policy_attachment" "attach-policy" {
name = "sagemaker-policy-attachment"
users = [aws_iam_user.user.name]
policy_arn = data.aws_iam_policy.sagemaker_policy.arn
}
output.tf
output "secret_key" {
value = aws_iam_access_key.user.secret
}
output "access_key" {
value = aws_iam_access_key.user.id
}
you will get the Access key and secret key into the plain text you can directly use it.

Related

How to create public google bucket with uniform_bucket_level_access enabled?

I want to create publicly accessible Google Cloud Bucket with uniform_bucket_level_access enabled using terraform. All of the examples on provider's docs which are for public bucket does not contain this setting.
When I try to use:
resource "google_storage_bucket_access_control" "public_rule" {
bucket = google_storage_bucket.a_bucket.name
role = "READER"
entity = "allUsers"
}
resource "google_storage_bucket" "a_bucket" {
name = <name>
location = <region>
project = var.project_id
storage_class = "STANDARD"
uniform_bucket_level_access = true
versioning {
enabled = false
}
}
I get the following error:
Error: Error creating BucketAccessControl: googleapi: Error 400: Cannot use ACL API to update bucket policy when uniform bucket-level access is enabled. Read more at https://cloud.google.com/storage/docs/uniform-bucket-level-access, invalid
If I remove the line for uniform access everything works as expected.
Do I have to use google_storage_bucket_iam resource for achieving this ?
You will have to use google_storage_bucket_iam. I like to use the member one so I don't accidentally clobber other IAM bindings, but you can use whatever your needs dictate.
resource "google_storage_bucket_iam_member" "member" {
bucket = google_storage_bucket.a_bucket.name
role = "roles/storage.objectViewer"
member = "allUsers"
}
EDIT: Use this instead of the google_storage_bucket_access_controls resource that you have.

Set cognito identity pool providers role resolution via Terraform

im trying to deploy cognito for opensearch via terraform. I have a manually built cognito working and ow trying to port it to terraform.
does anyone know how to set the below part?:
Choose role from token
role resolution 'DENY'
Terraform for the identity pool:
resource "aws_cognito_identity_pool" "cognito-identity-pool" {
identity_pool_name = "opensearch-${var.domain_name}-identity-pool"
allow_unauthenticated_identities = false
cognito_identity_providers {
client_id = aws_cognito_user_pool_client.cognito-user-pool-client.id
provider_name = aws_cognito_user_pool.cognito-user-pool.endpoint
}
}
ive tried adding server_side_token_check = false but no joy..
You need to use a different resource, namely aws_cognito_identity_pool_roles_attachment [1]. In order to achieve the same thing you see in the AWS console, you need to add the following block:
resource "aws_cognito_identity_pool_roles_attachment" "name" {
identity_pool_id = aws_cognito_identity_pool.cognito-identity-pool.id
roles = {
"authenticated" = <your-role-arn>
}
role_mapping {
ambiguous_role_resolution = "Deny"
type = "Token"
identity_provider = "${aws_cognito_user_pool.cognito-user-pool.endpoint}:${aws_cognito_user_pool_client.cognito-user-pool-client.id}"
}
}
Note that the roles block is required and the key can be authenticated or unathenticated. Additionally, you will probably have to figure out what kind of permissions the role will need and create it. The example in the documentation can be used as a blueprint. There are also other settings like mapping_rule block which might be of use to you, but since the details are lacking I omitted it from the answer.
[1] https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cognito_identity_pool_roles_attachment

Get AWS account ID by name

I know there are multiple ways to get AWS account name by its ID, but is the opposite possible? Is there a way to programmatically (API, CLI, terraform etc.) get AWS account ID by its name?
Update: Forgot to mention that these accounts exist under organization structure in a specific OU, maybe this could help.
While this is not ideal, I realized that aws organizations list-accounts-for-parent command is the best compromise. It would give me all accounts within given OU, which I can filter by account name.
Given that my solution will ultimately be implemented in terraform I came out with something like this
data "external" "accounts" {
program = ["aws", "organizations", "list-accounts-for-parent", "--parent-id", local.ou, "--query", "Accounts[?Name==`${local.account_name}`] | [0]"]
}
locals {
ou = "ou-12345678"
account_name = "my-cool-account"
account_id = lookup(data.external.tools_accounts.result, "Id", null)
}
it would execute AWS CLI command, return back a map of key/values if account info is found, and lookup function would retrieve the account ID.
I was able to solve with the following:
data "aws_organizations_organization" "main" {}
locals {
account-name = "account1"
account-index = index(data.aws_organizations_organization.main.accounts.*.name, local.account-name)
account-id = data.aws_organizations_organization.main.accounts[local.account-index].id
}
output "account_id" {
value = local.account-id
}

Add new users as members to GCP Cloud Identity Group using Terraform

I have the gcp-organization-admins Cloud Identity User Group to which I want to add a new user user-01#example.com as a Member using Terraform.
Getting error - Error creating GroupMembership: googleapi: got HTTP response code 404.
The requested URL /v1beta1/gcp-organization-admins#example.com/memberships?alt=json was not found on this server.
Can anyone suggest how to resolve this please.
fyi...Just as a test, I was able to create new Cloud Identity user groups and added some test users into it without any problems using Terraform module https://github.com/terraform-google-modules/terraform-google-group
#=====================
# terraform.tfvars
#=====================
org_admin_user = ["user-01#example.com"]
org_admin_group = "gcp-organization-admins#example.com"
#=========================================================
# add-member.tf (adds user to google group as a member)
#=========================================================
resource "google_cloud_identity_group_membership" "user-01" {
for_each = toset(var.org_admin_user)
provider = google-beta
group = var.org_admin_group
preferred_member_key {
id = each.key
}
roles {
name = "MEMBER"
}
}
I ran into this same problem. Turns out that Terraform wants the GCP Group "name" and not the email address.
So the group attribute of the google_cloud_identity_group_membership resource block should look something like "groups/23097432uwhwiyo" and not "gcp-organization-admins#example.com"
You can look up the group "name" with the following gcloud command:
gcloud identity groups describe "gcp-organization-admins#example.com"
This might to be the same issue as documented here: https://github.com/hashicorp/terraform-provider-google/issues/7616
A comment in that bug mentions the following:
I can work around the above issue by switching the order of the two roles in the resource, i.e.
From
roles { name = "MANAGER" }
roles { name = "MEMBER" }
to
roles { name = "MEMBER" }
roles { name = "MANAGER" }
https://github.com/hashicorp/terraform-provider-google/issues/7616#issuecomment-742779169

Is there a way to read the monitoring_role_arn from RDS into terraform.tfvars?

Instead of having to update this value manually each time, can I read this value directly into my terraform.tfvars file?
monitoring_role_arn = "arn:aws:iam::account:role/value"
you can use locals
Define in *.tf file
locals {
monitoring_role_arn = "arn:aws:iam::account:role/value"
}
in variables file you can refer as below
your_var = local.monitoring_role_arn
Role lookup option
Alternatively use the IAM Role lookup by the name given to the targeted role.
Ref: Data Source: aws_iam_role
To looup the resource by role name:
data "aws_iam_role" "monitoring_role_arn" {
name = "an_example_role_name" // This is the name of the role that appear in the AWS IAM Console
}
To get the ARN use the following line:
data.aws_iam_role.monitoring_role_arn.arn