Skip to content

Instantly share code, notes, and snippets.

@douglampe
Created January 22, 2022 04:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save douglampe/5b913c178640774d86b1abc13cf120c4 to your computer and use it in GitHub Desktop.
Save douglampe/5b913c178640774d86b1abc13cf120c4 to your computer and use it in GitHub Desktop.
A better SAM pipeline bootstrap template
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
Environment:
Type: String
Default: Dev
Description: Environment identifier
Identifier:
Type: String
Default: StreetlightBlog
Description: Identifier for pipeline roles. Roles will be named ${Identifier}CloudFormationExecutionRole and ${Identifier}PipelineExecutionRole.
IdentifierLower:
Type: String
Default: streetlight-blog
Description: Lowercase identifier used for bucket name for pipeline artifacts. Bucket name will be ${IdentifierLower}-pipeline-artifacts-${AWS::AccountId}.
ExpirationDays:
Type: String
Default: 7
Description: Number of days after which objects are deleted from the artifacts bucket. Leave blank to keep objects indefinitely.
Conditions:
NoExpiration: !Equals [!Ref ExpirationDays, ""]
Resources:
PipelineUser:
Type: AWS::IAM::User
Properties:
Tags:
- Key: Environment
Value: !Ref Environment
- Key: Application
Value: !Ref Identifier
Policies:
- PolicyName: AssumeRoles
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- "sts:AssumeRole"
Resource: "*"
Condition:
StringEquals:
aws:ResourceTag/Role: !Sub ${IdentifierLower}-pipeline-execution-role
PipelineUserAccessKey:
Type: AWS::IAM::AccessKey
Properties:
Serial: 1
Status: Active
UserName: !Ref PipelineUser
PipelineUserSecretKey:
Type: AWS::SecretsManager::Secret
Properties:
Name: !Sub ${Identifier}PipelineUserSecretKey
SecretString: !Sub '{"aws_access_key_id": "${PipelineUserAccessKey}", "aws_secret_access_key": "${PipelineUserAccessKey.SecretAccessKey}"}'
CloudFormationExecutionRole:
Type: AWS::IAM::Role
Properties:
RoleName:
Fn::Join:
- ''
- - !Ref Identifier
- 'CloudFormationExecutionRole'
Tags:
- Key: Environment
Value: !Ref Environment
- Key: Application
Value: !Ref Identifier
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: cloudformation.amazonaws.com
Action:
- 'sts:AssumeRole'
Policies:
- PolicyName: GrantCloudFormationAccess
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- 'apigateway:POST'
Resource:
- !Sub 'arn:aws:apigateway:${AWS::Region}::/restapis'
- Effect: Allow
Action:
- 'apigateway:DELETE'
- 'apigateway:GET'
- 'apigateway:PATCH'
- 'apigateway:POST'
Resource:
- !Sub 'arn:aws:apigateway:${AWS::Region}::/restapis/*'
- Effect: Allow
Action: 'cloudformation:CreateChangeSet'
Resource:
- !Sub 'arn:aws:cloudformation:${AWS::Region}:aws:stack/${IdentifierLower}-*'
- !Sub 'arn:aws:cloudformation:${AWS::Region}:aws:transform/Serverless-2016-10-31'
- Effect: Allow
Action:
- 'iam:*'
Resource:
- !Sub 'arn:aws:iam::${AWS::AccountId}:role/${IdentifierLower}-*'
- Effect: Allow
Action:
- 'lambda:*'
Resource:
- !Sub 'arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:${IdentifierLower}-*'
PipelineExecutionRole:
Type: AWS::IAM::Role
Properties:
RoleName:
Fn::Join:
- ''
- - !Ref Identifier
- 'PipelineExecutionRole'
Tags:
- Key: Role
Value: !Sub ${IdentifierLower}-pipeline-execution-role
- Key: Environment
Value: !Ref Environment
- Key: Application
Value: !Ref Identifier
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
AWS: !GetAtt PipelineUser.Arn
Action:
- 'sts:AssumeRole'
ArtifactsBucket:
Type: AWS::S3::Bucket
Properties:
BucketName:
Fn::Join:
- ''
- - !Ref IdentifierLower
- '-pipeline-artifacts-'
- !Ref AWS::AccountId
Tags:
- Key: Environment
Value: !Ref Environment
- Key: Application
Value: !Ref Identifier
LifecycleConfiguration:
Rules:
- Id: Expiration
ExpirationInDays: !If [NoExpiration, "7", !Ref ExpirationDays]
Status: !If [NoExpiration, "Disabled", Enabled]
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
ArtifactsBucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref ArtifactsBucket
PolicyDocument:
Statement:
- Effect: "Deny"
Action: "s3:*"
Principal: "*"
Resource:
- !Join [ '',[ !GetAtt ArtifactsBucket.Arn, '/*' ] ]
- !GetAtt ArtifactsBucket.Arn
Condition:
Bool:
aws:SecureTransport: false
- Effect: "Allow"
Action:
- 's3:GetObject*'
- 's3:PutObject*'
- 's3:DeleteObject*'
- 's3:GetBucket*'
- 's3:List*'
Resource:
- !Join ['',[!GetAtt ArtifactsBucket.Arn, '/*']]
- !GetAtt ArtifactsBucket.Arn
Principal:
AWS:
- !GetAtt PipelineExecutionRole.Arn
- !GetAtt CloudFormationExecutionRole.Arn
PipelineExecutionRolePermissionPolicy:
Type: AWS::IAM::Policy
Properties:
PolicyName: PipelineExecutionRolePermissions
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: 'iam:PassRole'
Resource:
- !GetAtt CloudFormationExecutionRole.Arn
- Effect: Allow
Action:
- "cloudformation:CreateChangeSet"
- "cloudformation:DescribeChangeSet"
- "cloudformation:ExecuteChangeSet"
- "cloudformation:DeleteStack"
- "cloudformation:DescribeStackEvents"
- "cloudformation:DescribeStacks"
- "cloudformation:GetTemplate"
- "cloudformation:GetTemplateSummary"
- "cloudformation:DescribeStackResource"
Resource: !Sub 'arn:aws:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/${IdentifierLower}-*/*'
- Effect: Allow
Action:
- 's3:DeleteObject'
- 's3:GetObject*'
- 's3:PutObject*'
- 's3:GetBucket*'
- 's3:List*'
Resource:
- !Join [ '',[ !GetAtt ArtifactsBucket.Arn, '/*' ] ]
- !GetAtt ArtifactsBucket.Arn
Roles:
- !Ref PipelineExecutionRole
Outputs:
PipelineUser:
Description: ARN of the Pipeline IAM User
Value: !GetAtt PipelineUser.Arn
PipelineUserSecretKey:
Description: AWS Access Key and Secret Key of pipeline user.
Value: !Ref PipelineUserSecretKey
CloudFormationExecutionRole:
Description: ARN of the IAM Role(CloudFormationExecutionRole)
Value: !GetAtt CloudFormationExecutionRole.Arn
PipelineExecutionRole:
Description: ARN of the IAM Role(PipelineExecutionRole)
Value: !GetAtt PipelineExecutionRole.Arn
ArtifactsBucket:
Description: ARN of the Artifacts bucket
Value: !GetAtt ArtifactsBucket.Arn
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment