0
votes

I am trying to create a cfn stack. Template takes one/two values as input from parameter section.if i am passing two values from parameter same reading in resource section its working fine. but if i pass one it is breaking.

Use Case :- I want to pass two values from parameters and read them in iam policy. if user passed one value it should use {"Ref" : "AWS::NoValue"}. but i am keep on getting

Template error: Fn::Select cannot select nonexistent value at index 1

here is the template -

{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "Template creates a IAMUser and attach a ListALLBuckets/ReadOnly Access Policy to it.",
    "Parameters": {
        "UserName": {
            "Type": "String",
            "Description": "Enter User Name"
        },
        "S3Bucket": {
            "Type": "CommaDelimitedList",
            "Description": "Select Bucket Name to Associate with the policy",
            "Default": ""
        }
    },
    "Conditions": {
        "CreateSomeResource": {
            "Fn::Not": [{
                "Fn::Equals": [{
                        "Fn::Join": [
                            "",
                            {
                                "Ref": "S3Bucket"
                            }
                        ]
                    },
                    ""
                ]
            }]
        }
    },
    "Resources": {
        "SomeUserName": {
            "Type": "AWS::IAM::User",
            "Properties": {
                "UserName":  {  "Ref": "UserName"}
            }
        },
        "SomeUserPolicy": {
            "Type": "AWS::IAM::Policy",
            "Properties": {
                "Groups": [],
                "PolicyDocument": {
                    "Version": "2012-10-17",
                    "Statement": [{
                            "Sid": "ListAllBuckets",
                            "Effect": "Allow",
                            "Action": [
                                "s3:ListAllMyBuckets"
                            ],
                            "Resource": "*"
                        }, {
                            "Sid": "ReadOnlyAccess",
                            "Effect": "Allow",
                            "Action": [
                                "s3:GetBucketPolicyStatus",
                                "s3:GetBucketTagging",
                                "s3:GetBucketLocation",
                                "s3:GetBucketPolicy",
                                "s3:GetObject"
                            ],
                            "Resource": [

                                {
                                    "Fn::If": [
                                        "CreateSomeResource",
                                        {
                                            "Fn::Join": ["", ["arn:aws:s3:::",
                                                {
                                                    "Fn::Select": ["0",
                                                        {
                                                            "Ref": "S3Bucket"
                                                        }
                                                    ]
                                                }
                                            ]]
                                        },
                                        {"Ref" : "AWS::NoValue"}
                                    ]
                                },

                                {
                                    "Fn::If": [
                                        "CreateSomeResource",
                                        {
                                            "Fn::Join": ["", ["arn:aws:s3:::",
                                                {
                                                    "Fn::Select": ["1",
                                                        {
                                                            "Ref": "S3Bucket"
                                                        }
                                                    ]
                                                }
                                            ]]
                                        },
                                        {"Ref" : "AWS::NoValue"}
                                    ]
                                }
                            ]
                        }

                    ]
                },
                "PolicyName": "ReadOnly",

                "Users": [{
                    "Ref": "SomeUserName"
                }]
            }
        }
    },
    "Outputs": {
        "UserName": {
            "Description": "Name of the Created User",
            "Value": {
                "Ref": "UserName"
            }
        }
    }
}
1

1 Answers

0
votes

If S3Bucket has only one value, then this:

"Fn::Select": ["1",
    {
        "Ref": "S3Bucket"
    }

is obviously invalid. Sadly, it does not matter that you have CreateSomeResource condition there. The select must be valid whether the condition is true or false.

Probably the easiet solution would be to pass the buckets as two separate parameters, S3Bucket1 and S3Bucket2 and have respective conditions for each of them.