How to use jinja if-else logic together with Ansible inventory - templates

I would like to use jinja logic in my template:
---
AWSTemplateFormatVersion: 2010-09-09
Description: '{{ git_repository.after | truncate(8, end='') }} # infra-lambda.git : roles/{{ lambda_name }}'
Resources:
{% if lambda_account == 'true' %}
RoleToAssume:
Type: AWS::IAM::Role
Properties:
RoleName: "infra-lambda-{{ lambda_name }}-LambdaRole-{{ shortname }}-{{ dtap }}"
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
Service:
- "lambda.amazonaws.com"
Action:
- "sts:AssumeRole"
Path: "/"
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole
Policies:
- PolicyName: RoleToAssumeLambdaPolicy
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource: arn:aws:logs:*:*:*
- Effect: Allow
Action:
- "cloudwatch:Get*"
- "cloudwatch:List*"
- "cloudwatch:Put*"
Resource:
- "*"
- Effect: Allow
Action:
- "sts:AssumeRole"
Resource:
- "*"
{% else %}
RoleToBeAssumed:
Type: AWS::IAM::Role
Properties:
RoleName: RoleToBeAssumed
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Sid: DefaultStatement
Effect: "Allow"
Principal:
AWS:
- "arn:aws:iam::{AWS_ACCOUNT}:role/lambda_assume"
Action:
- "sts:AssumeRole"
Path: "/"
Policies:
- PolicyName: "DeleteCertificates"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- acm:DeleteCertificate
- acm:GetCertificate
Action:
- acm:ListCertificates
Resource: '*'
{% endif %}
I've already tried true without '' and instead of true is defined but still no success. The logic is pretty simple. In the inventory I have:
unused_certs:
enabled: true
lambda_account: true
If I have the above in the inventory only RoleToAssume and LambdaFunction resources should be created. If I don’t have lambda_account set to true, only the resources after the else statement should be created. Any idea why only the resources after the else statement are being created by CloudFormation? I cannot use "when" in Ansible playbook because my repo is not constructed that way unfortunately.

The "pythonic" way to write the sentence is just:
{% if lambda_account %}
But you can still use true with lowercase, as stated in the jinja2 docs.
{% if lambda_account == true %}

Related

Getting InsufficientPrivilegesException when deploying CloudFormation stack to create an ElasticBeanstalk app

I've written a CloudFormation template that creates an ElasticBeanstalk application. However, when I execute the template, I receive the following error: Access Denied (Service: AWSElasticBeanstalk; Status Code: 403; Error Code: InsufficientPrivilegesException; Request ID: 6c580af3-250d-4658-bc2f-8f6af4c1dd6d; Proxy: null).
What permission do I need to add?
The relevant portion of my CloudFormation script:
# The role used by CloudFormation to create the stack
CFNRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: ["sts:AssumeRole"]
Effect: Allow
Principal:
Service: [cloudformation.amazonaws.com]
Version: "2012-10-17"
Path: /
Policies:
- PolicyName: CloudFormationRole
PolicyDocument:
Version: "2012-10-17"
Statement:
- Action:
- "ec2:*"
- "elasticbeanstalk:*"
- "iam:*"
- "lambda:*"
- "logs:*"
Effect: Allow
Resource: "*"
# more stuff here...
# Create the EB app without an Environment for now
EBApp1:
Type: AWS::ElasticBeanstalk::Application
Properties:
Description: my-api
It turns out I was missing the S3 permissions on the CFNRole. I modified the permissions to the following, and the stack could be deployed.
CFNRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Action: ["sts:AssumeRole"]
Effect: Allow
Principal:
Service: [cloudformation.amazonaws.com]
Version: "2012-10-17"
Path: /
Policies:
- PolicyName: CloudFormationRole
PolicyDocument:
Version: "2012-10-17"
Statement:
- Action:
- "ec2:*"
- "elasticbeanstalk:*"
- "iam:*"
- "lambda:*"
- "logs:*"
- "s3:*" #### Added this line ####
Effect: Allow
Resource: "*"

Error creating IAM Role - Value of property PolicyDocument must be an object

I am creating an IAM role in order to send logs from a stack to kinesis stream in another stack.
When I add permission policy, it fails with the error :
"Value of property PolicyDocument must be an object".
This is my cloudformation.template.yml :
KinesisRole:
Type: AWS::IAM::Role
Properties:
RoleName: {'Fn::Sub': 'Kinesis-Role-${AWS::Region}'}
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: [logs.amazonaws.com]
Action: ['sts:AssumeRole']
Policies:
- PolicyName: KinesisPolicy
PolicyDocument:
- Version: '2017-10-17'
Statement:
- Action: ['kinesis:PutRecord']
Effect: Allow
Resource: '*'
Your current PolicyDocument is a list of objects due to - in front of Version. Also your Version is wrong. So it should be:
KinesisRole:
Type: AWS::IAM::Role
Properties:
RoleName: {'Fn::Sub': 'Kinesis-Role-${AWS::Region}'}
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: [logs.amazonaws.com]
Action: ['sts:AssumeRole']
Policies:
- PolicyName: KinesisPolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Action: ['kinesis:PutRecord']
Effect: Allow
Resource: '*'

