public PipelineStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props) { var sourceArtifact = new Artifact_(); var cloudAssemblyArtifact = new Artifact_(); var pipeline = new CdkPipeline(this, "CdkPipeline", new CdkPipelineProps { PipelineName = "sandbank-api-pipeline", CdkCliVersion = "1.63.0", SourceAction = new GitHubSourceAction(new GitHubSourceActionProps { ActionName = "synth-cdk", Owner = "nicostouch", Repo = "sandbank", Output = sourceArtifact, OauthToken = SecretValue.SecretsManager("github/oauth/token") }), SynthAction = new SimpleSynthAction(new SimpleSynthActionProps { SynthCommand = "cdk synth", Subdirectory = "DevOps/Infrastructure/CDK", SourceArtifact = sourceArtifact, CloudAssemblyArtifact = cloudAssemblyArtifact }), CloudAssemblyArtifact = cloudAssemblyArtifact }); }
public IDatabaseInstance CreateDatabaseSqlServer(DeputyBase databaseEngineVersion, string identification, string databaseName, string userName, string password, StorageType storageType, InstanceClass instanceClass, string instanceSize, IVpc vpc, ISecurityGroup security, string securityGroupId, string parameterGroupId = null, IRole[] roles = null, double?allocatedStorageGb = 5, RemovalPolicy removalPolicy = RemovalPolicy.DESTROY, bool deleteAutomatedBackups = false, int backupRetentionDays = 1, bool?deletionProtection = false, SubnetType subnetType = SubnetType.PRIVATE_ISOLATED, string defaultSubnetDomainSeparator = ",", string subnets = "", bool multiAZEnabled = true, bool?autoMinorVersionUpgrade = false, bool?storageEncrypted = true, string licenseOption = "LICENSE_INCLUDED", string edition = "ex") { BasicDatabaseInfraWithHardcodedPassword(vpc, subnetType, defaultSubnetDomainSeparator, subnets, out var subnetSelection); var engine = GetInstanceEngine(databaseEngineVersion, edition); return(new DatabaseInstance(Scope, identification, new DatabaseInstanceProps { Engine = engine, RemovalPolicy = removalPolicy, DeletionProtection = deletionProtection, Credentials = Credentials.FromPassword(userName, SecretValue.PlainText(password)), StorageType = storageType, DatabaseName = licenseOption == LicenseModel.LICENSE_INCLUDED.ToString() ? null : databaseName, VpcSubnets = subnetSelection, Vpc = vpc, SecurityGroups = new[] { security }, DeleteAutomatedBackups = deleteAutomatedBackups, BackupRetention = Duration.Days(backupRetentionDays), AllocatedStorage = allocatedStorageGb, InstanceType = InstanceType.Of(instanceClass, GetInstanceSize(instanceSize)), ParameterGroup = CreateClusterParameterGroup(parameterGroupId, engine, roles), MultiAz = multiAZEnabled, AutoMinorVersionUpgrade = autoMinorVersionUpgrade, StorageEncrypted = storageEncrypted, LicenseModel = GetLicenseModel(licenseOption) })); }
public void CanRemoveSecretWithPassThruTest() { SecureString secureSecretValue = SecretValue.ConvertToSecureString(); Cmdlet.Secret expected = new Cmdlet.Secret() { Name = SecretName, VaultName = VaultName, SecretValue = secureSecretValue }; keyVaultClientMock.Setup(kv => kv.DeleteSecret(VaultName, SecretName)).Returns(expected).Verifiable(); // Mock the should process to return true commandRuntimeMock.Setup(cr => cr.ShouldProcess(SecretName, It.IsAny <string>())).Returns(true); cmdlet.Name = SecretName; cmdlet.Force = true; cmdlet.PassThru = true; cmdlet.ExecuteCmdlet(); keyVaultClientMock.VerifyAll(); commandRuntimeMock.Verify(f => f.WriteObject(expected), Times.Once()); //No force but should continue commandRuntimeMock.Setup(cr => cr.ShouldProcess(SecretName, It.IsAny <string>())).Returns(true); commandRuntimeMock.Setup(cr => cr.ShouldContinue(It.IsAny <string>(), It.IsAny <string>())).Returns(true); cmdlet.Force = false; cmdlet.PassThru = true; cmdlet.ExecuteCmdlet(); keyVaultClientMock.VerifyAll(); commandRuntimeMock.Verify(f => f.WriteObject(expected), Times.Exactly(2)); }
public SetKeyVaultSecretTests() { base.SetupTest(); secretAttributes = new SecretAttributes(true, null, null, null, null); secureSecretValue = SecretValue.ConvertToSecureString(); secret = new Secret() { VaultName = VaultName, Name = SecretName, Version = SecretVersion, SecretValue = secureSecretValue, Attributes = secretAttributes }; cmdlet = new SetAzureKeyVaultSecret() { CommandRuntime = commandRuntimeMock.Object, DataServiceClient = keyVaultClientMock.Object, VaultName = secret.VaultName, Name = secret.Name, SecretValue = secret.SecretValue, Disable = new SwitchParameter(!(secretAttributes.Enabled.Value)), Expires = secretAttributes.Expires, NotBefore = secretAttributes.NotBefore, ContentType = secretAttributes.ContentType, Tags = secretAttributes.Tags }; }
internal MyAmplifyAppStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props) { // Get user, repo string user = StringParameter.ValueForStringParameter(this, "amplify-user"); string repo = StringParameter.ValueForStringParameter(this, "amplify-repo"); SecretValue token = SecretValue.SecretsManager("my-github-token"); // The code that defines your stack goes here Amazon.CDK.AWS.Amplify.App amplifyApp = new Amazon.CDK.AWS.Amplify.App(this, "MyApp", new Amazon.CDK.AWS.Amplify.AppProps { SourceCodeProvider = new GitHubSourceCodeProvider(new GitHubSourceCodeProviderProps { Owner = user, Repository = repo, OauthToken = token }), BuildSpec = BuildSpec.FromObject(new Dictionary <string, object> { // Alternatively add a `amplify.yml` to the repo { "version", "1.0" }, { "frontend", new Dictionary <string, object> { { "Phases", new Dictionary <string, object> { { "PreBuild", new Dictionary <string, object> { { "Commands", new [] { "yarn" } } } }, { "Build", new Dictionary <string, object> { { "Commands", new [] { "yarn build" } } } } } }, { "Artifacts", new Dictionary <string, object> { { "BaseDirectory", "public" }, { "Files", "**/*" } } } } } }) }); }
protected override async Task <SecretData> RotateValue(Parameters parameters, RotationContext context, CancellationToken cancellationToken) { string key; DateTimeOffset expiresOn; DateTimeOffset nextRotationOn; if (parameters.StorageKeySecret != null) { SecretValue storageKeySecret = await context.GetSecret(parameters.StorageKeySecret); key = storageKeySecret.Value; expiresOn = storageKeySecret.ExpiresOn; nextRotationOn = storageKeySecret.NextRotationOn; } else { key = await StorageUtils.RotateStorageAccountKey(parameters.Subscription.ToString(), parameters.Account, context, _tokenCredentialProvider, cancellationToken); expiresOn = DateTimeOffset.MaxValue; nextRotationOn = _clock.UtcNow.AddMonths(6); } string connectionString = $"DefaultEndpointsProtocol=https;AccountName={parameters.Account};AccountKey={key}"; return(new SecretData(connectionString, expiresOn, nextRotationOn)); }
private void CreatePipeline(IRole cloudFormationRole, PipelineProject build, string githubOwner, string githubRepository, string githubOauthToken, string gitBranch) { Console.WriteLine($"... defining {gitBranch} pipeline"); var buildOutput = new Artifact_("BuildOutput"); new Pipeline(this, "Pipeline-" + gitBranch, new PipelineProps { Stages = new StageProps[] { new StageProps { StageName = "Source", Actions = new IAction[] { new GitHubSourceAction(new GitHubSourceActionProps { ActionName = "GitHubSource", Branch = gitBranch, Repo = githubRepository, Owner = githubOwner, OauthToken = SecretValue.PlainText(githubOauthToken), Output = SourceOutput }) } }, new StageProps { StageName = "Build", Actions = new IAction[] { new CodeBuildAction(new CodeBuildActionProps { ActionName = $"Build-{gitBranch}", Project = build, Input = SourceOutput, Outputs = new Artifact_[] { buildOutput } }) } }, new StageProps { StageName = "Deploy", Actions = new IAction[] { new CloudFormationCreateUpdateStackAction(new CloudFormationCreateUpdateStackActionProps { ActionName = "DeployServerlessTemplate", Capabilities = new CloudFormationCapabilities[] { CloudFormationCapabilities.ANONYMOUS_IAM, CloudFormationCapabilities.AUTO_EXPAND }, TemplatePath = ArtifactPath_.ArtifactPath(buildOutput.ArtifactName, "updated.template"), StackName = $"{githubRepository}-{gitBranch}-{DateTime.Now.Ticks}", AdminPermissions = true }) } } } }); }
protected override async Task <SecretData> RotateValue(Parameters parameters, RotationContext context, CancellationToken cancellationToken) { SecretValue secret = await context.GetSecret(parameters.Secret); byte[] plainTextBytes = System.Text.Encoding.UTF8.GetBytes(secret.Value); string secretEncodedBase64 = System.Convert.ToBase64String(plainTextBytes); return(new SecretData(secretEncodedBase64, secret.ExpiresOn, secret.NextRotationOn)); }
/// <summary> /// Serializes the object to JSON. /// </summary> /// <param name="writer">The <see cref="T: Newtonsoft.Json.JsonWriter" /> to write to.</param> /// <param name="obj">The object to serialize to JSON.</param> internal static void Serialize(JsonWriter writer, SecretValue obj) { // Required properties are always serialized, optional properties are serialized when not null. writer.WriteStartObject(); if (obj.Value != null) { writer.WriteProperty(obj.Value, "value", JsonWriterExtensions.WriteStringValue); } writer.WriteEndObject(); }
public void ErrorSetSecretTest() { SecureString secureSecretValue = SecretValue.ConvertToSecureString(); keyVaultClientMock.Setup(kv => kv.SetSecret(VaultName, SecretName, secureSecretValue)) .Throws(new Exception("exception")).Verifiable(); cmdlet.Name = SecretName; cmdlet.SecretValue = secureSecretValue; cmdlet.ExecuteCmdlet(); // Assert keyVaultClientMock.VerifyAll(); commandRuntimeMock.Verify(f => f.WriteError(It.IsAny <ErrorRecord>()), Times.Once()); }
protected override void Execute(CodeActivityContext context) { try { CreateSecret obj = new CreateSecret(); obj.SecretName = SecretName.Get(context); obj.SecretValue = SecretValue.Get(context); obj.ContenType = "dev-Action-secret"; string output = CreateSecretinAzure(obj); PublishedVersion.Set(context, output); } catch (Exception ex) { throw new InvalidWorkflowException("exception in action" + ex.Message, ex.InnerException); } }
public override async Task SetSecretValueAsync(string name, SecretValue value) { SecretClient client = await CreateSecretClient(); var createdSecret = await client.SetSecretAsync(name, value.Value); var properties = createdSecret.Value.Properties; foreach (var(k, v) in value.Tags) { properties.Tags[k] = v; } properties.Tags[_nextRotationOnTag] = value.NextRotationOn.ToString("O"); properties.ExpiresOn = value.ExpiresOn; await client.UpdateSecretPropertiesAsync(properties); }
public void CanSetSecretTest() { SecureString secureSecretValue = SecretValue.ConvertToSecureString(); Cmdlet.Secret expected = new Cmdlet.Secret() { Name = SecretName, VaultName = VaultName, SecretValue = secureSecretValue, Version = SecretVersion }; keyVaultClientMock.Setup(kv => kv.SetSecret(VaultName, SecretName, secureSecretValue)).Returns(expected).Verifiable(); cmdlet.Name = SecretName; cmdlet.SecretValue = secureSecretValue; cmdlet.ExecuteCmdlet(); // Assert keyVaultClientMock.VerifyAll(); commandRuntimeMock.Verify(f => f.WriteObject(expected), Times.Once()); }
public void ErrorSetSecretTest() { SecureString secureSecretValue = SecretValue.ConvertToSecureString(); keyVaultClientMock.Setup(kv => kv.SetSecret(VaultName, SecretName, secureSecretValue)) .Throws(new Exception("exception")).Verifiable(); cmdlet.Name = SecretName; cmdlet.SecretValue = secureSecretValue; try { cmdlet.ExecuteCmdlet(); } catch {} keyVaultClientMock.VerifyAll(); commandRuntimeMock.Verify(f => f.WriteObject(It.IsAny <Cmdlet.Secret>()), Times.Never()); }
internal PipelineStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props) { Artifact_ sourceArtifact = new Artifact_(); Artifact_ cloudAssemblyArtifact = new Artifact_(); CdkPipeline pipeline = new CdkPipeline(this, "LambdaApiSolutionPipeline", new CdkPipelineProps() { CloudAssemblyArtifact = cloudAssemblyArtifact, PipelineName = "LambdaApiSolutionPipeline", SourceAction = new GitHubSourceAction(new GitHubSourceActionProps() { ActionName = "GitHubSource", Output = sourceArtifact, OauthToken = SecretValue.SecretsManager(Constants.GitHubTokenSecretsManagerId), Owner = Constants.Owner, Repo = Constants.RepositoryName, Branch = Constants.Branch, Trigger = GitHubTrigger.POLL }), SynthAction = new SimpleSynthAction(new SimpleSynthActionProps() { Environment = new BuildEnvironment { // required for .NET 5 // https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-available.html BuildImage = LinuxBuildImage.STANDARD_5_0 }, SourceArtifact = sourceArtifact, CloudAssemblyArtifact = cloudAssemblyArtifact, Subdirectory = "LambdaApiSolution", InstallCommands = new[] { "npm install -g aws-cdk" }, BuildCommands = new[] { "dotnet build src/LambdaApiSolution.sln" }, SynthCommand = "cdk synth" }) }); CdkStage developmentStage = pipeline.AddApplicationStage(new SolutionStage(this, "Development")); CdkStage testStage = pipeline.AddApplicationStage(new SolutionStage(this, "Test")); testStage.AddManualApprovalAction(new AddManualApprovalOptions() { ActionName = "PromoteToProduction" }); CdkStage productionStage = pipeline.AddApplicationStage(new SolutionStage(this, "Production")); }
internal S2VXStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props) { var app = new Amplify.App(this, "S2VX", new Amplify.AppProps { // Configurations for Amplify to find and access our repo SourceCodeProvider = new GitHubSourceCodeProvider(new GitHubSourceCodeProviderProps { Owner = "maxrchung", Repository = "S2VX", OauthToken = SecretValue.PlainText( // Personal access token generated for my GitHub account System.Environment.GetEnvironmentVariable("PERSONAL_ACCESS_TOKEN") ) }), }); // Links our s2vx.com domain to the repository branch var branch = app.AddBranch("release"); var domain = app.AddDomain("s2vx.com"); domain.MapRoot(branch); }
public void Store(string key, string value) { if (!IsUnlocked) { throw new Exception("Please unlock the key store prior to using it."); } if (String.IsNullOrEmpty(value)) { _keyStore.DeleteEntry(key); } else { var secretKey = new SecretValue(value); Java.Security.KeyStore.SecretKeyEntry entry = new KeyStore.SecretKeyEntry(secretKey); _keyStore.SetEntry(key, entry, _passwordProtection); Save(); } }
public void CanRemoveSecretWithNoPassThruTest() { SecureString secureSecretValue = SecretValue.ConvertToSecureString(); Secret expected = new Secret() { Name = SecretName, VaultName = VaultName, SecretValue = secureSecretValue }; keyVaultClientMock.Setup(kv => kv.DeleteSecret(VaultName, SecretName)).Returns(expected).Verifiable(); // Mock the should process to return true commandRuntimeMock.Setup(cr => cr.ShouldProcess(SecretName, It.IsAny <string>())).Returns(true); cmdlet.Name = SecretName; cmdlet.Force = true; cmdlet.ExecuteCmdlet(); keyVaultClientMock.VerifyAll(); // Without PassThru never call WriteObject commandRuntimeMock.Verify(f => f.WriteObject(expected), Times.Never()); }
protected override async Task <SecretData> RotateValue(Parameters parameters, RotationContext context, CancellationToken cancellationToken) { string adAppId = await context.GetSecretValue(new SecretReference { Location = parameters.ADApplication.Location, Name = parameters.ADApplication.Name + ADApplication.AppIdSuffix }); SecretValue adAppSecret = await context.GetSecret(new SecretReference { Location = parameters.ADApplication.Location, Name = parameters.ADApplication.Name + ADApplication.AppSecretSuffix }); var connectionString = new StringBuilder(); connectionString.Append($"Data Source={parameters.DataSource}"); if (!string.IsNullOrEmpty(parameters.InitialCatalog)) { connectionString.Append($";Initial Catalog={parameters.InitialCatalog}"); } connectionString.Append($";AAD Federated Security=True;Application Client Id={adAppId};Application Key={adAppSecret?.Value}"); if (!string.IsNullOrWhiteSpace(parameters.AdditionalParameters)) { connectionString.Append($";{parameters.AdditionalParameters}"); } return(new SecretData(connectionString.ToString(), adAppSecret.ExpiresOn, adAppSecret.NextRotationOn)); }
public override Task <bool> SaveAsync() { var secureKey = GetKeyFromPreferences(context); var keyStore = LoadKeyStore(context, secureKey); var password = new KeyStore.PasswordProtection(secureKey); var secretValue = new SecretValue(System.Text.Encoding.UTF8.GetBytes(DictionaryToJson(data))); var secretKeyEntry = new KeyStore.SecretKeyEntry(secretValue); keyStore.SetEntry(FILENAME, secretKeyEntry, password); lock (fileLock) { using (var stream = context.OpenFileOutput(FILENAME, FileCreationMode.Private)) { keyStore.Store(stream, secureKey); stream.Flush(); stream.Close(); } } return(Task.FromResult(true)); }
public ServerlessTodoListPipelineCdkStack(Construct parent, string id, IStackProps props) : base(parent, id, props) { var frontendBuild = new PipelineProject(this, "CodeBuild", new PipelineProjectProps { BuildSpec = BuildSpec.FromSourceFilename("./Application/Final/ServerlessTODOList.Frontend/buildspec.yml"), Environment = new BuildEnvironment { BuildImage = LinuxBuildImage.STANDARD_2_0 } }); var s3PolicyStatement = new PolicyStatement(); s3PolicyStatement.Effect = Effect.ALLOW; s3PolicyStatement.AddActions("s3:*"); s3PolicyStatement.AddResources("arn:aws:s3:::normj-east1/", "arn:aws:s3:::normj-east1/*"); frontendBuild.Role.AddToPolicy(s3PolicyStatement); var sourceOutput = new Artifact_(); var buildOutput = new Artifact_("BuildOutput"); var pipeline = new Pipeline(this, "Pipeline", new PipelineProps { Stages = new StageProps[] { new StageProps { StageName = "Source", Actions = new IAction[] { new GitHubSourceAction(new GitHubSourceActionProps { ActionName = "GitHubSource", Branch = "master", Repo = "ServerlessTODOListTutorial", Owner = "normj", OauthToken = SecretValue.PlainText(FetchGitHubPersonalAuthToken()), Output = sourceOutput }) } }, new StageProps { StageName = "Build", Actions = new IAction[] { new CodeBuildAction(new CodeBuildActionProps { ActionName = "BuildServerlessTODOListFrontend", Project = frontendBuild, Input = sourceOutput, Outputs = new Artifact_[] { buildOutput } }) } }, new StageProps { StageName = "Deploy", Actions = new IAction[] { new CloudFormationCreateUpdateStackAction(new CloudFormationCreateUpdateStackActionProps { ActionName = "DeployFrontend", Capabilities = new CloudFormationCapabilities[] { CloudFormationCapabilities.ANONYMOUS_IAM, CloudFormationCapabilities.AUTO_EXPAND }, TemplatePath = ArtifactPath_.ArtifactPath("BuildOutput", "updated.template"), StackName = "ServerlessFrontendCdk", AdminPermissions = true }) } } } }); }
public override async Task SetSecretValueAsync(AzureKeyVaultParameters parameters, string name, SecretValue value) { SecretClient client = await CreateSecretClient(parameters); var createdSecret = await client.SetSecretAsync(name, value.Value ?? ""); var properties = createdSecret.Value.Properties; foreach (var(k, v) in value.Tags) { properties.Tags[k] = v; } properties.Tags[_nextRotationOnTag] = value.NextRotationOn.ToString("O"); properties.Tags["ChangedBy"] = "secret-manager.exe"; // Tags to appease the old secret management system properties.Tags["Owner"] = "secret-manager.exe"; properties.Tags["SecretType"] = "MANAGED"; properties.ExpiresOn = value.ExpiresOn; await client.UpdateSecretPropertiesAsync(properties); }
internal DatabaseConstructOutput CreateDatabaseConstruct(Construct parent, Vpc vpc, SecretValue databasePasswordSecret) { return(this.IsClustered ? CreateDbClusterConstruct(parent, vpc, databasePasswordSecret) : CreateDbInstanceConstruct(parent, vpc, databasePasswordSecret)); }
internal AppdeploymentStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props) { #region Application hosting resources var vpc = new Vpc(this, "appVpc", new VpcProps { MaxAzs = 3 }); var image = new LookupMachineImage(new LookupMachineImageProps { // maps to "Amazon Linux 2 with .NET Core 3.0 and Mono 5.18" Name = "amzn2-ami-hvm-2.0.*-x86_64-gp2-mono-*", Owners = new [] { "amazon" } }); var userData = UserData.ForLinux(); userData.AddCommands(new string[] { "sudo yum install -y httpd", "sudo systemctl start httpd", "sudo systemctl enable httpd" }); var scalingGroup = new AutoScalingGroup(this, "appASG", new AutoScalingGroupProps { Vpc = vpc, InstanceType = InstanceType.Of(InstanceClass.BURSTABLE3, InstanceSize.MEDIUM), MachineImage = image, MinCapacity = 1, MaxCapacity = 4, AllowAllOutbound = true, UserData = userData }); var alb = new ApplicationLoadBalancer(this, "appLB", new ApplicationLoadBalancerProps { Vpc = vpc, InternetFacing = true }); var albListener = alb.AddListener("Port80Listener", new BaseApplicationListenerProps { Port = 80 }); albListener.AddTargets("Port80ListenerTargets", new AddApplicationTargetsProps { Port = 80, Targets = new [] { scalingGroup } }); albListener.Connections.AllowDefaultPortFromAnyIpv4("Open access to port 80"); scalingGroup.ScaleOnRequestCount("ScaleOnModestLoad", new RequestCountScalingProps { TargetRequestsPerSecond = 1 }); #endregion #region CI/CD resources var _sourceOutput = new Artifact_("Source"); var _buildOutput = new Artifact_("Build"); var build = new PipelineProject(this, "CodeBuild", new PipelineProjectProps { // relative path to sample app's file (single html page for now) BuildSpec = BuildSpec.FromSourceFilename("talk-demos/appdeployment/SimplePage/buildspec.yml"), Environment = new BuildEnvironment { BuildImage = LinuxBuildImage.AMAZON_LINUX_2_2 }, }); var appDeployment = new ServerApplication(this, "appDeployment"); // we will use CodeDeploy's default one-at-a-time deployment mode as we are // not specifying a deployment config var deploymentGroup = new ServerDeploymentGroup(this, "appDeploymentGroup", new ServerDeploymentGroupProps { Application = appDeployment, InstallAgent = true, AutoRollback = new AutoRollbackConfig { FailedDeployment = true }, AutoScalingGroups = new [] { scalingGroup } }); // SecretValue.SsmSecure is not currently supported for setting OauthToken, // and haven't gotten the SecretsManager approach to work either so // resorting to keeping my token in an environment var for now! var oauthToken = SecretValue.PlainText(System.Environment.GetEnvironmentVariable("GitHubPersonalToken")); var pipeline = new Pipeline(this, "sampleappPipeline", new PipelineProps { Stages = new StageProps[] { new StageProps { StageName = "Source", Actions = new IAction[] { new GitHubSourceAction(new GitHubSourceActionProps { ActionName = "GitHubSource", Branch = "master", Repo = this.Node.TryGetContext("repo-name").ToString(), Owner = this.Node.TryGetContext("repo-owner").ToString(), OauthToken = oauthToken, Output = _sourceOutput }) } }, new StageProps { StageName = "Build", Actions = new IAction[] { new CodeBuildAction(new CodeBuildActionProps { ActionName = "Build-app", Project = build, Input = _sourceOutput, Outputs = new Artifact_[] { _buildOutput }, RunOrder = 1 }) } }, new StageProps { StageName = "Deploy", Actions = new IAction[] { new CodeDeployServerDeployAction(new CodeDeployServerDeployActionProps { ActionName = "Deploy-app", Input = _buildOutput, RunOrder = 2, DeploymentGroup = deploymentGroup }) } } } }); #endregion }
public QaStage(Construct scope, string id, QaStageProps props) : base(scope, id, props) { var mainStack = new Stack(this, "main-stack", new StackProps { Env = Constants.DefaultEnv }); var credentials = new GitHubSourceCredentials(mainStack, "github-source-credentials", new GitHubSourceCredentialsProps { AccessToken = SecretValue.SecretsManager("github/oauth/token") }); var vpc = new Vpc(mainStack, "main-vpc", new VpcProps { Cidr = "10.0.0.0/16" }); //should change this to Aurora Serverless!!! //https://dev.to/cjjenkinson/how-to-create-an-aurora-serverless-rds-instance-on-aws-with-cdk-5bb0 var db = new PostgresStack(this, "postgres-db-stack", new DatabaseInstanceProps { Vpc = vpc, Engine = DatabaseInstanceEngine.Postgres(new PostgresInstanceEngineProps { Version = PostgresEngineVersion.VER_12_3 }), AllocatedStorage = 5, BackupRetention = Duration.Days(0), DeletionProtection = false, InstanceType = InstanceType.Of(InstanceClass.BURSTABLE2, InstanceSize.MICRO), MasterUsername = "******", MultiAz = false, DatabaseName = "postgres", RemovalPolicy = RemovalPolicy.DESTROY, AllowMajorVersionUpgrade = false }, new StackProps { Env = Constants.DefaultEnv }); var containerEnvVars = new Dictionary <string, string> { { "DB__ADDRESS", db.Instance.InstanceEndpoint.SocketAddress } }; var containerSecrets = new Dictionary <string, Secret> { { "DatabaseConnection", Secret.FromSecretsManager(db.Instance.Secret) } }; var accountMetadataTable = new Table(mainStack, "AccountMetadata", new TableProps { TableName = "AccountMetadata", PartitionKey = new Attribute { Name = "UserId", Type = AttributeType.NUMBER }, SortKey = new Attribute { Name = "AccountId", Type = AttributeType.NUMBER }, Stream = StreamViewType.NEW_IMAGE }); var ecsCluster = new Cluster(mainStack, "app-cluster", new ClusterProps { Vpc = vpc, ClusterName = "app-cluster", ContainerInsights = true }); var fargateSslCertArn = SecretValue.SecretsManager("fargateSslCertArn").ToString(); var albCert = Certificate.FromCertificateArn(mainStack, "alb-cert", fargateSslCertArn); var sandbankBuildInfra = this.CreateApiBuildStack("SandBank", vpc); var sandbankApi = this.CreateApiStack("SandBank", ecsCluster, vpc, sandbankBuildInfra.EcrRepository, "sandbank-api", props.HostedZoneName, props.HostedZoneId, albCert, containerEnvVars, containerSecrets); accountMetadataTable.GrantFullAccess(sandbankApi.FargateService.TaskDefinition.TaskRole); var cloudfrontCertArn = SecretValue.SecretsManager("cloudfrontcertarn").ToString(); var cert = Certificate.FromCertificateArn(mainStack, "cloudfront-cert", cloudfrontCertArn); var sandbankSpa = new SpaStack(this, "sandbank-spa-stack", new SpaStackProps { Env = Constants.DefaultEnv, Vpc = vpc, ServiceName = "sandbank-spa", SubDomain = "sandbank", HostedZoneName = props.HostedZoneName, HostedZoneId = props.HostedZoneId, CloudFrontCert = cert, GitHubSourceProps = Constants.GithubRepo, BuildSpecFile = Constants.NpmBuildSpec, SpaDirectory = "App/FrontEnd/sandbank.spa", ApiUrl = $"{sandbankApi.ApiUrl}/api" //maybe should use CfnOutput instead }); //lambda //SandBank.Lambda.ConfigAuditTrail::SandBank.Lambda.ConfigAuditTrail.Function::FunctionHandler }
public PipelineStack(Construct parent, string id, IPipelineStackProps props) : base(parent, id, props) { EcrRepository = new Repository( this, "EcrRepository", new RepositoryProps { RepositoryName = "cdk-dotnet-example", RemovalPolicy = RemovalPolicy.DESTROY, }); var cdkBuild = new PipelineProject( this, "CdkBuild", new PipelineProjectProps { BuildSpec = BuildSpec.FromSourceFilename("Infrastructure/Resources/cdk_buildspec.yml"), Environment = new BuildEnvironment { BuildImage = LinuxBuildImage.AMAZON_LINUX_2, }, }); var apiBuildTaskRole = new Role( this, "ApiBuildRole", new RoleProps { ManagedPolicies = new[] { ManagedPolicy.FromAwsManagedPolicyName("AmazonEC2ContainerRegistryPowerUser"), }, AssumedBy = new ServicePrincipal("codebuild.amazonaws.com") }); var apiBuild = new PipelineProject( this, "ApiBuild", new PipelineProjectProps { BuildSpec = BuildSpec.FromSourceFilename("Infrastructure/Resources/api_buildspec.yml"), Role = apiBuildTaskRole, Environment = new BuildEnvironment { BuildImage = LinuxBuildImage.AMAZON_LINUX_2, Privileged = true, EnvironmentVariables = new Dictionary <string, IBuildEnvironmentVariable> { ["AWS_ACCOUNT_ID"] = CdkUtil.PlainTextBuildEnvironmentVariable(Of(this).Account), ["AWS_DEFAULT_REGION"] = CdkUtil.PlainTextBuildEnvironmentVariable(Of(this).Region), }, }, }); var apiTest = new PipelineProject( this, "ApiTest", new PipelineProjectProps { BuildSpec = BuildSpec.FromSourceFilename("Infrastructure/Resources/ci_buildspec.yml"), Environment = new BuildEnvironment { BuildImage = LinuxBuildImage.AMAZON_LINUX_2, Privileged = true, }, }); var sourceOutput = new Artifact_(); var cdkBuildOutput = new Artifact_("CdkBuildOutput"); var apiBuildOutput = new Artifact_("ApiBuildOutput"); new Pipeline( this, "Api", new PipelineProps { Stages = new IStageProps[] { new StageProps { StageName = "Source", Actions = new IAction[] { new GitHubSourceAction(new GitHubSourceActionProps { ActionName = "GitHub", OauthToken = SecretValue.SecretsManager(props.GitHubSecretName), Repo = props.GitHubRepo, Owner = props.GitHubOwner, Output = sourceOutput, Trigger = GitHubTrigger.WEBHOOK, }), }, }, new StageProps { StageName = "Build", Actions = new IAction[] { new CodeBuildAction(new CodeBuildActionProps { ActionName = "ApiTest", Project = apiTest, Input = sourceOutput, RunOrder = 1, }), new CodeBuildAction(new CodeBuildActionProps { ActionName = "ApiBuild", Project = apiBuild, Input = sourceOutput, Outputs = new[] { apiBuildOutput }, RunOrder = 2, }), new CodeBuildAction(new CodeBuildActionProps { ActionName = "CdkBuild", Project = cdkBuild, Input = sourceOutput, Outputs = new[] { cdkBuildOutput }, RunOrder = 3, }), }, }, new StageProps { StageName = "Deploy", Actions = new IAction[] { new CloudFormationCreateUpdateStackAction(new CloudFormationCreateUpdateStackActionProps { ActionName = "ApiStack", TemplatePath = cdkBuildOutput.AtPath($"{props.ApiStackName}.template.json"), StackName = "Api", AdminPermissions = true, ParameterOverrides = new Dictionary <string, object> { [props.ApiImageTag] = apiBuildOutput.GetParam("metadata.json", "imageTag"), }, ExtraInputs = new[] { apiBuildOutput, }, }), }, }, }, }); }
private DatabaseConstructOutput CreateDbClusterConstruct(Construct parent, Vpc vpc, SecretValue databasePasswordSecret) { var database = new DatabaseCluster(parent, $"{this.Settings.ScopeName}-Database-{this.Settings.DbEngine}", new DatabaseClusterProps { Engine = this.DbClusterEgnine, ClusterIdentifier = $"{this.Settings.ScopeName}-Database-{this.Settings.DbEngine}-Cluster", ParameterGroup = ClusterParameterGroup.FromParameterGroupName( parent, $"{this.Settings.ScopeName}DbParamGroup", this.ExistingAuroraDbParameterGroupName ), RemovalPolicy = RemovalPolicy.DESTROY, MasterUser = new Login { Username = this.Settings.DbUsername, Password = databasePasswordSecret }, InstanceProps = new Amazon.CDK.AWS.RDS.InstanceProps { InstanceType = this.InstanceType, Vpc = vpc, VpcSubnets = new SubnetSelection { SubnetType = this.Settings.DbSubnetType } } } ); string clusterPort = database.ClusterEndpoint.SocketAddress.Split(':')[1]; // Bad - port placeholder is not available otherwise return(new DatabaseConstructOutput { Connections = database.Connections, EndpointAddress = database.ClusterEndpoint.Hostname, Port = clusterPort }); }
private DatabaseConstructOutput CreateDbInstanceConstruct(Construct parent, Vpc vpc, SecretValue databasePasswordSecret) { var database = new DatabaseInstance(parent, $"{this.Settings.ScopeName}-Database-{this.Settings.DbEngine}", new DatabaseInstanceProps { InstanceClass = this.InstanceType, Vpc = vpc, VpcPlacement = new SubnetSelection { SubnetType = this.Settings.DbSubnetType }, DeletionProtection = this.Settings.DotNetEnvironment != "Development", InstanceIdentifier = $"{this.Settings.ScopeName}-Database-{this.Settings.DbEngine}", Engine = this.DbInstanceEgnine, MasterUsername = this.Settings.DbUsername, MasterUserPassword = databasePasswordSecret, RemovalPolicy = RemovalPolicy.DESTROY } ); return(new DatabaseConstructOutput { EndpointAddress = database.InstanceEndpoint.Hostname, Connections = database.Connections, Port = database.DbInstanceEndpointPort }); }