Hello, I'm currently creating a policy for an AWS ...
# general
b
Hello, I'm currently creating a policy for an AWS bucket and assigning it to the bucket with the BucketPolicy resource. In this policy I need an Origin Access Identity
Copy code
oai = OriginAccessIdentity(
            f"OAI-{data_conf['project_name'].upper()}", 
            comment="OAI for allowing CloudFront to access the site S3 bucket")
which is perfectly created
Copy code
oai = Output.all(oai.iam_arn, oai.s3_canonical_user_id).apply(
            lambda args: print(f"OAI ARN: {args[0]} | OAI Canonical User ID: {args[1]}")
        )

>>>  OAI ARN: arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E2HBZRUL9B8YD6 | OAI Canonical User ID: 6816a94df8576437bce079301fa206257850acd55849d905e19e13d4b942310f7646739fe2c756ae7e376c0fce7aaaf5
However, when I try to use these values ​​in the policy document I get a NoneType error:
AttributeError: 'NoneType' object has no attribute 's3_canonical_user_id'
my policy_document:
Copy code
site_bucket_policies_statement = get_policy_document(
            version="2012-10-17",
            statements=[
                {
                    "effect": "Deny",
                    "principals": [
                        {
                            "type": "AWS",
                            "identifiers": ["*"]
                        }
                    ],
                    "actions": ["s3:*"],
                    "resources": [
                        site_bucket[0].arn.apply(lambda arn: arn),
                    ],
                    "conditions": [
                        {
                            "test": "Bool",
                            "variable": "aws:SecureTransport",
                            "values": ["false"]
                        }
                    ]
                },
                {
                    "effect": "Allow",
                    "actions": ["s3:GetObject"],
                    "resources": [
                        site_bucket[0].arn.apply(lambda arn: arn)
                    ],
                    "principals": [{
                        "type": "AWS",
                        "identifiers": [ oai.s3_canonical_user_id.apply(lambda id: id)]
                    }]
                },
                {
                    "effect": "Allow",
                    "actions": [
                        "s3:PutBucketPolicy",
                        "s3:GetBucket*",
                        "s3:List*",
                        "s3:DeleteObject*"
                    ],
                    "resources": [
                        site_bucket[0].arn.apply(lambda arn: arn)
                    ],
                    "principals": [{
                        "type": "AWS",
                        "identifiers": [ lambda_role.arn.apply(lambda arn: arn) ]
                    }]
                }
            ]
        )
and the Bucket Policy creation:
Copy code
site_bucket_policy = BucketPolicy(
                f"BUCKET_POLICY_{data_conf['project_name'].upper()}",
                bucket=site_bucket[0].id,
                policy=site_bucket_policies_statement.json,
                opts=ResourceOptions(depends_on=[site_bucket[0]])
            )
I'd appreciate your help πŸ₯Ί please
d
In your code, you've reassigned
oai
, and the lambda in the apply doesn't return anything
Well, it returns the return of print(...), which is
None
πŸ‘€ 1
b
how use the oai into the get_policy_document to avoid the NoneType error?
d
Instead of
oai = Output.all(...)
, just do
Output.all(...)
βœ… 1
Sorry, I assumed something about the function. I think you need to wrap
get_policy_document
in an `Output.all(...).apply()`call, as it doesn't support Input/Output types
πŸ‘€ 1
b
my fool. my original error was a Malformed policy, then I wrote the line oai = Output.... for see if the values was ok. I returned to my original malformed policy error :v
Copy code
site_bucket_policies_statement = get_policy_document(
            version="2012-10-17",
            statements=[
                {
                    "effect": "Deny",
                    "principals": [
                        {
                            "type": "AWS",
                            "identifiers": ["*"]
                        }
                    ],
                    "actions": ["s3:*"],
                    "resources": [
                        site_bucket[0].arn
                    ],
                    "conditions": [
                        {
                            "test": "Bool",
                            "variable": "aws:SecureTransport",
                            "values": ["false"]
                        }
                    ]
                },
                {
                    "effect": "Allow",
                    "actions": ["s3:GetObject"],
                    "resources": [
                        site_bucket[0].arn
                    ],
                    "principals": [{
                        "type": "AWS",
                        "identifiers": [ oai.iam_arn ]
                    }]
                },
                {
                    "effect": "Allow",
                    "actions": [
                        "s3:PutBucketPolicy",
                        "s3:GetBucket*",
                        "s3:List*",
                        "s3:DeleteObject*"
                    ],
                    "resources": [
                        site_bucket[0].arn
                    ],
                    "principals": [{
                        "type": "AWS",
                        "identifiers": [ lambda_role.arn ]
                    }]
                }
            ]
        )
aws:s3:BucketPolicy (BUCKET_POLICY_ARCHIE-STACK):
error: 1 error occurred:
* putting S3 Bucket (bucket-1-archie-stack-nonprod) Policy: operation error S3: PutBucketPolicy, https response error StatusCode: 400, RequestID: ABG1XJX5FZPTS0Y1, HostID: ODRmhKJaygEo69JqTC0ZSAwSD3wBR3EBwskAjF+xh6tZp9MK+3pdIQzQxA2sp+uyRpTmGUCjza2niQptID1gdw==, api error MalformedPolicy: Action does not apply to any resource(s) in statement
d
what I think you need is something like this:
Copy code
site_bucket_policies_statement = Output.all(
  lambda_role_arn=lambda_role.arn,
  site_bucket_arn=site_bucket[0].arn,
  oai_iam_arn=oai.iam_arn,
).apply(lambda d: get_policy_document(
  version="",
  statements=[
    {
                    "effect": "Deny",
                    "principals": [
                        {
                            "type": "AWS",
                            "identifiers": ["*"]
                        }
                    ],
                    "actions": ["s3:*"],
                    "resources": [
                        d["site_bucket_arn"],
                    ],
                    "conditions": [
                        {
                            "test": "Bool",
                            "variable": "aws:SecureTransport",
                            "values": ["false"]
                        }
                    ]
                },
                {
                    "effect": "Allow",
                    "actions": ["s3:GetObject"],
                    "resources": [
                        d["site_bucket_arn"],
                    ],
                    "principals": [{
                        "type": "AWS",
                        "identifiers": [ d["oai_iam_arn"] ]
                    }]
                },
                {
                    "effect": "Allow",
                    "actions": [
                        "s3:PutBucketPolicy",
                        "s3:GetBucket*",
                        "s3:List*",
                        "s3:DeleteObject*"
                    ],
                    "resources": [
                        site_bucket[0].arn
                    ],
                    "principals": [{
                        "type": "AWS",
                        "identifiers": [ lambda_role.arn ]
                    }]
                }
  ],
))
though I'm unsure. the examples in the docs imply you can directly reference outputs in the statements, so either the examples are incorrect or the type definitions are incorrect
while it's more verbose, you'll get better editor support if you use the Input Classes instead of a list of dictionaries:
aws.iam.GetPolicyDocumentStatementArgs
so:
Copy code
statements=[
  aws.iam.GetPolicyDocumentStatementArgs(
    resources=[...],
  ),
]
πŸ‘€ 1
b
I will try the verbose form, because I still have the malformed policy error. thanks a lot :3
To resolve the malformed policy it was necessary to specify the object arn "/*" in addition to the bucket arn in the resources list. for example:
Copy code
"Resource": [
                 f"{args[0]}",
                 f"{args[0]}/*"
             ],
and use the verbose input classes for better debug messages xd
and the OAI statement only need the object arn