Cloudformation template to attach existing policy to existing IAM role - amazon-web-services

I want to attach an aws managed policy to an existing role. I am achieving this using template:
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "AWS CloudFormation template to modify Role",
"Parameters": {
"MyRole": {
"Type": "String",
"Default": "MyRole",
"Description": "Role to be modified"
}
},
"Resources": {
"S3FullAccess": {
"Type": "AWS::IAM::ManagedPolicy",
"Properties": {
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": [
"s3:*",
"s3-object-lambda:*"
],
"Resource": "*"
}]
},
"Roles": [
"MyRole"
]
}
}
}
}
This template will create a policy with s3FullAccess and attach it to MyRole. But I do not want to create a new policy, if I want to use the policy already present with aws for s3 full access, how can I do that.
And if I use this template:
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "AWS CloudFormation template to modify Role",
"Resources": {
"IAMRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"Path": "/",
"ManagedPolicyArns": [
"arn:aws:iam::aws:policy/ReadOnlyAccess"
],
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"AWS": "*"
}
}]
},
"RoleName": "RoleName"
}
}
}
}
This will attempt to create a new role and attach ReadOnlyPolicy to it. But if I want to attach a policy to existing role, how to refer that role in the template.

You use your AWS::IAM::Role's ManagedPolicyArns property, where you just specify the ARN of the manage policy to attach.
To use existing role in CloudFormation, you have to import it. Then you will be able to manage it from CloudFormation.

In general, CloudFormation service is for creating resources. There is not a native support to do something with already created resources if you don't import them.
If you don't want to import them, then, you have an option to write CloudFormation custom resource. You can create a lambda function-backed custom resource passing in the ARNs of the IAM policy and the IAM role you want to attach the policy to by IAM AttachRolePolicy API. More details are in AWS documentation.

Related

Jobs from specific AWS Batch permissions

How to allow only jobs from a certain AWS Batch queue (and based on a specific job description) to publish to the specific SNS topic?
I though about attaching to jobs IAM policy with the statement:
{
"Effect": "Allow",
"Action": "sns:Publish",
"Resource": ["<arn of the specific SNS topic"]
"Condition": {"ArnEquals": {"aws:SourceArn": "arn:aws:???"}}
}
But what should be the source ARN? ARN of the job queue, ARN of the job definition? Or maybe this should be set up completely differently?
I had a similar experience when worked with AWS Batch jobs executed in Fargate containers which follow the same principles as ECS in scope of assigning roles and permissions.
If you are going to publish messages into specific topic from the code executed inside of your container, then you should create a role with necessary permissions and then use its ARN in the JobRoleArn property of your job definition.
For example (there can be minor mistakes in the code below, but I am just trying to explain the concept here):
Role cloudformation:
"roleresourceID": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"AWS": "*"
}
}
],
"Version": "2012-10-17"
},
"RoleName": "your-job-role"
}
}
Policy attached to the role:
"policyresourceid": {
"Type": "AWS::IAM::Policy",
"Properties": {
"PolicyDocument": {
"Statement": [
{
"Action": "sns:Publish",
"Effect": "Allow",
"Resource": "<arn of the specific SNS topic>"
}
],
"Version": "2012-10-17"
},
"PolicyName": "your-job-role-policy",
"Roles": [
{
"Ref": "roleresourceID"
}
]
}
}
And finally attach role to the Job Definition:
....other job definition properties
"JobRoleArn": {
"Fn::GetAtt": [
"roleresourceID",
"Arn"
]
}
Of course you may structure and format roles and policies in way you like, the main idea of this explanation is that you need to attach proper role using JobRoleArn property of your job definition.

AWS Redshift: Masteruser not authorized to assume role

