I have the Terraform code (below) that is suppose to create an IAM policy. However, on terraform apply, I get the error:
Error: creating IAM Policy autoscale-policy: MalformedPolicyDocument: The policy failed legacy parsing
Terraform code:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.52.0"
}
}
}
provider "aws" {
region = "us-west-2"
}
resource "aws_iam_policy" "autoscale_policy" {
name = "autoscale-policy"
description = "EBS Autoscaling Policy"
policy = <<EOT
{
"Version": "2012-10-17",
"Statement": {
"Action": [
"ec2:AttachVolume",
"ec2:DescribeVolumeStatus",
"ec2:DescribeVolumes",
"ec2:ModifyInstanceAttribute",
"ec2:DescribeVolumeAttribute",
"ec2:CreateVolume",
"ec2:DeleteVolume",
"ec2:CreateTags",
"kms:Decrypt",
"kms:CreateGrant",
"kms:Encrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
"Resource": "*",
"Effect": "Allow"
}
}
EOT
}
However, when I use the AWS cli with the exact same policy, the policy is created in AWS with no issue:
--policy-name TestPolicy \
--policy-document \
'{
"Version": "2012-10-17",
"Statement": {
"Action": [
"ec2:AttachVolume",
"ec2:DescribeVolumeStatus",
"ec2:DescribeVolumes",
"ec2:ModifyInstanceAttribute",
"ec2:DescribeVolumeAttribute",
"ec2:CreateVolume",
"ec2:DeleteVolume",
"ec2:CreateTags",
"kms:Decrypt",
"kms:CreateGrant",
"kms:Encrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
"Resource": "*",
"Effect": "Allow"
}
}'
Does anyone see where there might be a difference between the TF code and the CLI command? How come my TF code returns a MalformedPolicyDocument error when the policy works fine from the cli?
Statement should be an array.
resource "aws_iam_policy" "autoscale_policy" {
name = "autoscale-policy"
description = "EBS Autoscaling Policy"
policy = <<EOT
{
"Version": "2012-10-17",
"Statement": [{
"Action": [
"ec2:AttachVolume",
"ec2:DescribeVolumeStatus",
"ec2:DescribeVolumes",
"ec2:ModifyInstanceAttribute",
"ec2:DescribeVolumeAttribute",
"ec2:CreateVolume",
"ec2:DeleteVolume",
"ec2:CreateTags",
"kms:Decrypt",
"kms:CreateGrant",
"kms:Encrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
"Resource": "*",
"Effect": "Allow"
}]
}
EOT
}
tested it works
OR you can you data resource to define your policies.
resource "aws_iam_policy" "autoscale_policy" {
name = "autoscale-policy"
description = "EBS Autoscaling Policy"
policy = data.aws_iam_policy_document.example.json
}
data "aws_iam_policy_document" "example" {
statement {
actions = [
"ec2:AttachVolume",
"ec2:DescribeVolumeStatus",
"ec2:DescribeVolumes",
"ec2:ModifyInstanceAttribute",
"ec2:DescribeVolumeAttribute",
"ec2:CreateVolume",
"ec2:DeleteVolume",
"ec2:CreateTags",
"kms:Decrypt",
"kms:CreateGrant",
"kms:Encrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
]
resources = ["*"]
effect = "Allow"
}
}
Related
I am trying to create a CMK for my SQS queue to allow encrypted SNS messages to be sent to my encrypted queue. After I create the cmk, I will set it to the "kms_master_key_id" in my queue.
resource "aws_kms_key" "mycmk" {
description = "KMS Key"
deletion_window_in_days = 10
policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"Service": "sns.amazonaws.com"
},
"Action": [
"kms:GenerateDataKey",
"kms:Decrypt"
],
"Resource": "*"
}]
}
POLICY
}
This is throwing an error:
my_role_arn is not authorized to perform: kms:CreateKey on resource: *
I've double checked to make sure that action is allowed and it is.
Do I need to update the 'resource' in the policy? If so to what?
The role I am using to run this has these permissions:
Effect = "Allow"
Action = [
"kms:CreateAlias",
"kms:CreateGrant",
"kms:CreateKey",
"kms:DeleteAlias",
"kms:DisableKey",
"kms:EnableKey",
"kms:PutKeyPolicy",
"kms:RevokeGrant",
"kms:ScheduleKeyDeletion",
"kms:TagResource",
"kms:UntagResource",
"kms:UpdateAlias",
"kms:UpdateKeyDescription"
]
Resource = [
"arn:aws:kms:${local.aws_region}:${var.aws_account_id}:key/*",
"arn:aws:kms:${local.aws_region}:${var.aws_account_id}:alias/*"
]
As someone else suggested, it looks like the credentials you use to run Terraform don't have the right permissions.
CreateKey explicitly only works with the "*" resource, so change the policy to this:
data "aws_iam_policy_document" "key_Access" {
statement {
actions = [
"kms:CreateAlias",
"kms:CreateGrant",
"kms:DeleteAlias",
"kms:DisableKey",
"kms:EnableKey",
"kms:PutKeyPolicy",
"kms:RevokeGrant",
"kms:ScheduleKeyDeletion",
"kms:TagResource",
"kms:UntagResource",
"kms:UpdateAlias",
"kms:UpdateKeyDescription"
]
resources = [
"arn:aws:kms:${local.aws_region}:${var.aws_account_id}:key/*",
"arn:aws:kms:${local.aws_region}:${var.aws_account_id}:alias/*"
]
}
statement {
actions = ["kms:CreateKey"]
resources = ["*"]
}
}
With that being said, maybe don't make your own policy. Just assign the existing policy arn:aws:iam::aws:policy/AWSKeyManagementServicePowerUser to the role. That gives the following permissions:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"kms:CreateAlias",
"kms:CreateKey",
"kms:DeleteAlias",
"kms:Describe*",
"kms:GenerateRandom",
"kms:Get*",
"kms:List*",
"kms:TagResource",
"kms:UntagResource",
"iam:ListGroups",
"iam:ListRoles",
"iam:ListUsers"
],
"Resource": "*"
}
]
}
I am trying to create an IAM role/policy to enable my EC2 instance to be able to list and attach EBS volumes (via scripts that call the aws cli). I want this policy to allow only listing/attaching of EBS volumes that have a specific tag.
I've noticed that the script is able to list/attach volumes when I set Resources: "*" and no Conditions in my policy below.
But as soon as I introduce the policy I have below, the AWS cli throws the following error:
./aws ec2 describe-volumes
An error occurred (UnauthorizedOperation) when calling the DescribeVolumes operation: You are not authorized to perform this operation.
Here is the IAM policy I have so far defined in terraform:
resource "aws_iam_role" "web_role" {
name = "web_role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
resource "aws_iam_instance_profile" "web_profile" {
name = "web_profile"
role = aws_iam_role.web_role.name
}
resource "aws_iam_role_policy" "web_disk_policy" {
name = "web_disk_policy"
role = aws_iam_role.web_role.id
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:AttachVolume",
"ec2:DetachVolume",
"ec2:DescribeVolumes"
],
"Resource": [
"arn:aws:ec2:*:*:instance/*",
"arn:aws:ec2:*:*:volume/*"
],
"Condition": {
"StringEquals": {
"ec2:ResourceTag/app": "web"
}
}
}
]
}
EOF
}
And my EC2 instances is created with the following:
resource "aws_instance" "web_vm" {
...
iam_instance_profile = aws_iam_instance_profile.web_profile.name
...
tags = {
app = "web"
}
}
And disk created with:
resource "aws_ebs_volume" "ebs-volume-1" {
availability_zone = "us-west-2a"
size = 10
tags = {
app = "web"
}
}
DescribeVolumes does not support aws:ResourceTag/${TagKey} condition, nor any other.
Most Describe/List type operations that target many resources aren't compatible with the conditional logic. DescribeVolumes does not work with conditions so split that off into a different statement.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:AttachVolume",
"ec2:DetachVolume"
],
"Resource": [
"arn:aws:ec2:*:*:instance/*",
"arn:aws:ec2:*:*:volume/*"
],
"Condition": {
"StringEquals": {
"ec2:ResourceTag/app": "web"
}
}
},
{
"Effect": "Allow",
"Action": "ec2:DescribeVolumes",
"Resource": "*"
}
]
}
I using terraform to deploy containers with fargate.
I got an error:
error: Error creating IAM Role ecs_task_execution_role: MalformedPolicyDocument: Has prohibited field Resource
status code: 400, request id: 351d657b-32ef-4ffa-a1e8-bee912e5c788
on ecs.tf line 74, in resource "aws_iam_role" "ecs_execution_role":
74: resource "aws_iam_role" "ecs_execution_role" {
My terraform settings:
resource "aws_ecs_task_definition" "nginx" {
family = "nginx-${var.app}"
network_mode = "awsvpc"
requires_compatibilities = ["FARGATE"]
cpu = "256"
memory = "512"
execution_role_arn = "${aws_iam_role.ecs_execution_role.arn}"
task_role_arn = "${aws_iam_role.ecs_execution_role.arn}"
container_definitions = <<DEFINITION
[
...
}
resource "aws_iam_role" "ecs_execution_role" {
name = "ecs_task_execution_role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "ecs-tasks.amazonaws.com"
},
"Action": [
"sts:AssumeRole",
"ecs:CreateCluster",
"ecs:DeregisterContainerInstance",
"ecs:DiscoverPollEndpoint",
"ecs:Poll",
"ecs:RegisterContainerInstance",
"ecs:StartTelemetrySession",
"ecs:Submit*",
"ecs:StartTask",
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "*"
}
]
}
EOF
}
What policy do I need? what is wrong with current policy?
When I change the action property in the policy to "Action": "sts:AssumeRole" I get this error in the task log:
Status reason CannotPullECRContainerError: AccessDeniedException: User: arn:aws:sts::993934193145:assumed-role/ecs_task_execution_role/0d2f817c-d7b5-4221-afb8-56baaee68b0e is not authorized to perform: ecr:GetAuthorizationToken on resource: * status code: 400, request
assume_role_policy in aws_iam_role is only for trust relationship, i.e. which IAM entity can assume the role.
The actually permissions you want to added to the role, could be placed in aws_iam_policy and attached to the role using aws_iam_role_policy_attachment.
For example, your code could be refactored into the following:
resource "aws_iam_role" "ecs_execution_role" {
name = "ecs_task_execution_role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "ecs-tasks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
}
resource "aws_iam_policy" "ecs_permissions" {
name = "my_ecs_permissions"
description = "Permissions to enable CT"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Action": [
"ecs:CreateCluster",
"ecs:DeregisterContainerInstance",
"ecs:DiscoverPollEndpoint",
"ecs:Poll",
"ecs:RegisterContainerInstance",
"ecs:StartTelemetrySession",
"ecs:Submit*",
"ecs:StartTask",
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "*"
}
]
}
EOF
}
resource "aws_iam_role_policy_attachment" "ecs_attachment" {
role = aws_iam_role.ecs_execution_role.name
policy_arn = aws_iam_policy.ecs_permissions.arn
}
This is actually down to the assume_role_policy containing both the trust policy and the permissions
Instead you should move all not trust policy permissions into a standard policy
This assume_role_policy is very similar but slightly different than just a standard IAM policy and cannot use an aws_iam_policy resource. It can however, use an aws_iam_policy_document data source, see example below for how this could work.
I've been trying to make a IAM policy that restricts creation of an Instance if certain tags are not applied at the time of Instance Creation. The policy is as follows:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowToDescribeAll",
"Effect": "Allow",
"Action": [
"ec2:Describe*",
"ec2:CreateTags",
"ec2:DeleteTags"
],
"Resource": "*"
},
{
"Sid": "AllowRunInstances",
"Effect": "Allow",
"Action": "ec2:RunInstances",
"Resource": [
"arn:aws:ec2:*::image/*",
"arn:aws:ec2:*::snapshot/*",
"arn:aws:ec2:*:*:subnet/*",
"arn:aws:ec2:*:*:network-interface/*",
"arn:aws:ec2:*:*:security-group/*",
"arn:aws:ec2:*:*:key-pair/*"
]
},
{
"Sid": "AllowLaunchOnlyWithRequiredTags1",
"Effect": "Deny",
"Action": [
"ec2:RunInstances"
],
"Resource": [
"arn:aws:ec2:*:012345678901:instance/*"
],
"Condition": {
"StringNotLike": {
"aws:RequestTag/Purpose": "?*",
"aws:RequestTag/CostCategory": "?*",
"aws:RequestTag/Env": "?*",
"aws:RequestTag/CreatedBy": "?*",
"aws:RequestTag/Owner": "?*",
"aws:RequestTag/CreationDate": "?*",
"aws:RequestTag/Expiry": "?*",
"aws:RequestTag/Name": "?*",
"aws:RequestTag/Project": "?*"
}
}
}
]}
This policy works well if I select "Amazon Linux 2 AMI (HVM), SSD Volume Type" this type of AMI but gives permission denied error if I select "CentOS 7 (x86_64) - with Updates HVM" this type of AMI. Can someone explain why this is so? Thanks!
Objective : IAM user should be allowed to create a DynamoDB table in N.Virginia region only.
My IAM Policy attached to the IAM User:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "CreateMyTable",
"Effect": "Allow",
"Action": [
"dynamodb:CreateTable",
"dynamodb:ListTables",
"dynamodb:DescribeTable",
"dynamodb:Query",
"dynamodb:Scan",
"dynamodb:GetItem",
"dynamodb:BatchGetItem",
"dynamodb:PutItem",
"cloudwatch:*",
"sns:CreateTopic"
],
"Resource": "*"
},
{
"Sid": "DenyOtherRegions",
"Effect": "Deny",
"Action": "dynamodb:*",
"Resource": "*",
"Condition": {
"ForAllValues:StringNotEqualsIfExists": {
"aws:RequestedRegion": "us-east-1"
}
}
}
]
}
I am getting following error:
Not Authorised
Am i missing out on any policy here? Please suggest.