Created
January 22, 2022 04:03
-
-
Save douglampe/5b913c178640774d86b1abc13cf120c4 to your computer and use it in GitHub Desktop.
A better SAM pipeline bootstrap template
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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