I created a cloudformation stack with redshift cluster and a masteruser: testuser
"RedshiftCluster" : {
"IamRoles" : [
{
"Fn::GetAtt": [
"IAMInstanceRole",
"Arn"
]
}
]
... other configurations
It uses the below IAM role (IAMInstanceRole) which is in in-sync status and the redshift cluster is up and running:
"IAMInstanceRole": {
"Properties": {
"RoleName": "test-iam-role",
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": [
"sts:AssumeRole"
],
"Effect": "Allow",
"Principal": {
"Service": [
"ec2.amazonaws.com",
"redshift.amazonaws.com",
"s3.amazonaws.com"
]
}
}
]
},
"Path": "/",
"Policies": [
{
"PolicyName": "root",
"PolicyDocument": {
"Version" : "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}
]
}
}
]
}
I'm trying to load csv file from s3 to redshift using copy command and iam_role as credential. The iam_role has the arn of IAMInstanceRole (declared above).
Whenever I execute the below command:
copy test_table from 's3://test-bucket/test.csv' CREDENTIALS 'aws_iam_role=arn:aws:iam::<account-id>:role/test-iam-role' MAXERROR 100000 removequotes TRIMBLANKS emptyasnull blanksasnull delimiter '|';
I get the error:
ERROR: User arn:aws:redshift:us-west-2:189675173661:dbuser:automated-data-sanity-redshiftcluster-fbp9fgls6lri/sanityuser is not authorized to assume IAM Role arn:aws:iam::189675173661:role/sanity-test-iam-instance-role
DETAIL:
-----------------------------------------------
error: User arn:aws:redshift:us-west-2:<account-id>:dbuser:test-redshiftcluster-fbp9fgls6lri/testuser is not authorized to assume IAM Role arn:aws:iam::<account-id>:role/test-iam-role
code: 8001
context: IAM Role=arn:aws:iam::<account-id>:role/test-iam-role
query: 1139
location: xen_aws_credentials_mgr.cpp:236
process: padbmaster [pid=29280]
-----------------------------------------------
Please suggest some resolution.
I ran into the same problem but after a good 1 hour of troubleshooting, I realised I had failed to add the Redshift role to the cluster while I was creating it. If you select the cluster from Redshift, choose the drop-down on 'Actions' and select 'Manage IAM roles' from there you will be able to attach the Redshift role you may have created for this cluster.
That solved the problem for me, anyways.
Hope this helps.
I resolved this issue !!
By default, IAM roles that are available to an Amazon Redshift cluster are available to all users on that cluster. You can choose to restrict IAM roles to specific Amazon Redshift database users on specific clusters or to specific regions.
To permit only specific database users to use an IAM role, take the following steps.
To identify specific database users with access to an IAM role
Identify the Amazon Resource Name (ARN) for the database users in your Amazon Redshift cluster. The ARN for a database user is in the format: arn:aws:redshift:region:account-id:dbuser:cluster-name/user-name.
Open the IAM Console at url="https://console.aws.amazon.com/.
In the navigation pane, choose Roles.
Choose the IAM role that you want to restrict to specific Amazon Redshift database users.
Choose the Trust Relationships tab, and then choose Edit Trust Relationship. A new IAM role that allows Amazon Redshift to access other AWS services on your behalf has a trust relationship as follows:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "redshift.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
Add a condition to the sts:AssumeRole action section of the trust relationship that limits the sts:ExternalId field to values that you specify. Include an ARN for each database user that you want to grant access to the role.
For example, the following trust relationship specifies that only database users user1 and user2 on cluster my-cluster in region us-west-2 have permission to use this IAM role.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "redshift.amazonaws.com"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": [
"arn:aws:redshift:us-west-2:123456789012:dbuser:my-cluster/user1",
"arn:aws:redshift:us-west-2:123456789012:dbuser:my-cluster/user2"
]
}
}
}]
}
7.Choose Update Trust Policy.
Here's a template that works fine:
{
"AWSTemplateFormatVersion": "2010-09-09",
"Resources": {
"RedshiftRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"RoleName": "Redshift-Role",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"redshift.amazonaws.com"
]
},
"Action": [
"sts:AssumeRole"
]
}
]
},
"Path": "/",
"Policies": [
{
"PolicyName": "root",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
}
]
}
}
]
}
},
"RedshiftSG": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupName": "Redshift Security Group",
"GroupDescription": "Enable access to redshift",
"VpcId": "vpc-11223344",
"SecurityGroupIngress": [
{
"IpProtocol": "tcp",
"FromPort": 5439,
"ToPort": 5439,
"CidrIp": "0.0.0.0/0"
}
],
"Tags": [
{
"Key": "Name",
"Value": "Redshift Security Group"
}
]
}
},
"RedshiftCluster": {
"Type": "AWS::Redshift::Cluster",
"Properties": {
"ClusterType": "single-node",
"NodeType": "dc2.large",
"MasterUsername": "master",
"MasterUserPassword": "YourPassword",
"IamRoles": [
{
"Fn::GetAtt": [
"RedshiftRole",
"Arn"
]
}
],
"VpcSecurityGroupIds": [
{
"Ref": "RedshiftSG"
}
],
"PubliclyAccessible": true,
"Port": 5439,
"DBName": "foo"
}
}
}
}
Be sure to insert your own VpcId in the security group.
The Role can be assumed by Redshift and grants access to s3:* (which you should reduce in scope).
I was trying to access Glue data catalog from Redshift. I created the role with the necessary policies attached (AWSGlueServiceRole, AmazonS3FullAccess), and added it to the cluster. However, I had set the AWS service as Glue but it should've been Redshift since Redshift is the service needing the access. Attaching these policies the Redshift role I have (and adding the role to the cluster, if necessary) solved the problem for me.
Resolved it
Complete Steps followed :
Create s3 bucket in the same region as redshift ( move-redshift-data)
create a folder inside it. ( move-redshift-data)
create an IAM role (move-redshift-data-role) ,attach S3Fullaccesss and add the following to trust relationship
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::126111577039:root”
},
"Action": "sts:AssumeRole"
}
]
}
where 126111577039 is the account ID of redshift cluster
Find you already attached role to your cluster
Open your redshift cluster
Click on actions -->Manage IAM roles
You could see the role (mine is RedshiftDynamoDBAccess)
Open the role in IAM console and attach the following inline policy to it .
Add below policy to the role already associated to redshift cluster (See in manage cluster)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"sts:AssumeRole"
],
"Resource": "arn:aws:iam::888850378087:role/move-redshift-data-role"
}
]
}
where 888850378087 : account which has s3 bucket in it and move-redshift-data role
Finally Run command
unload ('select * from sellercompliancestate')
to 's3://unload-swarnimg/unload-swarnimg/'
iam_role 'arn:aws:iam::126111577039:role/RedshiftDynamoDBAccess,arn:aws:iam::888850378087:role/move-redshift-data-role'
allowoverwrite
format as csv;
Got the solution after searching for a while. I created separate IAM role for redshift as John suggested, which is a correct advice but was not the issue in my case.
Then followed the thread to resolve the issue: Copy from remote S3 using IAM Role - not authorized to assume IAM Role
I'd to activate the region where my cluster was in Account Settings
I solved by editing function like this
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"sagemaker.amazonaws.com",
"redshift.amazonaws.com"
]
},
"Action": "sts:AssumeRole"
}
]
}
I add "sagemaker.amazonaws.com" to my function AmazonRedshiftML
Function
I figured it out.
There is no use of deleting a cluster, rebooting or managing IAM Roles in redshift Cluster.
Though I did all above many times, still I was getting the error. Then I tried below steps.
Give Access Key Id and secret Key in COPY command, instead of IAM role. Example as below.
copy users from 's3://awssampledbuswest2/tickit/allusers_pipe.txt'
credentials 'aws_access_key_id=;SKDFHSJKD;aws_secret_access_key=SDJHFJHajhsdjh'
delimiter '|' region 'us-west-2';