How to create a yml while to create create a new IAM::ROLE in AWS lambda

In AWS cloud formation template how to create a new lambda(test_lambda_role) role
which is having access to s3:getObject, RDS access(rds-db:connect),
Resources:
Role:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub test_lambda_role
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Lambda:
- !Sub "arn:aws:iam::${AWS::AccountId}:saml-provider/${pSamlProviderAdmin}"
Action:
- rds-db:connect
Lambda function not creating with above template
AssumeRolePolicyDocument is for a trust policy, as explained in:
Creating a role to delegate permissions to an AWS service
Thus a template with only a lambda execution role could be:
AWSTemplateFormatVersion: 2010-09-09
Parameters:
testlambdarole:
Type: String
Default: role-name
Resources:
Role:
Type: AWS::IAM::Role
Properties:
RoleName: !Ref testlambdarole
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal: {'Service': ['lambda.amazonaws.com']}
Action: ['sts:AssumeRole']
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AWSLambdaExecute
Policies:
- PolicyName: S3Access
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- s3:getObject
Resource: "*"
- PolicyName: RdsAccess
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- rds-db:connect
Resource: "*"
You would need to adjust Policies to exactly what you require.

CloudFormation - Not able to create KMS

I am trying to create a KMS Key using Cloudformation unfortunately I am not able to create it. In the console I am getting the following error :
null (Service: Kms, Status Code: 400, Request ID: 156b452d-8ffb-5517-9jbc-a6yh6e3a79, Extended Request ID: null)
I am not able to understand the root cause of the issue. Please refer to the attached template which I am using to create the KMS :
AWSTemplateFormatVersion: 2010-09-09
Description: Testing KMS Using CloudFormation
Resources:
KMSEncryption:
Type: AWS::KMS::Key
Properties:
Description: KMS-Key
KeyPolicy:
Version: '2012-10-17'
Id: encryption-key
EnableKeyRotation: 'True'
PendingWindowInDays: 7
Statement:
- Sid: Enable IAM User Permissions
Effect: Allow
Principal:
AWS:
Fn::Join:
- ''
- - 'arn:aws:iam::'
- Ref: AWS::AccountId
- :root
Action: kms:*
Resource: '*'
- Sid: Allow use of the key
Effect: Allow
Principal:
AWS:
Fn::Join:
- ''
- - 'arn:aws:iam::'
- Ref: AWS::AccountId
- :role/
- !Ref KMSLambdaRole
Action:
- kms:DescribeKey
- kms:Encrypt
- kms:Decrypt
- kms:ReEncrypt*
- kms:GenerateDataKey
- kms:GenerateDataKeyWithoutPlaintext
Resource: '*'
- Sid: Allow administration of the key
Effect: Allow
Principal:
AWS: arn:aws:iam::xxxxxxxxx:user/Shiv
Action:
- kms:Create*
- kms:Describe*
- kms:Enable*
- kms:List*
- kms:Put*
- kms:Update*
- kms:Revoke*
- kms:Disable*
- kms:Get*
- kms:Delete*
- kms:ScheduleKeyDeletion
- kms:CancelKeyDeletion
EncryptionAlias:
Type: AWS::KMS::Alias
Properties:
AliasName: 'Testing'
TargetKeyId:
Ref: KMSEncryption
KMSLambdaRole:
Type: AWS::IAM::Role
Properties:
RoleName: 'TestingKMSAccess'
AssumeRolePolicyDocument:
Statement:
- Action: ['sts:AssumeRole']
Effect: Allow
Principal:
Service: [lambda.amazonaws.com]
Path: /
ManagedPolicyArns:
- arn:aws:iam::aws:policy/ReadOnlyAccess
Policies:
- PolicyName: AWSLambdaBasicExecutionRole
PolicyDocument:
Version: 2012-10-17
Statement:
- Sid: SQS
Action:
- 'sqs:SendMessage'
- 'sqs:SendMessageBatch'
Effect: Allow
Resource: '*'
Your EnableKeyRotation and PendingWindowInDays should be outside of KeyPolicy:
Resources:
KMSEncryption:
Type: AWS::KMS::Key
Properties:
Description: KMS-Key
EnableKeyRotation: 'True'
PendingWindowInDays: 7
KeyPolicy:
Version: '2012-10-17'
Id: encryption-key
# the rest
Note, that there could be other issues which are not yet apparent, e.g. non-existing principles.

How do I add SQS IAM for my Lambda function?

I was able to get this to work with the serverless.yml:
iamRoleStatements:
- Effect: "Allow"
Action:
- "sqs:SendMessage"
- "sqs:ListQueues"
Resource: "arn:aws:sqs:us-east-1:*:*"
But I want to apply it only to a certain function. How can I do this?
From docs, you need to create the function role under resources and reference this new role inside your function.
Example:
service: my-test
provider:
name: aws
runtime: nodejs6.10
functions:
hello:
role: mySQSRole
handler: handler.hello
resources:
Resources:
mySQSRole:
Type: AWS::IAM::Role
Properties:
RoleName: mySQSRole
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: myPolicyName
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- sqs:SendMessage
- sqs:ListQueues
Resource: "arn:aws:sqs:us-east-1:*:*"