I'm trying to convert a Cloud Formation script to Terraform. One of the issues I'm running into in the script
Cloud Formation:
"Resources": {
"*******InstanceProfile": {
"Condition": "IsInstanceProfile",
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
},
"Policies": [
{
"PolicyName": "********-*******-instance",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Resource": [
{
"Fn::Sub": "arn:aws:iam::*:role/${ReadOnlyRole}"
},
{
"Fn::Sub": "arn:aws:iam::${AWSOrganizationsAccountID}:role/${OrganizationsRole}"
}
]
}
]
}
}
],
"RoleName": {
"Ref": "AccessName"
}
}
}
I am ASSUMING I can use an inline_policy within a resource like in aws_iam_role. Here is my Terraform snippet that I've produced but get errors:
resource "aws_iam_role" "*****_instance_profile" {
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = "sts:AssumeRole"
Effect = "Allow"
Sid = ""
Principal = {
Service = "ec2.amazonaws.com"
}
},
]
})
policy = jsonencode({
Version = "2012-10-17"
Statement = [
Action = ["sts:AssumeRole"]
Effect = "Allow"
Resource = "arn:aws:iam::*:role/${ReadOnlyRole"
]
})
}
I guess I'm stuck with adding the resource within the policy. How would anyone handle this conversion? Do you folks think I'm going down the correct path with aws_iam_role? And, if so, how would you handle multiple resources in an inline_policy?
I would just use the official documentation when adding multiple resources to a policy.
data "aws_iam_policy_document" "example" {
statement {
actions = [
"s3:ListAllMyBuckets",
"s3:GetBucketLocation",
]
resources = [
"arn:aws:s3:::*",
]
}
statement {
actions = [
"s3:*",
]
resources = [
"arn:aws:s3:::${var.s3_bucket_name}/home/&{aws:username}",
"arn:aws:s3:::${var.s3_bucket_name}/home/&{aws:username}/*",
]
}
}
resource "aws_iam_user" "user" {
name = "test-user"
}
resource "aws_iam_policy" "policy" {
name = "test-policy"
description = "A test policy"
policy = data.aws_iam_policy_document.example.json
}
resource "aws_iam_user_policy_attachment" "test-attach" {
user = aws_iam_user.user.name
policy_arn = aws_iam_policy.policy.arn
}
I know this question has been asked before, and I've seen several of the SO responses and read the AWS docs on the subject... I have a terraform module that, in part, builds out an ECS service, cluster, task, and Fargate container:
###############################################################################
#### EFS for added stoage
#### TODO: remove in favor of larger ephmemeral storage when terraform supports it
###############################################################################
resource "aws_efs_file_system" "test" {
creation_token = var.fargate_container_name
tags = {
Name = "test"
}
}
resource "aws_efs_access_point" "test" {
file_system_id = aws_efs_file_system.test.id
root_directory {
path = "/"
}
}
resource "aws_efs_mount_target" "test" {
count = 3
file_system_id = aws_efs_file_system.test.id
subnet_id = local.directory_subnet_ids[count.index]
security_groups = [aws_security_group.test_ecs.id]
}
###############################################################################
#### ECS Task and Service
###############################################################################
resource "aws_ecs_task_definition" "test" {
family = "test"
requires_compatibilities = ["FARGATE"]
cpu = var.test_cpu_limit
memory = var.test_memory_limit
container_definitions = <<JSON
[
{
"name": "test",
"image": "${var.test_image_registry_repo_and_image_name}",
"memory": ${var.test_memory_limit},
"cpu": ${var.test_cpu_limit},
"essential": true,
"portMappings": [
{
"containerPort": 7001,
"hostPort": 7001,
"protocol": "tcp"
},
{
"containerPort": 7002,
"hostPort": 7002,
"protocol": "tcp"
},
{
"containerPort": 9001,
"hostPort": 9001,
"protocol": "tcp"
},
{
"containerPort": 9002,
"hostPort": 9002,
"protocol": "tcp"
}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "${aws_cloudwatch_log_group.test_ecs.name}",
"awslogs-region": "${data.aws_region.main.name}",
"awslogs-stream-prefix": "ecs"
}
},
"linuxParameters": {
"initProcessEnabled": true
},
"mountPoints": [
{
"containerPath": "/",
"sourceVolume": "${var.fargate_container_name}"
}
]
}
]
JSON
volume {
name = var.fargate_container_name
efs_volume_configuration {
file_system_id = aws_efs_file_system.test.id
transit_encryption = "ENABLED"
transit_encryption_port = 2049
authorization_config {
access_point_id = aws_efs_access_point.test.id
iam = "ENABLED"
}
}
}
network_mode = "awsvpc"
# The role used by ECS to pull images and the like.
execution_role_arn = aws_iam_role.test_ecs_execution.arn
task_role_arn = aws_iam_role.test_task_ecs.arn
tags = merge(
local.tags, {
"Name" = "test"
}
)
}
resource "aws_ecs_service" "test" {
name = "test"
cluster = aws_ecs_cluster.test.id
task_definition = aws_ecs_task_definition.test.arn
desired_count = var.test_desired_count
enable_execute_command = true
platform_version = "1.4.0"
# service_registries {
# registry_arn = aws_service_discovery_service.test.arn
# container_name = "test"
# }
capacity_provider_strategy {
base = var.fargate_capacity_provider_base_value
capacity_provider = "FARGATE"
weight = var.fargate_capacity_provider_weight_value
}
capacity_provider_strategy {
base = var.fargate_spot_capacity_provider_base_value
capacity_provider = "FARGATE_SPOT"
weight = var.fargate_spot_capacity_provider_weight_value
}
network_configuration {
security_groups = [aws_security_group.test_ecs.id]
subnets = local.directory_subnet_ids
}
tags = merge(
local.tags, {
"Name" = "test"
}
)
}
resource "aws_security_group" "test_ecs" {
name_prefix = "test-ecs"
description = "Allow strict inbound access to ECS Tasks"
vpc_id = data.aws_vpc.primary.id
ingress {
from_port = 2049
to_port = 2049
protocol = "tcp"
cidr_blocks = [data.aws_vpc.primary.cidr_block]
}
ingress {
from_port = 7001
to_port = 7002
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 9001
to_port = 9002
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = merge(
local.tags, {
"Name" = "test-ecs"
}
)
}
resource "aws_iam_role" "test_task_ecs" {
name = "EST"
description = "Test."
permissions_boundary = data.aws_iam_policy.role_permissions_boundary.arn
assume_role_policy = <<POLICY
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "ecs-tasks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
POLICY
}
I've explicitly set the Fargate version in the service, I saw some other SO user answered stating that the VPC needed to have DNS hostnames and resolution set to true -- they are. I'm still getting the error:
container_linux.go:370: starting container process caused: process_linux.go:459: container init caused: rootfs_linux.go:71: creating device nodes caused: errno 524
It seems to be connected to "mountPoints" block in the container definition, as removing it will at least start the container, but it will not mount the EFS volume.
EDIT: Added ECS Task role
EDIT 2: Adding role permissions boundary:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "UseServices",
"Effect": "Allow",
"Action": [
"organizations:DescribeOrganization",
"cloudshell:*",
"compute-optimizer:*",
"amplify:*",
"appmesh:*",
"appmesh-preview:*",
"appconfig:*",
"appflow:*",
"clouddirectory:*",
"datapipeline:*",
"dms:*",
"dbqms:*",
"devicefarm:*",
"devops-guru:*",
"ds:*",
"autoscaling:*",
"imagebuilder:*",
"ec2-instance-connect:*",
"ecr-public:*",
"forecast:*",
"honeycode:*",
"proton:*",
"rds-db:*",
"rds-data:*",
"access-analyzer:*",
"ce:*",
"cur:*",
"health:*",
"pricing:*",
"ram:Get*",
"ram:List*",
"servicequotas:*",
"ssm:*",
"ssmmessages:*",
"support:*",
"tag:*",
"cloudfront:*",
"elasticloadbalancing:*",
"ecs:*",
"ecr:*",
"cloudwatch:*",
"synthetics:*",
"servicequotas:*",
"apigateway:*",
"rds:*",
"secretsmanager:*",
"route53:*",
"acm:*",
"resource-groups:*",
"servicediscovery:*",
"application-autoscaling:*",
"ec2messages:*",
"trustedadvisor:*",
"cloud9:*",
"codeartifact:*",
"codebuild:*",
"codecommit:*",
"codedeploy:*",
"codepipeline:*",
"codestar:*",
"codestar-connections:*",
"codestar-notifications:*",
"cognito-identity:*",
"cognito-idp:*",
"cognito-sync:*",
"dynamodb:*",
"eks:*",
"emr-containers:*",
"elasticache:*",
"elasticbeanstalk:*",
"elasticfilesystem:*",
"firehose:*",
"kafka:*",
"kinesis:*",
"kinesisanalytics:*",
"serverlessrepo:*",
"sqs:*",
"xray:*",
"workspaces:*",
"wam:*",
"appsync:*",
"athena:*",
"batch:*",
"states:*",
"backup:*",
"backup-storage:*",
"es:*",
"glue:*",
"databrew:*",
"lightsail:*",
"timestream:*",
"schemas:*",
"ec2:*",
"sts:AssumeRole",
"sts:TagSession",
"cloudformation:*",
"lambda:*",
"s3:*",
"sns:*",
"events:*",
"kms:*",
"logs:*",
"cloudtrail:*",
"iam:ListAccountAliases"
],
"Resource": "*"
},
{
"Sid": "AllowServiceLinkedRole",
"Effect": "Allow",
"Action": [
"iam:CreateServiceLinkedRole",
"iam:DeleteServiceLinkedRole",
"iam:GetServiceLinkedRoleDeletionStatus",
"iam:UpdateRole"
],
"Resource": [
"arn:aws:iam::*:role/aws-service-role/*"
]
},
{
"Sid": "AllowPolicy",
"Effect": "Allow",
"Action": [
"iam:GetPolicy",
"iam:DeletePolicy",
"iam:CreatePolicy",
"iam:GetPolicyVersion",
"iam:CreatePolicyVersion",
"iam:DeletePolicyVersion",
"iam:ListPolicyVersions"
],
"Resource": [
"arn:aws:iam::*:policy/*"
]
},
{
"Sid": "AllowReadRole",
"Effect": "Allow",
"Action": [
"iam:GetRole",
"iam:DeleteRole",
"iam:TagRole",
"iam:UpdateRoleDescription",
"iam:ListInstanceProfilesForRole",
"iam:ListAttachedRolePolicies",
"iam:ListRolePolicies",
"iam:UpdateAssumeRolePolicy",
"iam:PassRole",
"iam:GetRolePolicy"
],
"Resource": [
"arn:aws:iam::*:role/*"
]
},
{
"Sid": "AllowWriteRole",
"Effect": "Allow",
"Action": [
"iam:CreateRole",
"iam:DeleteRolePolicy",
"iam:AttachRolePolicy",
"iam:DetachRolePolicy",
"iam:PutRolePermissionsBoundary",
"iam:PutRolePolicy",
"iam:UpdateRole",
"iam:PassRole"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"iam:PermissionsBoundary": "arn:aws:iam::835718480179:policy/CuriPipelineAdministratorAccessPermBoundaries"
}
}
},
{
"Sid": "AllowWriteInstanceProfile",
"Effect": "Allow",
"Action": [
"iam:AddRoleToInstanceProfile",
"iam:CreateInstanceProfile",
"iam:DeleteInstanceProfile",
"iam:GetInstanceProfile",
"iam:ListInstanceProfiles",
"iam:RemoveRoleFromInstanceProfile"
],
"Resource": [
"arn:aws:iam::*:instance-profile/*"
]
},
{
"Sid": "DenyIamActions",
"Effect": "Deny",
"Action": [
"iam:*OpenIDConnect*",
"iam:*SAMLProvider*",
"iam:*User*",
"iam:*Group*",
"iam:*AccessKey*",
"iam:*Password*",
"iam:CreateAccountAliases",
"iam:DeleteAccountAliases",
"iam:*LoginProfile*",
"iam:*ServiceSpecificCredential*",
"iam:*MFADevice*",
"iam:*CredentialReport*",
"iam:*OrganizationsAccessReport*",
"iam:*SecurityTokenServicePreferences*",
"iam:GetAccountAuthorizationDetails",
"iam:GetAccountSummary"
],
"Resource": "*"
},
{
"Sid": "NoBoundaryPolicyEdit",
"Effect": "Deny",
"Action": [
"iam:CreatePolicyVersion",
"iam:DeletePolicy",
"iam:DeletePolicyVersion",
"iam:SetDefaultPolicyVersion"
],
"Resource": [
"arn:aws:iam::835718480179:policy/CuriPipelineAdministratorAccessPermBoundaries"
]
},
{
"Sid": "NoSelfRoleEdit",
"Effect": "Deny",
"Action": [
"iam:Add*",
"iam:Attach*",
"iam:Change*",
"iam:Create*",
"iam:Delete*",
"iam:Deactivate*",
"iam:Detach*",
"iam:Enable*",
"iam:Update*",
"iam:Put*",
"iam:Remove*",
"iam:Reset*",
"iam:Tag*",
"iam:Untag*"
],
"Resource": [
"arn:aws:iam::835718480179:role/CuriPipelineAdministratorAccess"
]
}
]
}
The whole problem had nothing to do with AWS, but the server I am running (weblogic) failed to start because I was trying to mount EFS in /, which cannot be done as it would overlay many critical startup and credential files. If I had the whole filesystem already on EFS (which I did not, I used a blank filesystem), then this likely would have been fine. I mounted it successfully to a lower subdirectory and the container spun up and is running.
I'm trying to hook up my amazon account to our Opsgenie account to get CloudWatch events pushed to the team. I followed this guide here: https://docs.opsgenie.com/docs/amazon-cloudwatch-events-integration
I'm creating the items in terraform, as we want to be able to create and destroy this environment on the fly and make it somewhat configurable. Everything seems to be created, but OpsGenie won't autoconfirm the SNS subscription to the topic. Even if I do the same thing in the UI, OpsGenie won't confirm.
Below is my terraform code:
##############################################################################
# Opsgenie integration
###############################################################################
resource "opsgenie_api_integration" "test_integration" {
name = "api-based-int"
type = "API"
responders {
type = "user"
id = opsgenie_user.first.id
}
enabled = true
allow_write_access = true
ignore_responders_from_payload = false
suppress_notifications = false
owner_team_id = opsgenie_team.test_team.id
}
resource "opsgenie_user" "first" {
username = "testerman#gmail.com"
full_name = "Tester Man"
role = "Admin"
}
resource "opsgenie_user" "second" {
username = "testerman2#gmail.com"
full_name = "Tester Man II"
role = "User"
}
resource "opsgenie_team" "test_team" {
name = "example"
description = "This team deals with all the things"
member {
id = opsgenie_user.first.id
role = "admin"
}
member {
id = opsgenie_user.second.id
role = "user"
}
}
###############################################################################
# Cloudwatch
###############################################################################
resource "aws_cloudwatch_event_rule" "opsgenie_cloudwatch_event_rule" {
name = "send_events_to_opsgenie"
description = "Send all events to opsgenie"
event_pattern = <<EOF
{
"source": [
"aws.sns"
]
}
EOF
}
resource "aws_cloudwatch_event_target" "opsgenie_cloudwatch_event_rule" {
rule = aws_cloudwatch_event_rule.opsgenie_cloudwatch_event_rule.name
target_id = "OpsGenie"
arn = aws_sns_topic.opsgenie_notifications.arn
}
###############################################################################
# SNS
###############################################################################
resource "aws_sns_topic" "opsgenie_notifications" {
name = "OpsGenie"
kms_master_key_id = aws_kms_key.kms_key_for_sns_topic.key_id
policy = <<POLICY
{
"Version":"2012-10-17",
"Statement":[{
"Effect": "Allow",
"Principal": {"Service":"events.amazonaws.com"},
"Action":[
"SNS:GetTopicAttributes",
"SNS:SetTopicAttributes",
"SNS:AddPermission",
"SNS:RemovePermission",
"SNS:DeleteTopic",
"SNS:Subscribe",
"SNS:ListSubscriptionsByTopic",
"SNS:Publish",
"SNS:Receive"
],
"Resource": "*"
}]
}
POLICY
}
resource "aws_sns_topic_policy" "opsgenie_topic_policy" {
arn = aws_sns_topic.opsgenie_notifications.arn
policy = data.aws_iam_policy_document.sns_topic_policy_doc.json
}
resource "aws_sns_topic_subscription" "user_updates_opsgenie_target" {
topic_arn = aws_sns_topic.opsgenie_notifications.arn
protocol = "https"
### IS THIS ENDPOINT CORRECT?? ###
endpoint = "https://api.opsgenie.com/v1/json/amazonsns?apiKey=${opsgenie_api_integration.test_integration.api_key}"
confirmation_timeout_in_minutes = 1
endpoint_auto_confirms = true
}
###############################################################################
# IAM
###############################################################################
data "aws_iam_policy_document" "sns_topic_policy_doc" {
statement {
effect = "Allow"
actions = ["SNS:GetTopicAttributes",
"SNS:SetTopicAttributes",
"SNS:AddPermission",
"SNS:RemovePermission",
"SNS:DeleteTopic",
"SNS:Subscribe",
"SNS:ListSubscriptionsByTopic",
"SNS:Publish",
"SNS:Receive"]
principals {
type = "Service"
identifiers = ["events.amazonaws.com"]
}
resources = ["aws_sns_topic.opsgenie_notifications.arn"]
}
}
###############################################################################
# KMS
###############################################################################
resource "aws_kms_key" "kms_key_for_sns_topic" {
description = "For OpsGenie"
key_usage = "ENCRYPT_DECRYPT"
customer_master_key_spec = "SYMMETRIC_DEFAULT"
enable_key_rotation = true
policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::${data.aws_caller_identity.primary_region.account_id}:root"
},
"Action": "kms:*",
"Resource": "*"
},
{
"Effect": "Allow",
"Principal": {
"Service": "events.amazonaws.com"
},
"Action": [
"kms:Encrypt*",
"kms:Decrypt*",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:Describe*"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Principal": {
"Service": "sns.amazonaws.com"
},
"Action": [
"kms:Encrypt*",
"kms:Decrypt*",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:Describe*"
],
"Resource": "*"
}
]
}
POLICY
}
resource "aws_kms_alias" "topic_key_alias" {
name_prefix = "alias/opsgenie-notifications"
target_key_id = aws_kms_key.kms_key_for_sns_topic.key_id
}
I feel like I'm close, but I either missed something in the documentation or just am misunderstanding something.
It looks like I needed to read further into the documentation. The "API" in the type:
resource "opsgenie_api_integration" "test_integration" {
name = "api-based-int"
type = "API"
... needed to be a specfic type. In my case,
type = "CloudWatchEvents"
was what I needed. For reference, the documentation link is located on this page:
https://docs.opsgenie.com/docs/integration-types-to-use-with-api
Here is my aws_iam_role definition in terraform
resource "aws_iam_role" "server_role" {
name = "server-role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"sts:AssumeEnvironment",
"sqs:ChangeMessageVisibility",
"sqs:ReceiveMessage",
"sqs:SendMessage",
"s3:GetObject*",
"s3:ListBucket*",
"s3:PutBucket*",
"s3:PutObject*"
],
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
but i got this error when I try to run terraform plan:
Error: Error applying plan:
1 error(s) occurred:
aws_iam_role.server_role: 1 error(s) occurred:
aws_iam_role.server_role: Error creating IAM Role server-role: MalformedPolicyDocument: AssumeRole policy may
only specify STS AssumeRole actions. status code: 400, request id:
55f1bfaf-a121-11e9-acaf-bb57d635757b
I basically want to allow the server to read/write S3 buckets and read/write SQS queues.
Apparently I cannot add all these sqs:* and s3:* in the same place. How can I do it in terraform?
you are confused IAM Policy and IAM assume role Policy.
Try like below. It will create IAM Profile for EC2 and you can attach it to your EC2 instances.
resource "aws_iam_role" "server_role" {
name = "server-role"
path = "/"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
}
resource "aws_iam_policy" "server_policy" {
name = "server_policy"
path = "/"
description = "TBD"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"sqs:ChangeMessageVisibility",
"sqs:ReceiveMessage",
"sqs:SendMessage",
"s3:GetObject*",
"s3:ListBucket*",
"s3:PutBucket*",
"s3:PutObject*"
],
"Resource": [
"*"
]
,
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
resource "aws_iam_role_policy_attachment" "server_policy" {
role = "${aws_iam_role.server_role.name}"
policy_arn = "${aws_iam_policy.server_policy.arn}"
}
resource "aws_iam_instance_profile" "server" {
name = "server_profile"
role = "${aws_iam_role.server_role.name}"
}
I am setting up cloud security and I need to:
Select type of trusted entity > Another AWS account
Account ID: xxxxxxxxxx
External ID: xxxxxxxxxx
Attach the SecurityAudit Policy (which is already in AWS)
I'm not sure how to add an already existing policy or where to add the ids. I can't seem to work out a solution from the terraform documentation.
../Core/iam_roles.tf
# BEGIN 'foo'
resource "aws_iam_role" "foo" {
name = "${terraform.workspace}_Foo"
path = "/"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"automation.amazonaws.com",
"events.amazonaws.com"
]
},
"Action": "sts:AssumeRole"
}
]
}
EOF
}
resource "aws_iam_role_policy_attachment" "foo" {
policy_arn = "${aws_iam_policy.security_audit.arn}"
role = "${aws_iam_role.foo.name}"
}
Any help would be much appreciated!
If you're attaching a policy that already exists in the account, I would use a data source to query it. You have to know the ARN to use the IAM policy data source so it's not much different than specifying the ARN directly in the aws_iam_role_policy_attachment resource except it allows the terraform plan command to validate that the policy exists before running apply, it's an extra safeguard for you. The data source also gives you more information about the resource should you need it.
data "aws_iam_policy" "security_audit" {
arn = "arn:aws:iam::${var.target_account_id}:policy/SecurityAudit"
}
# BEGIN 'foo'
resource "aws_iam_role" "foo" {
name = "${terraform.workspace}_Foo"
path = "/"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"automation.amazonaws.com",
"events.amazonaws.com"
]
},
"Action": "sts:AssumeRole"
},
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::${var.other_aws_account_id}:role/your_role_name_and_path_here"
]
},
"Action": "sts:AssumeRole"
}
]
}
EOF
}
resource "aws_iam_role_policy_attachment" "foo" {
policy_arn = "${data.aws_iam_policy.security_audit.arn}"
role = "${aws_iam_role.foo.name}"
}
`# BEGIN 'Foo'
resource "aws_iam_role" "foo" {
name = "${terraform.workspace}_Foo"
path = "/"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::INSERT_ACCOUNT_NUMBER:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "INSERT_EXTERNAL_ID"
}
}
}
]
}
EOF
}
resource "aws_iam_role_policy_attachment" "foo" {
policy_arn = "arn:aws:iam::aws:policy/SecurityAudit"
role = "${aws_iam_role.foo.name}"
}
resource "aws_iam_instance_profile" "foo" {
name = "${terraform.workspace}_Foo"
role = "${aws_iam_role.foo.name}"
}
# END
`