Grant permissions between AWS resources with CloudFormation

I would like to have a CloudFormation template create an EC2 instance and give that instance access to a S3 bucket.
One way is to have the template create an IAM user with proper permissions and use its access key to grant access.
But what if I don't want to give that user access to the IAM service?
Is there a way to have that user deploy this template without IAM?
UPDATE:
I want to be able to just share that template, so I am wondering if it is possible to not have a dependency on pre-existing IAM resources (roles, policies, etc)
The common method to grant permissions for an instance is Instance Profiles. You create a role with all the required permissions, assign that role to an instance profile and then assign the profile to any instance you need.
You can do this with CloudFormation:
{
"AWSTemplateFormatVersion": "2010-09-09",
"Resources": {
"myEC2Instance": {
"Type": "AWS::EC2::Instance",
"Version": "2009-05-15",
"Properties": {
"ImageId": "ami-205fba49",
"InstanceType": "t2.micro",
"IamInstanceProfile": {
"Ref": "RootInstanceProfile"
}
}
},
"MyRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version" : "2012-10-17",
"Statement": [ {
"Effect": "Allow",
"Principal": {
"Service": [ "ec2.amazonaws.com" ]
},
"Action": [ "sts:AssumeRole" ]
} ]
},
"Path": "/"
}
},
"RolePolicies": {
"Type": "AWS::IAM::Policy",
"Properties": {
"PolicyName": "s3",
"PolicyDocument": {
"Version" : "2012-10-17",
"Statement": [ {
"Effect": "Allow",
"Action":["s3:PutObject","s3:PutObjectAcl"],
"Resource":["arn:aws:s3:::examplebucket/*"],
} ]
},
"Roles": [ { "Ref": "MyRole" } ]
}
},
"RootInstanceProfile": {
"Type": "AWS::IAM::InstanceProfile",
"Properties": {
"Path": "/",
"Roles": [ { "Ref": "MyRole" } ]
}
}
}
}
If you want to avoid giving the user deploying this template IAM access, you can create the instance profile before deploying the template and specify the already existing instance profile in the template. I haven't tried that yet, but it seems that should only require ec2:AssociateIamInstanceProfile and you should be able to constrain that just to that one specific profile.
Depends on what you mean by IAM service.
You can create IAM User Access Keys that give permissions to specific AWS services and no others. Access Keys do not allow IAM Console Access (this requires login credentials or federation).
For your use case your user will need at a minimum:
Permission to use CloudFormation to execute your template.
Permission to create the EC2 instance.
These permissions are defined in a policy that you add to the IAM user in the AWS Management Console. You can create users that cannot log into the console. Then you generate the Access Keys that the user will use in their application, AWS CLI, etc.
Overview of IAM Policies

