Hi all, I am trying to get a policy document so my...
# aws
c
Hi all, I am trying to get a policy document so my EKS cluster can pull images from ECR. But I get the following error: error: awsiam/policyPolicy resource 'ecrPolicy' has a problem: "policy" contains an invalid JSON policy: leading space characters are not allowed. Examine values at 'ecrPolicy.policy'. I am trying three approaches and all of them fail: ecr_repo_arn = "arnawsecrus east 1***********:repository/app_dev" Approach 1: policy_document = pulumi.Output.all(ecr_repo_arn, ecr_repo_arn).apply(lambda _args_: json.dumps({ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action": [ "ecr:GetDownloadUrlForLayer", "ecr:BatchGetImage", "ecr:BatchCheckLayerAvailability", ], "Resource": _args_[0] }] })) ecr_policy = aws.iam.Policy("ecrPolicy", description="ECR read-only access policy for EKS worker nodes", policy=ecr_policy_document Approach 2: ecr_policy_document = aws.iam.get_policy_document(statements=[ { "actions": [ "ecr:GetDownloadUrlForLayer", "ecr:BatchGetImage", "ecr:BatchCheckLayerAvailability", # Add additional ECR actions as needed ], "resources": [ # Replace with the ARN of your ECR repository ecr_repo_arn, ], }, ]) Approach 3: ecr_policy_document = aws.iam.get_policy_document(statements=[ aws.iam.GetPolicyDocumentStatementArgs( actions=[ "ecr:GetDownloadUrlForLayer", "ecr:BatchGetImage", "ecr:BatchCheckLayerAvailability", ], resources=[ecr_repo_arn], ) ]) # For approach 2 & 3 ecr_policy = aws.iam.Policy("ecrPolicy", description="ECR read-only access policy for EKS worker nodes", policy=ecr_policy_document.json() Not able to go past this step unfortunately.
l
There's a few problems in there, but they're hard to see in Slack because of the formatting. Are you aware of the Text Snippet tool, and the code/monospace format? Using either or both of those may help highlight the problems.
I'm not a Python user, but the use of
pulumi.Output.all()
and then just using a single arg from that array seems redundant, and may lead to an error. Since you want only the first element in the all array, you can skip creating the array, and just use
ecr_repo_arn.apply( .... )
. Also, the 2nd element in the array was the same item, was that right?
I recommend outputting the policy document after you've created it but before you use it. It should show you the error (which is probably that the document is an error string, which cannot be formatted to JSON).
c
I am more surprised why the second and third approaches are failing as the policy statement is created programmatically instead of from string, so should be less prone to format errors. The main problem is though the IaC with pulumi uses Python, the debugging is not pythonic at all. I can't put a print statement and check what is going on. Probably I will get a hang of things as I learn more, but the docs are not helping at all.
import pulumi_aws as aws
ecr_repo_arn = "arn:aws:ecr:us-east-1:*****:repository/app_dev"
# Asynchronously get the policy document
def get_policy_document(args):
ecr_policy_document = aws.iam.get_policy_document(statements=[
aws.iam.GetPolicyDocumentStatementArgs(
actions=[
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage",
"ecr:BatchCheckLayerAvailability",
],
resources=args,
)
])
return ecr_policy_document.json
`# Use
apply
to handle the asynchronous result`
policy_json = pulumi.Output.all(ecr_repo_arn).apply(get_policy_document)
# Export the policy
pulumi.export("policy", policy_json)
When I do pulumi up, I get the following, not sure if this is right or wrong:
l
You can print and debug from your code. It may be slightly different than the normal ways of doing things because the entrypoint is different, but it will work. Maybe someone over in #python can help with that aspect.
Creating the JSON policy document does not prevent it from being badly formatted, if you're putting unformattable objects into it.
For example, you put
ecr_repo_arn
directly into the object in both approaches 2 and 3. When get_policy_document calls to_string (or the Python equivalent) on
ecr_repo_arm
, it will produce an error message that is not an ARN, and will be unformattable. Which is probably causing your problem.
You cannot turn an Output into a string inline. You must do it in a future.
It is a very common problem when working with Pulumi, and once you've solved it a few times, you'll spot it so quickly that you'll avoid it without even thinking. I don't know the solution for Python, but I'll have a go at finding it in the examples GitHub repository.
It looks like the solution is very simple in Python: change
json_dumps
to `Output.json_dumps`: https://github.com/pulumi/examples/blob/7a0dbf40e0924297e94426ea534d748ad1589b45/aws-py-s3-folder/__main__.py#L28
c
Thanks @little-cartoon-10569
l
Does it work?
c
The second approach works as I was doing a mistake with json conversion. Instead of json, I was using json(). But overall attaching roles to EKS cluster is not working for me for some reason. For now I just create a simple EKS cluster and then manually give permissions as I could not get it to work in Pulumi. It fails with this error: pulumipulumiStack (pulumi_eks_cluster-dev): error: Error: an instanceProfile is required There is one example in the github repo where they are using a Cluster class from pulumi_aws for creating the cluster while I was using a Cluster class from pulumi_eks. The whole interface is entirely different and I am not in position to delve into the complexities because I feel I might get stuck with some other error anyway if I pursue that direction. For me apart from the only examples in the docs, nothing worked out of box. If I try to add anything extra to the examples from the docs, the whole thing falls apart.
l
The AWS EKS Cluster is available from the EKS cluster. Use the
eksCluster
property.
c
I am using the Cluster class from pulumi_eks. Somewhere in stackoverflow, I read it is to create EKS cluster easily.
l
Yes. And that object has a property
eksCluster
, which points to the
aws.eks.Cluster
object that the EKS provider creates and wraps for you.
Ah sorry, in Python it's called
eks_cluster
.
c
Yes, that is the one I am using 🙂 I want that to be able to pull image from my ECR repo. I just could not get it to work. This is my code for creating the role and then I pass that info to the arguments of Cluster class like this: _instance_roles_=[eks_worker_role], _instance_profile_name_=eks_worker_instance_profile.name Suppose to work, but I get the error "an instanceProfile is required".