AWS Codepipeline with a Codecommit targetsource repository from another account

Is it possible to create a codepipeline that has a target source of a CodeCommit Repository in another account?
I just had to do this, I'll explain the process.
Account C is the account with your CodeCommit repository.
Account P is the account with your CodePipeline... pipelines.
In Account P:
Create an AWS KMS Encryption Key and add Account C with having access (guide here in pre-requisite step). You will also need to add the CodePipeline role, and if you have a CodeBuild and CodeDeploy step add those roles too.
In your CodePipeline artifacts S3 bucket you need to add Account C access. Go to the Bucket Policy and add:
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::ACCOUNTC_ID:root"
},
"Action": [
"s3:Get*",
"s3:Put*"
],
"Resource": "arn:aws:s3:::YOUR_BUCKET_NAME/*"
},
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::ACCOUNTC_ID:root"
},
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::YOUR_BUCKET_NAME"
}
Change ACCOUNTC_ID to the account ID of Account C, and change YOUR_BUCKET_NAME to the CodePipeline artifact S3 bucket name.
Add a policy to your CodePipeline service role so you can get access to Account C and the CodeCommit repositories:
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": [
"arn:aws:iam::ACCOUNTC_ID:role/*"
]
}
}
Again, change ACCOUNTC_ID to the account ID of Account C.
In Account C:
Create an IAM Policy that lets Account P to access the CodeCommit resources and also the KMS key so it can encrypt them with the same key as the rest of your CodePipeline:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject*",
"s3:PutObject",
"s3:PutObjectAcl",
"codecommit:ListBranches",
"codecommit:ListRepositories"
],
"Resource": [
"arn:aws:s3:::YOUR_BUCKET_NAME_IN_ACCOUNTP_FOR_CODE_PIPELINE/*"
]
},
{
"Effect": "Allow",
"Action": [
"kms:DescribeKey",
"kms:GenerateDataKey*",
"kms:Encrypt",
"kms:ReEncrypt*",
"kms:Decrypt"
],
"Resource": [
"arn:aws:kms:YOUR_KMS_ARN"
]
}
]
}
Replace bucket name and KMS ARN in the above policy. Save the policy as something like CrossAccountPipelinePolicy.
Create a role for cross account access and attach the above policy as well as the AWSCodeCommitFullAccess policy. Make sure to make the Trusted entity as the account ID of Account P.
In AWS CLI
You can't do this bit in the console so you have to use the AWS CLI. This will be to get your CodePipeline in AccountP to assume the role in the Source step and dump it in the S3 bucket for all your next steps to use.
aws codepipeline get-pipeline --name NameOfPipeline > pipeline.json
Modify the pipeline json so it looks a bit like this and replace the bits that you need to:
"pipeline": {
"name": "YOUR_PIPELINE_NAME",
"roleArn": "arn:aws:iam::AccountP_ID:role/ROLE_NAME_FOR_CODE_PIPELINE",
"artifactStore": {
"type": "S3",
"location": "YOUR_BUCKET_NAME",
"encryptionKey": {
"id": "arn:aws:kms:YOUR_KMS_KEY_ARN",
"type": "KMS"
}
},
"stages": [
{
"name": "Source",
"actions": [
{
"name": "Source",
"actionTypeId": {
"category": "Source",
"owner": "AWS",
"provider": "CodeCommit",
"version": "1"
},
"runOrder": 1,
"roleArn": "arn:aws:iam::AccountC_ID:role/ROLE_NAME_WITH_CROSS_ACCOUNT_POLICY",
"configuration": {
"BranchName": "master",
"PollForSourceChanges": "false",
"RepositoryName": "YOURREPOSITORYNAME"
},
"outputArtifacts": [
{
"name": "MyApp"
}
],
"inputArtifacts": []
}
]
},
Update the pipeline with aws codepipeline update-pipeline --cli-input-json file://pipeline.json
Verify it works by running the pipeline.
You can deploy resources using pipeline with codecommit repository in another account.
Let's say you have Account A where your codecommit repository sits, and Account B where you codepipeline sits.
Configure the following in account B:
You would need to create custom KMS key because AWS Default Key does not have an associated Key policy. You can use Create a Pipeline in CodePipeline That Uses Resources from Another AWS Account if you need assistance with creating CMK. Add the Codepipeline service role to the KMS Key Policy to allow the codepipeline to use it.
Event bus for receiving events from cross account Go to CloudWatch → Event Buses under Events section → Add Permission → Enter DEV AWS Account Id → Add. For more details, check Creating an Event Bus
Add the following Policy to S3 pipeline Artifact store:
{
“Version”: “2012–10–17”,
“Id”: “PolicyForKMSAccess”,
“Statement”: [
{ “Sid”: “AllowAccessFromAAccount”,
“Effect”: “Allow”,
“Principal”: { “AWS”: “arn:aws:iam::ACCOUNT_A_ID:root” },
“Action”: [ “s3:Get*”, “s3:Put*”, "s3:ListBucket ],
“Resource”: “arn:aws:s3:::NAME-OF-THE-BUCKET/*” }
]
}
Edit the Pipeline IAM rols to assume role to Account A as follows:
{
“Version”:“2012–10–17”,
“Statement”:{
“Effect”:“Allow”,
“Action”:“sts:AssumeRole”,
“Resource”:[
“arn:aws:iam::ACCOUNT_A_ID:role/*
]
}
}
Create a CloudWatch Event Rule to trigger the pipeline on master branch of the CodeCommit in account A. Add CodePipeline's ARN as a target of this rule.
Now, do the following in Account A:
Create a cross account IAM role with 3 policies.
a) AWSCodeCommitFullAccess
b) Inline Policy to assume role to Account B as follows:
{
“Version”:“2012–10–17”,
“Statement”:[
{
“Effect”:“Allow”,
“Principal”:{
“AWS”:“arn:aws:iam::ACCOUNT_B_ID:root”
},
“Action”:“sts:AssumeRole”
}
]
}
c)Inline policy for KMS, CodeCommit and S3 access:
{
“Version”:“2012–10–17”,
“Statement”:[
{
“Effect”:“Allow”,
“Action”:[
“s3:Get*”,
“s3:Put*”,
“codecommit:*”
],
“Resource”:[
“arn:aws:s3:::YOUR_BUCKET_NAME_IN_B_FOR_CODE_PIPELINE_ARTIFACTS/”
]
},
{
“Effect”:“Allow”,
“Action”:[
“kms:*" ],
“Resource”: [ “arn:aws:kms:YOUR_KMS_ARN_FROM_B_ACCOUNT” ] } ] }
2. Update your pipeline as #Eran Medan suggested.
For more details, please visit AWS CodePipeline with a Cross-Account CodeCommit Repository
Also, please note that I have given a lot more permissions than required for example codecommit:* and kms:*, you can alter them as per your needs.
I hope this will help.
Yes, it should be possible. Follow these instructions: http://docs.aws.amazon.com/codepipeline/latest/userguide/pipelines-create-cross-account.html

AWS Policy Limited Administrator

I want to create a policy that allows an IAM user or role to create a set of resources (for example EC2 instances) and then manage (delete, update, etc) ONLY those resources. I hope I can accomplish this using IAM variables, wildcards, and/or conditions, but I'm not sure how.
My policy would look something like this ideally
{
"Effect": "Allow",
"Action": [
"ec2:*"
],
"Condition": [
{ "Created_By_The_Instance_Profile_In_The_CFN_Stack_That_Created_The_EC2Instance}" }
]
}
Further, what if I want to grant the EC2 instance profile to do ssm:CreateAssociation for an SSM document that was created in the same stack as the EC2 instance itself? In other words, I have a stack with an EC2 instance, and IAM Instance Profile, an IAM Role, and an SSM document and I want the EC2 instance to CreateAssociation on startup, via UserData. The user that launches the stack should have access to create these resources, but NOT to create new policies (effectively making them an administrator). I want to create a Role + Policy ahead of time and grant the stack creator the ability to attach this Role to the IAM Instance Profile Role it creates.
So, ahead of time, I (the admin), create a policy and role as such
"DeployerRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"ec2.amazonaws.com",
"lambda.amazonaws.com"
],
"AWS": "*"
},
"Action": [
"sts:AssumeRole"
]
}
]
}
}
},
"PolicyManagerPolicy": {
"Type": "AWS::IAM::ManagedPolicy",
"Properties": {
"Description": "Allows CFN deployer to attach and detach required policies.",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iam:AttachRolePolicy",
"iam:DetachRolePolicy"
],
"Resource": "*",
"Condition": {
"ArnEquals": {
"iam:PolicyArn": [
"The_Policy_Arn_I_Want_To_Create"
]
}
}
},
{
"Effect": "Allow",
"Action": [
"iam:CreateRole"
],
"Resource": "*"
}
]
},
"Roles": [ { "Ref": "DeployerRole" } ]
}
}
The "limited administrator" deployer (an IAM user in the DeployerRole) should be able to launch a stack containing an:
EC2 Instance
IAM Instance Profile
IAM Role
SSM Document
I need The_Policy_Arn_I_Want_To_Create to:
Allow ONLY the EC2 Instance created by the stack to be able to CreateAssociation ONLY with the SSM Document created by the stack. Using tags is fine, but since the Resource for the SSM document would not be able to use tags, how can I do this?
ec2 does not know about the account who created the instance (you might have that if you enable CloudTrail), a possibility will be to tag the ec2 instance when you create it with the user account and then read that from your policy as
"Condition": {"StringEquals": {"ec2:ResourceTag/<tag where the username will be>": "${aws:username}"